Re: Casting of pointer to member functions

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance



"David Olsson" wrote:
I am writing an application in which I use pointer to
member functions
to achieve a certain functionality. At one point I need to
be able to
cast between different types of member function. In a very
simplified
version, this is what I want to do:

class Base {
public:
typedef void (Base::*MethodPrototype)();

Base(MethodPrototype method): m_method(method) {}

void call() {
(this->*m_method)();
}
private:
MethodPrototype m_method;
};

class Derived: virtual public Base {
public:
Derived():
Base(reinterpret_cast<MethodPrototype>(&Derived::myMethod))
{}

int myMethod() {
return(1);
}
};

The constructor of the Derived class failes to compile as
visual c++
reports that the reinterpret_cast is invalid. This does
however only
occur when the inheritance is virtual, if it isn't
virtual, the casting
works fine. Furthermore, the above code compiles with GCC
3.4.2. Is it
Visual C++ or GCC that isn't quite conformant. And is
there a
workaround to be able to do this?


Even if it will compile I wonder whether it will work
properly. Pointers to members can differ in their sizes from
4 to 16 bytes. The error you get tells you that pointer to
Derived member cannot fit into pointer to Base member. When
you remove `virtual' modifier pointers have the same size,
so compiler can assign `&Derived::myMethod' to variable of
`MethodPrototype' type.

You can safely cast pointer to member to other type (which
must be poiner to member, too) only in case you intend to
cast it back before any usage. That's the only thing that
Standard guarantees you:

<quote>
5.2.10/9 Reinterpret cast

An rvalue of type "pointer to member of X of type T1" can be
explicitly converted to an rvalue of type "pointer to member
of Y of type T2" if T1 and T2 are both function types or
both object types. The null member pointer value (4.11) is
converted to the null member pointer value of the
destination type. The result of this conversion is
unspecified, except in the following cases:

? converting an rvalue of type "pointer to member function"
to a different pointer to member function type and back to
its original type yields the original pointer to member
value.

? converting an rvalue of type "pointer to data member of X
of type T1" to the type "pointer to data member of Y of type
T2" (where the alignment requirements of T2 are no stricter
than those of T1) and back to its original type yields the
original pointer to member value.
</quote>

In your specific case you can use /vmg compiler switch, so
compiler will assume the worst case all the time and
generate pointers to member large enough to accommodate to
any input. However, when class hierarchy will expand and/or
`Derived::myMethod' will access data members, then you're
likely to crash inside `Base::call' because necessary `this'
adjustments won't be performed.

HTH
Alex


.



Relevant Pages

  • Re: Casting of pointer to member functions
    ... cast it back before any usage. ... The example above will compile only if /ymg compiler switch ... the bits that pointer is ... calling a member function through such pointer is ...
    (microsoft.public.vc.language)
  • Re: Problem bei for Anweisung
    ... wenn man ein char-Feld hat. ... — if it has pointer type, it is initialized to a null pointer; ... if it is an aggregate, every member is initialized ... according to these rules; ...
    (de.comp.lang.c)
  • Re: Class members, pointers or not?
    ... > Is it best to declare class member objects as pointers or not pointers? ... using pointer members (and reference members) ...
    (comp.lang.cpp)
  • Re: pointer to a method
    ... > classes each containing it's own specific member variables. ... > am searching for and the value is a pointer to a method from one of the ... and the proxy can call the appropriate member function of the appropriate ... you'd have to cast the pointer to the correct derived-class pointer in the ...
    (comp.lang.cpp)
  • Re: can the member function be compared?
    ... So we can set a void pointer's value to be the reference of the member function like below ... I have a question about the pointer ptr. ... Pointer to member is not like regular pointer. ... If you need to distinguish between pointers to member function, then you could make arbitrary index for them. ...
    (microsoft.public.vc.language)