1

说我们有基类:在多继承的情况下,C++编译器如何处理成员变量内存偏移量?

class CommonClass { 
    ... 
    int common_value; 
} 

class ParentOfA { 
    ... 
    int some_int; 
    int some_int_2; 
} 

class ParentOfB { 
    ... 
    int some_int_3; 
} 

我们已经继承的类:

class ClassA : ParentOfA, CommonClass 
class ClassB : ParentOfB, CommonClass 

然后ClassAClassB将有结构是这样的:

ClassA: 
    ParentOfA: 
    int some_int; 
    int some_int_2; 
    int common_value; 

ClassB: 
    ParentOfB: 
    int some_int_3; 
    int common_value; 

因此,对于相同common_value成员变量,在ClassA它距离01个字节8个字节的指针,而在ClassB它只有4个字节。

然后在下面的情况下(假设它是在.cpp文件等等已经编译):

int GetCommonValue(CommonClass* ptr) { 
    return ptr->common_value; 
} 

编译器如何提前知道什么时间偏移查找处理->common_value什么时候?可以将ClassAClassB作为指针传入。

+2

指向'CommonClass'的指针将在调用站点进行调整,以便函数可以在所有情况下使用相同的偏移量。 –

回答

0

调用者的工作是将正确的地址传递给函数。一个指向类的指针总是指向同一类的对象的开始 - 这样成员偏移就可以工作。

对于单一继承,基础和派生对象从相同地址开始(换言之,基础部分位于派生对象的开始处)。

对于所有基类,这是不可能的 - 对于所有基类,只有一个将从与派生对象相同的地址开始。这意味着在比较CommonClass和ParentOfA指针时,具有ClassA类型的对象和指向它的三个指针(类型CommonClass,ParentOfA和ClassA),其中一个指针指向与ClassA指针相同的地址。另一个将指向不同的地址 - 与基类类型的开始部分相同,与指针的类型相同。

哪个指针指向对象内存位置的开始,取决于派生对象中基础部件的顺序。这个顺序是实现定义的。

0

你的结构图实际上是这样的:

ClassA: 
    ParentOfA: 
    int some_int; 
    int some_int_2; 
    CommonClass: 
    int common_value; 

ClassB: 
    ParentOfB: 
    int some_int_3; 
    CommonClass: 
    int common_value; 

(您省略了CommonClass:前缀)。

希望很明显,找到common_value的偏移量没有问题,给定CommonClass *

也许你忽略了如果将ClassB *转换为CommonClass *,它会指向内存中的不同位置?编译器知道CommonClassClassB中的偏移量,就像它知道任何成员变量的偏移量一样。

相关问题