gpt4 book ai didi

c++ - 为什么两个指针值不相同?

转载 作者:行者123 更新时间:2023-11-30 02:34:42 25 4
gpt4 key购买 nike

引用 Effective C++,Scott Meyer,第 3 版,第 27 项

class Base { ... };
class Derived: public Base { ... };
Derived d;
Base *pb = &d; // implicitly convert Derived* ⇒ Base*

Here we’re just creating a base class pointer to a derived class object, but sometimes, the two pointer values will not be the same. When that’s the case, an offset is applied at runtime to the Derived* pointer to get the correct Base* pointer value.

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

最佳答案

这在使用多重继承时总是会发生。

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

Derived d;
Base1* pb1 = &d;
Base2* pb2 = &d;

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

在大多数具有单一继承的实现中,偏移量为零,但标准没有强制要求。

事实上,典型的实现会简单地将基础对象布置在派生对象的开头:

 ++-----++
||Base ||
|+-----+|
|Derived|
+-------+

但是当有多个基地时,一开始只能走一个:

 ++-----++
||Base1||
|+-----+|
||Base2||
|+-----+|
|Derived|
+-------+

向下转型之所以有效,是因为偏移量是固定的并且在编译时已知,因此在向上转型或向下转型时应用它都没有问题。

一个异常(exception)是虚拟继承。对于虚拟基,偏移量在编译时是未知的。通常,派生对象包含一个指向其虚基的内部隐藏指针,因此向上转型可以工作。但是 base 不知道它的派生对象在哪里,所以向下转换无法工作,并且是语言不允许的。

关于c++ - 为什么两个指针值不相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34368983/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com