Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #9264
| From | Andrey Tarasevich <andreytarasevich@hotmail.com> |
|---|---|
| Newsgroups | comp.lang.c++ |
| Subject | Re: Fun with member-function pointers |
| Date | 2011-08-23 18:43 -0700 |
| Organization | A noiseless patient Spider |
| Message-ID | <j31kvb$iso$1@dont-email.me> (permalink) |
| References | <9bg0ojFsapU1@mid.individual.net> <4e5351c3$0$6566$9b4e6d93@newsspool3.arcor-online.net> |
On 8/23/2011 12:07 AM, Marcel Müller wrote:
>>
>> class tbase
>> {
>> public:
>> tbase() : p(0)
>> {
>> }
>> typedef int (tbase::*HandlerPtr)(int);
>> protected:
>> HandlerPtr p;
>> };
>> class test : tbase
>> {
>> public:
>> test()
>> {
>> p = static_cast<HandlerPtr>(&test::f);
>
> This is undefined behavior. It only happens to work as long as pointers
> to tbase and pointers to test are binary the same.
Absolutely incorrect. This cast is perfectly legal. This use of
`static_cast` is explicitly allowed and supported by the language
specification.
Actually, if this cast suffered from the problem you imply, it would
simply be disallowed. C++ style casts were specifically introduced to
outlaw straightforward hacks.
> To illustrate the point: change your code to (see below) and it will
> sadly fail.
No, the code you provided below also works perfectly fine, as it should.
The only reason it might "fail" is the non-compliant compiler that
attempts to save memory by using different pointer representation for
different hierarchy types. Such compiler usually have an option to
restore the proper behavior.
> I would like to have this pattern supported by the language too, but
> there is an important implementation issue.
This "pattern" has been supported by the language since the very first
standard of C++.
> Any function of type HandlerPtr expects an object of type tbase* as this
> argument, while the function test::f expects an object of type test* as
> this argument. Normally when the tbase slice of test is accessed the
> compiler generates the required code to access the slice. But this time
> is the other way around (contravariance). The compiler converts test* to
> tbase* to call the function pointer which claims to need tbase*, but the
> function behind p expects test*. Ouch, who does the downcast?
The compiler does it. It is required to perform the downcast by the
language standard. This downcast is in general case a non-trivial
operation, which is why a correctly implemented pointer to member
function has to carry some extra information with it (and which is why
its size is generally larger than that of an ordinary pointer). This
extra information is there specifically to allow the compiler to
generate the code for proper run-time downcast.
> Also how should the compiler ensure that the this pointer used to invoke
> a function pointer of type HandlerPtr is of type test*.
It doesn't. It is your responsibility. If you attempt to access a member
that doesn't really exist, the behavior is undefined.
> Member function pointers are not the solution of your problem. You
> should use an observer pattern instead.
They are. They are not developed very well, meaning that some pattern
(like Observer) might indeed be a better solution. But your specific
arguments against the pointer are based on totally incorrect premise.
> Member function pointers are the other way around. A pointer of type
> void(test::*)() can be used to call functions of type void(tbase::*)(),
> since every function that expects tbase* can also be invoked with test*.
> The compiler will handle the necessary conversion at each invocation of
> the function pointer. For this reason member function pointers are
> larger than one machine size word in general. The compiler usually adds
> offset information for this. (Things get even more complicated if tbase
> is a virtual base class of test.)
You are almost right. Member function pointers are indeed "the other way
around". Member function pointers are contravariant. They support
implicit conversion down the hierarchy, as well as they support an
explicit conversion up the hierarchy. The latter is explicitly allowed
by the specification of `static_cast`.
--
Best regards,
Andrey Tarasevich
Back to comp.lang.c++ | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
Fun with member-function pointers "Default User" <defaultuserbr@yahoo.com> - 2011-08-22 16:41 -0500
Re: Fun with member-function pointers Victor Bazarov <v.bazarov@comcast.invalid> - 2011-08-22 19:25 -0400
Re: Fun with member-function pointers "Default User" <defaultuserbr@yahoo.com> - 2011-08-22 19:06 -0500
Re: Fun with member-function pointers Juha Nieminen <nospam@thanks.invalid> - 2011-08-23 07:09 +0000
Re: Fun with member-function pointers Victor Bazarov <v.bazarov@comcast.invalid> - 2011-08-23 08:04 -0400
Re: Fun with member-function pointers Juha Nieminen <nospam@thanks.invalid> - 2011-08-23 13:34 +0000
Re: Fun with member-function pointers Victor Bazarov <v.bazarov@comcast.invalid> - 2011-08-23 13:02 -0400
Re: Fun with member-function pointers Andrey Tarasevich <andreytarasevich@hotmail.com> - 2011-08-23 19:12 -0700
Re: Fun with member-function pointers Andrey Tarasevich <andreytarasevich@hotmail.com> - 2011-08-23 18:51 -0700
Re: Fun with member-function pointers Marcel Müller <news.5.maazl@spamgourmet.com> - 2011-08-23 09:07 +0200
Re: Fun with member-function pointers Juha Nieminen <nospam@thanks.invalid> - 2011-08-23 10:09 +0000
Re: Fun with member-function pointers Marcel Müller <news.5.maazl@spamgourmet.com> - 2011-08-23 15:04 +0200
Re: Fun with member-function pointers "Default User" <defaultuserbr@yahoo.com> - 2011-08-23 10:36 -0500
Re: Fun with member-function pointers Andrey Tarasevich <andreytarasevich@hotmail.com> - 2011-08-23 18:46 -0700
Re: Fun with member-function pointers "Default User" <defaultuserbr@yahoo.com> - 2011-08-24 09:33 -0500
Re: Fun with member-function pointers Andrey Tarasevich <andreytarasevich@hotmail.com> - 2011-08-24 08:32 -0700
Re: Fun with member-function pointers "Default User" <defaultuserbr@yahoo.com> - 2011-08-24 11:15 -0500
Re: Fun with member-function pointers Andrey Tarasevich <andreytarasevich@hotmail.com> - 2011-08-24 09:30 -0700
Re: Fun with member-function pointers Marcel Müller <news.5.maazl@spamgourmet.com> - 2011-08-24 12:27 +0200
Re: Fun with member-function pointers Andrey Tarasevich <andreytarasevich@hotmail.com> - 2011-08-24 06:46 -0700
Re: Fun with member-function pointers Marcel Müller <news.5.maazl@spamgourmet.org> - 2011-08-24 18:57 +0200
Re: Fun with member-function pointers Paul <pchristor@yahoo.co.uk> - 2011-08-24 13:08 -0700
Re: Fun with member-function pointers Andrey Tarasevich <andreytarasevich@hotmail.com> - 2011-08-24 13:44 -0700
Re: Fun with member-function pointers Paul <pchristor@yahoo.co.uk> - 2011-08-25 04:23 -0700
Re: Fun with member-function pointers Andrey Tarasevich <andreytarasevich@hotmail.com> - 2011-08-25 07:31 -0700
Re: Fun with member-function pointers Andrey Tarasevich <andreytarasevich@hotmail.com> - 2011-08-25 08:21 -0700
Re: Fun with member-function pointers Paul <pchristor@yahoo.co.uk> - 2011-08-25 10:50 -0700
Re: Fun with member-function pointers Leigh Johnston <leigh@i42.co.uk> - 2011-08-25 13:57 +0100
Re: Fun with member-function pointers Leigh Johnston <leigh@i42.co.uk> - 2011-08-25 14:08 +0100
Re: Fun with member-function pointers Andrey Tarasevich <andreytarasevich@hotmail.com> - 2011-08-25 07:32 -0700
Re: Fun with member-function pointers Leigh Johnston <leigh@i42.co.uk> - 2011-08-25 15:45 +0100
Re: Fun with member-function pointers Andrey Tarasevich <andreytarasevich@hotmail.com> - 2011-08-25 07:48 -0700
Re: Fun with member-function pointers Andrey Tarasevich <andreytarasevich@hotmail.com> - 2011-08-23 18:43 -0700
Re: Fun with member-function pointers Paul <pchristor@yahoo.co.uk> - 2011-08-23 03:49 -0700
Re: Fun with member-function pointers Paul <pchristor@yahoo.co.uk> - 2011-08-23 06:44 -0700
Re: Fun with member-function pointers Andrey Tarasevich <andreytarasevich@hotmail.com> - 2011-08-23 18:28 -0700
Re: Fun with member-function pointers Jeff Flinn <TriumphSprint2000@hotmail.com> - 2011-08-25 11:29 -0400
csiph-web