gpt4 book ai didi

c++ - 指针 vector : Why does changing the pointer externally not change the vector element?

转载 作者:行者123 更新时间:2023-12-03 06:56:03 24 4
gpt4 key购买 nike

请看下面的例子:

#include <iostream>
#include <string>
#include <vector>


class Base {
public:
virtual void price() const = 0;
};

class D1 : public Base {
public:
virtual void price() const {
std::cout << "Price of D1\n";
}
};

class D2 : public Base {
public:
virtual void price() const {
std::cout << "Price of D2\n";
}
};

int main()
{
std::vector<Base*> v;


Base* b = new D1();
v.push_back(b);
v[0]->price(); // "Price of D1\n" - OK!

b = new D2();
v[0]->price(); // "Price of D1\n"?! Why not "Price of D2\n"
}

一个简单的基类有两个派生类。在我的 main() 中,我声明了一个包含指向基类的指针的 vector ,并用指向 D1 的对象的指针填充它。

当我将 b 更改为指向 D2 的指针时,b = new D2();,为什么这不会更改元素 v[0] 相应的?他们不应该指向同一件事吗?

最佳答案

我会尝试在较低的层次上解释它。

首先,要明白指针本质上只是一个保存值的变量,它恰好是内存中的一个地址。
让我们简化一下,假设每种类型都具有相同的大小,并且只有 5 个内存地址(在堆上)。 (我也会忽略数组也会在堆上分配。)
我们现在执行

Base* b = new D1();

假设分配的内存位于地址 3。b 现在是一个仅保存值 3 的变量。我们的(堆)内存如下所示:

0: ?
1: ?
2: ?
3: variable of type D1
4: ?

然后我们继续

v.push_back(b);

现在数组 v 包含一个值为 3 的条目。

b = new D2();

我们现在分配了一个新的内存部分,比方说在地址 1:

0: ?
1: variable of type D2
2: ?
3: variable of type D1
4: ?

b现在存放的是这个地址,也就是b的值为1。如果我们看v,我们并没有改变它。它包含一个值为 3 的条目。

v[0]->price();

这给了我们一个值为 3 的指针,我们取消引用并打印它。鉴于我们上面的内存映射,那里存储的是一个 D1 类型的变量。

这是否为您澄清了事情?

我还对您的代码进行了一些扩展,以使用实际地址进行演示:
http://www.cpp.sh/3s4b4
(如果您运行该代码,请注意紧接着分配的地址往往几乎相似,通常仅相差一个数字,因此仔细观察。例如,我得到 0x1711260 和 0x1711220。)


如果你真的需要做你期望的事情,你可以在 Base** 上存储一个 vector ,并将 b 的地址存储在 vector 中:

std::vector<Base**> v;

Base* b = new D1();
v.push_back(&b);
(*v[0])->price();

b = new D2();
(*v[0])->price();

实现于 http://www.cpp.sh/8c3i3 .但我不建议,如果你不是绝对需要,缺乏可读性和不必要的混淆。 (请注意,第一个指针在此示例中未被删除,并且在更改 b 后无法访问,因此我们会泄漏内存。)

关于c++ - 指针 vector : Why does changing the pointer externally not change the vector element?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63934567/

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