How to use reinterpret_cast to convert to a pointer to a derived class in C ++

Here is my test case:

struct base { virtual ~base(){} int x; }; struct derived: public virtual base { base * clone() { return new derived; } derived(): s("a") {} std::string s; }; int main () { derived d; base * b = d.clone(); derived * t = reinterpret_cast<derived*>(b); std::cout << t->s << std::endl; return 0; } 

Crash on the line where I type s. Since "b" is a pointer to a derived class, reinterpret_cast should just work. I wonder why he is falling. At the same time, if I replace reinterpret_cast with dynamic_cast, then it will work.

+4
source share
3 answers

Even if b here is dynamically of type derived , you should use dynamic_cast . To do this, use dynamic_cast to dynamically convert the base class pointer to a derived class at run time.

reinterpret_cast takes a raw pointer and considers it derived. However, due to virtual inheritance, there must be a slight adjustment to the pointer indicating the correct label dispatch table, and that is exactly what dynamic_cast will do.

+10
source

Not reinterpret_cast , this will cause a problem with multiple or virtual inheritance, for example, in your case. Are you not just static_cast doing this job here?

To find out why look for virtual inheritance implementations. It is common to keep a pointer to the base class inside the object, so the virtual database does not have the same address except for its derived classes. There is a similar case when multiple inheritance is used.

In short, reinterpret_cast cannot do much more than cast pointers to ints and back (if int has enough size to contain a pointer).

+1
source

Like the other answers here, you cannot use reinterpret_cast this way because the value of the pointer to base actually different from the value of the pointer to derived . A valid pointer is output at runtime, so you should use dynamic_cast . static_cast cannot work, because you do not know at design time through which intermediate type the most derived class (the one you want to use) was obtained from the type you have a pointer to.

The real question here should be: I know at design time how to calculate the derived pointer with the base pointer. How to avoid runtime limitation ( dynamic_cast )?

Frankly, I don’t see a really good option here, but a possible possibility is to save the pointer to the most derived type in a constant pointer inside the root class, for example:

 struct base { void* const self; virtual ~base() {} protected: base(void* self) : self(self) {} }; struct derived : public virtual base { derived() : base(this) {} } 

This is ugly and dangerous because it sacrifices type safety for performance (if you are really lucky, you get little performance at runtime). But you can reinterpret_cast a base pointer (a member of self type void* ) into a derived pointer.

0
source

All Articles