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

标签 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

然后 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 都可以作为指针传入。

最佳答案

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

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

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

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

关于c++ - C++编译器在多重继承的情况下如何处理成员变量内存偏移?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42467884/

相关文章:

c++ - 用一个参数调用的重载函数,但我以为我传递了两个

c++ - 不能长疙瘩

c++ - 初始化空的2D vector ?

c++ - 复制后在子类中丢失指针

java - 继承类将所有继承的公共(public)方法更改为私有(private)方法

c++ - 如何删除抽象类中类似的 const 和非 const 成员函数之间的代码重复?

c++ - 检查文件是否存在的 Visual C++ DLL

c - 是否存在相当于 Rust 的 NonNull<T>::dangling() 指针实例化的 C 语言?

c++ - 这会导致内存泄漏吗?

c# - Unity3D - 抽象类,单一行为功能