When using multiple inheritance, C ++ must support multiple vtables, which leads to "multiple representations" of common base classes.
Here's the code snippet:
#include "stdafx.h" #include <Windows.h> void dumpPointer( void* pointer ) { __int64 thisPointer = reinterpret_cast<__int64>( pointer ); char buffer[100]; _i64toa( thisPointer, buffer, 10 ); OutputDebugStringA( buffer ); OutputDebugStringA( "\n" ); } class ICommonBase { public: virtual void Common() = 0 {} }; class IDerived1 : public ICommonBase { }; class IDerived2 : public ICommonBase { }; class CClass : public IDerived1, public IDerived2 { public: virtual void Common() { dumpPointer( this ); } int stuff; }; int _tmain(int argc, _TCHAR* argv[]) { CClass* object = new CClass(); object->Common(); ICommonBase* casted1 = static_cast<ICommonBase*>( static_cast<IDerived1*>( object ) ); casted1->Common(); dumpPointer( casted1 ); ICommonBase* casted2 = static_cast<ICommonBase*>( static_cast<IDerived2*>( object ) ); casted2->Common(); dumpPointer( casted2 ); return 0; }
it outputs the following result:
206968 //CClass::Common this 206968 //(ICommonBase)IDerived1::Common this 206968 //(ICommonBase)IDerived1* casted1 206968 //(ICommonBase)IDerived2::Common this 206972 //(ICommonBase)IDerived2* casted2
here casted1they casted2have different meanings, which are reasonable, because they indicate different subobjects. At that moment, when the virtual function is called a throw to the base class, it was executed, and the compiler does not know that it was originally the most derived class. However, this is the same every time. How does this happen?
casted1
casted2
, "thunk", this. vtbl casted1 , - IDerived1 CClass CClass ( casted1 CClass object).
this
IDerived1
CClass
object
casted2 - IDerived2 CClass, vtbl thunk CClass::Common() . Thunk this CClass, CClass::Common(). CClass, , .
IDerived2
CClass::Common()
S tanley Lippman " ++" , 4.2 " / MI" .
, vtable . , ICommonBase* , , IDerived2. ->foo bar(). , .
ICommonBase*
->foo
bar()
. Derived Base, , 0 Derived 0 Base, , Derived, Base. , , Base1 Base2. .
Derived
Base
Base1
Base2
, , ( Foo), , Foo Base1 X, Base2 Y. this.
Foo
Foo, Foo, - "" , , Base1 Base2. , this "" .
, , , .
, :
v-pointer for IDerived1 v-pointer for IDerived2 .... ....
... ..
this , v- IDerived1. IDetived2 v- IDerived2, sizeof () this.
IDetived2
g++ 4.3, (. ), , casted1 casted2 .
, g++ 4.3 :
ICommonBase* casted1 = (ICommonBase*)(IDerived1*)object; ICommonBase* casted2 = (ICommonBase*)(IDerived2*)object;
.