Analysis of multiple inheritance in C ++ and void * pointer Conversion
C ++ supports multiple inheritance. However, multiple inheritance may cause some strange problems. I encountered a pointer conversion problem some time ago, which is very typical.
Let's first look at a simple test code:
#include
using namespace std;class IA {public: virtual ~IA(){} virtual void a() = 0;};class IB{public: virtual ~IB(){} virtual void b() = 0;};class CMulti : public IA, public IB{public: CMulti(){} ~CMulti(){} void a(){ cout << "C::a()" << endl; } void b(){ cout << "C::b()" << endl; }};void testCastA(void *p){ cout << "cast from void*(" << p << ")to IA*: "; IA *a = (IA *)p; a->a();}void testCastB(void *p){ cout << "cast from void*(" << p << ")to IB*: "; IB *b = (IB *)p; b->b();}int _tmain(int argc, _TCHAR* argv[]){ CMulti * c = new CMulti; cout << "cast to void*, then to IA or IB:" << endl; testCastA((void*)c); testCastB((void*)c); cout << endl; cout << "static_cast to void*, then to IA or IB:" << endl; testCastA((void*)static_cast
(c)); testCastB((void*)static_cast
(c)); cout << endl; cout << "dynamic_cast to void*, then to IA or IB:" << endl; testCastA((void*)dynamic_cast
(c)); testCastB((void*)dynamic_cast
(c)); return 0;}
I tested:
Forced conversion to void * First static_cast and then forced conversion to void * First dynamic_cast and then forced conversion to void *
The running result of (32-bit program) is shown in:
The difference is obvious, and the conclusion is also clear:When the child class pointer is converted to a parent class pointer that is not first inherited when multiple inheritance occurs, an address offset occurs.(Pay attention to the red part on the graph ). This is because each parent class occupies 4 bytes to maintain its own virtual function table. Therefore, when CMulti * is converted to IB *, add 4 to the pointer, because IA is the first parent class of CMulti, IB is the second parent class, and so on ......
If we have to use void * for code adaptation in some places, pay attention to this in case of multiple inheritance. Otherwise, you may call the B () method, the actual execution is a (), which fails to achieve the expected results.