C++ C++;编译器在多重继承的情况下处理成员变量内存偏移量?

C++ C++;编译器在多重继承的情况下处理成员变量内存偏移量?,c++,pointers,inheritance,multiple-inheritance,memory-layout,C++,Pointers,Inheritance,Multiple Inheritance,Memory Layout,假设我们有基类: 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

假设我们有基类:

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
然后
ClassA
ClassB
的结构如下所示:

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

ClassB:
  ParentOfB:
    int some_int_3;
    int common_value;
因此,对于相同的
common_值
成员变量,在
ClassA
中,它距离
ClassA
的指针只有8个字节,而在
ClassB
中,它距离指针只有4个字节

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


在处理
->common_值时,编译器如何提前知道要查找的偏移量?
ClassA
ClassB
都可以作为指针传入

调用方的任务是将正确的地址传递给函数。指向类的指针始终指向同一类的对象的开头,这样成员偏移就可以工作

对于单一继承,基对象和派生对象从同一地址开始(换句话说,基部分位于派生对象的开头)

对于多重继承,这对于所有基类来说都是不可能的——只有一个基类从与派生对象相同的地址开始。这意味着,当比较CommonClass和ParentOfA指针时,有ClassA类型的对象和指向它的三个指针(CommonClass、ParentOfA和ClassA类型),其中一个指针将指向与ClassA指针相同的地址。另一个将指向基类部分开头的不同地址,与指针的类型相同


哪个指针将指向对象内存位置的开头,取决于派生对象中基本部分的顺序。此顺序由实现定义。

调用方的任务是将正确的地址传递给函数。指向类的指针始终指向同一类的对象的开头,这样成员偏移就可以工作

对于单一继承,基对象和派生对象从同一地址开始(换句话说,基部分位于派生对象的开头)

对于多重继承,这对于所有基类来说都是不可能的——只有一个基类从与派生对象相同的地址开始。这意味着,当比较CommonClass和ParentOfA指针时,有ClassA类型的对象和指向它的三个指针(CommonClass、ParentOfA和ClassA类型),其中一个指针将指向与ClassA指针相同的地址。另一个将指向基类部分开头的不同地址,与指针的类型相同


哪个指针将指向对象内存位置的开头,取决于派生对象中基本部分的顺序。此顺序由实现定义。

您的结构图实际上如下所示:

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

ClassB:
  ParentOfB:
    int some_int_3;
  CommonClass:
    int common_value;
(您省略了
CommonClass:
前缀)

如果给定
CommonClass*
,那么很显然,查找
公共值的偏移量是没有问题的


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

您的结构映射实际上如下所示:

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

ClassB:
  ParentOfB:
    int some_int_3;
  CommonClass:
    int common_value;
(您省略了
CommonClass:
前缀)

如果给定
CommonClass*
,那么很显然,查找
公共值的偏移量是没有问题的


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

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