Why is this the same even when object pointers differ in multiple inheritance?

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?

+3
source share
4

, "thunk", this. vtbl casted1 , - IDerived1 CClass CClass ( casted1 CClass object).

casted2 - IDerived2 CClass, vtbl thunk CClass::Common() . Thunk this CClass, CClass::Common(). CClass, , .

S tanley Lippman " ++" , 4.2 " / MI" .

+3

, vtable . , ICommonBase* , , IDerived2. ->foo bar(). , .

. Derived Base, , 0 Derived 0 Base, , Derived, Base. , , Base1 Base2. .

, , ( Foo), , Foo Base1 X, Base2 Y. this.

Foo, Foo, - "" , , Base1 Base2. , this "" .

, , , .

+3

, :

v-pointer for IDerived1
v-pointer for IDerived2
....
....

... ..

this , v- IDerived1. IDetived2 v- IDerived2, sizeof () this.

+1

g++ 4.3, (. ), , casted1 casted2 .

, g++ 4.3 :

ICommonBase* casted1 = (ICommonBase*)(IDerived1*)object; 
ICommonBase* casted2 = (ICommonBase*)(IDerived2*)object;

.

+1

All Articles