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
的指针将在调用位置进行调整,以便函数在所有情况下都可以使用相同的偏移量。