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

How does C++ compiler handle member variable memory offset in the case of multiple inheritance?

假设我们有基础类:

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中与ClassA的指针相差8个字节,而在ClassB中仅相差4个字节.

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

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

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

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

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

对于多重继承,这不可能适用于所有基 classes - 只有一个会从与派生对象相同的地址开始。这意味着拥有 ClassA 类型的对象和三个指向它的指针——CommonClass、ParentOfA 和 ClassA 类型,当比较 CommonClass 和 ParentOfA 指针时,其中一个将指向与 ClassA 指针相同的地址。另一个将指向不同的 addres-to base class 部分的开头,与指针的类型相同。

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

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

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 * 的情况下找到 common_value 的偏移量没有问题。

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