Static_cast from Derived * to void * to Base *

I would like to point the pointer to a member of the derived class to void* and from there to the pointer to the base class, as in the example below:

 #include <iostream> class Base { public: void function1(){std::cout<<"1"<<std::endl;} virtual void function2()=0; }; class Derived : public Base { public: virtual void function2(){std::cout<<"2"<<std::endl;} }; int main() { Derived d; void ptr* = static_cast<void*>(&d); Base* baseptr=static_cast<Base*>(ptr); baseptr->function1(); baseptr->function2(); } 

Compiles and gives the desired result (prints 1 and 2 respectively), but is it guaranteed to work? Description of static_cast I found here: http://en.cppreference.com/w/cpp/language/static_cast only mentions the conversion to void* and back to the pointer to the same class (point 10).

+7
c ++ static-cast
source share
3 answers

In general, converting a base from void to a derivative (or vice versa) using static casting is not safe.

There will be times when this will almost certainly work: if everything is involved in the form of a pod or a standard layout, and only one inheritance is involved, then everything should be fine, at least in practice: I do not have a chapter and verses from the standard, but the general idea lies in the fact that the base in this case is guaranteed as a prefix of the derivative, and they will exchange addresses.

If you want to see this crash, mix virtual inheritance, multiple inheritance (both virtual and not), and multiple implementation inheritance, which is not trivial. Basically, when different representations of this type are different from each other, casting void from another and back to another type is doomed. I saw that this did not work in practice, and the fact that it may fail (due to changes in your code base far from the casting point) is why you want to be careful always using the void and pointer with the same type.

+8
source share

In general, no, it is not safe.

Suppose casting Derived* directly on Base* leads to a different address (for example, if multiple inheritance or virtual inheritance is involved).

Now, if you added void* between the command, how does the compiler know how to convert this void* to the corresponding Base* address?

If you need to cast Derived* to void* , you must explicitly port void* back to the original Derived* type. (And from there, casting from Derived* to Base* is implicit anyway, so you end up in the same number of throws and, therefore, it's actually no less convenient.)

+3
source share

From the link you provided

9) A pointer to a member of some class D can be converted to a pointer to a member of its base class B. This static_cast does not perform any checks to ensure that the element really exists in the environment type of the pointed object.

Value as long as you know that upcast is safe, before you do this, it is guaranteed to work. This is why you should use dynamic_cast , which returns nullptr if failed.

Think about it if you want.

 Type * t1; 

static_cast from t1 to one of the classes obtained from it cannot be known at compile time, without an in-depth analysis of your program (which, obviously, this should not be the case), therefore, even if it ends with the Right one, you no way to check. dynamic_cast does extra work at runtime to verify that the conversion was successful, therefore a dynamic prefix.

0
source share

All Articles