C + + supports multiple inheritance, however multiple inheritance can cause some strange problems, and I encountered a pointer conversion problem in the previous period, very typical.
Let's look at a simple test code:
#include <iostream>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<ia*> (c)); Testcastb ((void*) static_cast<ib*> (c)); cout << ENdl cout << "dynamic_cast to void*, then to IA or IB:" << Endl; Testcasta ((void*) dynamic_cast<ia*> (c)); Testcastb ((void*) dynamic_cast<ib*> (c)); return 0;}
I tested it:
- Cast to Void*
- First static_cast and then cast to void*
- First dynamic_cast and then cast to void*
(32-bit program) The results of the run are as follows:
The difference is obvious, and the conclusion is clear: When multiple inheritance occurs, the address offset takes place when a subclass pointer is converted to a parent class pointer other than the first inheritance (note the red portion of the image). This is because each parent class consumes 4 bytes to maintain its own virtual function table. So, when cmulti* is converted to ib*, the pointer is 4 because IA is the first parent of Cmulti, IB is the second parent class, and so on ...
If we have to use void* for code adaptation in some places, it is important to pay attention to this when we encounter multiple inheritance, otherwise it is likely that you are invoking the B () method, which actually executes a () and does not achieve the desired effect.
C + + multiple inheritance and void* pointer conversion problems