C++ 为什么不';两个指针值不相同吗? class Base { ... }; class Derived: public Base { ... }; Derived d; Base *pb = &d; // implicitly convert Derived* ⇒ Base*

C++ 为什么不';两个指针值不相同吗? class Base { ... }; class Derived: public Base { ... }; Derived d; Base *pb = &d; // implicitly convert Derived* ⇒ Base*,c++,pointers,inheritance,casting,C++,Pointers,Inheritance,Casting,这里我们只是创建一个指向派生类的基类指针 对象 但有时,两个指针值将不相同。在这种情况下,将在运行时向派生的指针应用偏移量* 获取正确的基*指针值的指针 为什么两个指针值不相同?如果是因为子对象和父对象在内存中的布局,那么downcast以后如何工作?在使用多重继承时,总是会发生这种情况 class Base1 { int a; }; class Base2 { double b }; class Derived : public Base1, public Base2 { ... }; De

这里我们只是创建一个指向派生类的基类指针 对象 但有时,两个指针值将不相同。在这种情况下,将在运行时向派生的指针应用偏移量* 获取正确的基*指针值的指针


为什么两个指针值不相同?如果是因为子对象和父对象在内存中的布局,那么downcast以后如何工作?

在使用多重继承时,总是会发生这种情况

class Base1 { int a; };
class Base2 { double b };
class Derived : public Base1, public Base2 { ... };

Derived d;
Base1* pb1 = &d;
Base2* pb2 = &d;
现在
&d
不可能同时等于
pb1
pb2
,因为否则
pb1
将等于
pb2
,这是不可能的,因为两个不相关类型的不同非空对象必须占用不同的内存区域。因此,至少在一种情况下,必须应用非零偏移

在大多数具有单继承的实现中,偏移量为零,但标准并不强制要求这样做

实际上,一个典型的实现只需在派生对象的开始处布置基本对象:

 ++-----++
 ||Base ||
 |+-----+|
 |Derived|
 +-------+
但当有多个基地时,一开始只能有一个基地:

 ++-----++
 ||Base1||
 |+-----+|
 ||Base2||
 |+-----+|
 |Derived|
 +-------+
向下转换之所以有效,是因为偏移量在编译时是固定的和已知的,所以在向上转换或向下转换时应用它没有问题


虚拟继承是一个例外。对于虚拟基,偏移量在编译时是未知的。通常,派生对象包含指向其虚拟基的内部隐藏指针,因此向上转换可以工作。但是基不知道其派生对象的位置,因此向下转换无法工作,并且该语言不允许向下转换。

当您有一个多态的继承树时,编译器要求每个对象以VMT(虚拟方法表)开头。如果基类是多态的,指针值将匹配。但是如果基类是非多态的,而派生类是多态的,那么基类不会引入VMT,它是由树下的第一个多态类引入的。VMT将插入基础之前。现在指针值将不匹配。

证据在哪里?@EdHeal:我有问题吗?请澄清哪部分是引用,哪部分是您的。是的-这就是评论的要点-clariffication@whomever-为什么给出关闭标志?你确定-请检查!我认为对于
pb1
pb2
的声明,代码应该分别说
Base1
Base2
。@Matstpeterson是,修复了。@EdHeal是,选中了。@n.m.我的编译器给出了pb1和pb2相同的值。