gpt4 book ai didi

c++ - 将 Derived** 转换为 Base** 并将 Derived* 转换为 Base*

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:26:05 26 4
gpt4 key购买 nike

好的,我正在通读 this entry in the FQA处理将 Derived** 转换为 Base** 的问题以及为什么它被禁止,我得到的问题是你可以分配给 Base* 不是 Derived* 的东西,所以我们禁止这样做。

到目前为止,还不错。

但是,如果我们深入应用该原则,我们为什么不禁止这样的例子呢?

void nasty_function(Base *b)
{
*b = Base(3); // Ouch!
}

int main(int argc, char **argv)
{
Derived *d = new Derived;
nasty_function(d); // Ooops, now *d points to a Base. What would happen now?
}

我同意 nasty_function 做了一些愚蠢的事情,所以我们可以说让这种转换很好,因为我们启用了有趣的设计,但我们也可以说双重间接:你得到了一个 Base **,但是你不应该为它的 deference 分配任何东西,因为你真的不知道 Base ** 是从哪里来的,就像 Base *

那么,问题来了:这个额外级别的间接寻址有什么特别之处?也许重点是,只有一个间接级别,我们可以使用虚拟 operator= 来避免这种情况,而同样的机制在普通指针上不可用?

最佳答案

nasty_function(d); // Ooops, now *d points to a Base. What would happen now?

不,它没有。它指向一个Derived。该函数只是更改了现有 Derived 对象中的 Base 子对象。考虑:

#include <cassert>

struct Base {
Base(int x) : x(x) {}
int x;
};
struct Derived : Base {
Derived(int x, int y) : Base(x), y(y) {}
int y;
};

int main(int argc, char **argv)
{
Derived d(1,2); // seriously, WTF is it with people and new?
// You don't need new to use pointers
// Stop it already
assert(d.x == 1);
assert(d.y == 2);
nasty_function(&d);
assert(d.x == 3);
assert(d.y == 2);
}

d 不会神奇地变成一个 Base,对吧?它仍然是 Derived,但它的 Base 部分发生了变化。


在图片中:)

这是 BaseDerived 对象的样子:

Layouts

当我们有两层间接时,它不起作用,因为被分配的东西是指针:

Assigning pointers - type mismatch

请注意,BaseDerived 对象都没有尝试更改:只有中间指针。

但是,当您只有一个间接级别时,代码会以对象允许的方式修改对象本身(它可以通过私有(private)化、隐藏或从 Base 中删除赋值运算符来禁止它):

Assigning with only one level of indirection

注意这里没有指针发生变化。这就像更改对象的一部分的任何其他操作一样,例如 d.y = 42;

关于c++ - 将 Derived** 转换为 Base** 并将 Derived* 转换为 Base*,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11264587/

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