gpt4 book ai didi

c++ - 我如何正确地将 shared_pointers 添加到可能的派生类到 std::vector 中?

转载 作者:搜寻专家 更新时间:2023-10-31 00:12:20 27 4
gpt4 key购买 nike

我基本上是这样设置的:

class B { /* ... */};
class C1 : public B { /* ... */};
class C2 : public B { /* ... */};

class X
{
std::vector<shared_ptr<B>> m_vec;
void addToVector(B* b);
}

addToVector 无法知道有多少类派生自 B 并且不应该关心。它将被这样调用:

someFunction() {
C1 tmp;
/* do something with tmp */
m_myX.addToVector(&tmp);
}

所以在 someFunction 的末尾,tmp 超出范围并将被删除。 addToVector 必须将 shared_ptr push_back 到 vector 中的 tmp 拷贝,但它如何做到这一点?

void X::addToVector(B* b)
{
int i = sizeof(b); // allways sizeof(B) :(
shared_ptr<B> np(b);
m_vec.push_back(np); // garbage collected after calling fn returns :(
}

它应该做的是:

  • 通过调用正确类的复制构造函数/操作符来复制b指向的对象
  • 将该拷贝的 shared_ptr 推回 vector 中。

我该怎么做?

最佳答案

您正在堆栈上创建一个对象,然后将其地址提供给 shared_ptr,它将尝试删除堆栈上的一个对象,这是未定义的行为。

解决方案是停止这样做:

void someFunction() {
C1* c = new C1;
/* do something with *c */
m_myX.addToVector(c);
}

现在堆上有一个对象,它可以由 shared_ptr 拥有。无需复制它。

这只有在 B 有一个虚拟析构函数时才能正常工作,但是可以通过首先创建一个 shared_ptr 来避免这种情况(并且代码可以变得更安全和更清晰):

void someFunction() {
auto c = std::make_shared<C1>();
/* do something with *c */
m_myX.addToVector(c);
}

void X::addToVector(std::shared_ptr<B> b)
{
m_vec.push_back(np);
}

现在堆对象一创建就由 shared_ptr 管理,然后安全地存储在 vector 中。

关于c++ - 我如何正确地将 shared_pointers 添加到可能的派生类到 std::vector 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30478182/

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