是否可以在类中存储unique_ptr,并在C++中存储向量?

Is it possible to store an unique_ptr both in class and vector in C++?

本文关键字:存储 并在 C++ 向量 ptr unique 是否      更新时间:2023-10-16

我试图持有一个指向向量(来自Base类(和Derivated类对象的唯一指针,所以后来我能够为所有人调用一个方法。但是我想从Derivated类调用aswell方法,所以我也需要存储它们的引用。

class Foo
{
vector<unique_ptr<Base>> bar;
unique_ptr<Derivated1> bar2;
unique_ptr<Derivated2> bar3;
}
Foo::Foo(){
this->bar2 = make_unique<Derivated1>();
this->bar2->doSomethingDerivated1();
this->bar3 = make_unique<Derivated2>();
this->bar->push_back(move(bar2));
this->bar->push_back(move(bar3));
}
Foo::callForAll() {
for (const auto& foo: this->bar) foo->doSomethingBase();
}
Foo::callForDerivated1() {
this->bar2->doSomethingDerivated1();
}

这样的事情可能吗?据我了解,这段代码很可能会失败。会将第bar2bar3的地方移动到 nullptr 吗?创建一个unique_ptr,存储一个带有bar2->get()的原始指针,然后push_backvector工作?

注意:这些对象只属于此类,因此唯一性是有意义的。

No.unique_ptr的全部意义在于独一无二。这意味着您无法复制它。

但是,您可以复制unique_ptr管理的基础指针。

例如
unique_ptr<Foo> foo(new Foo);
Foo* foo_copy = foo.get();

执行此操作时,您需要注意几件事:

  1. 不要删除foo_copy。这是unique_ptr的工作。如果你删除foo_copy,那么你将犯双重删除的罪,它具有未定义的行为(即允许编译器生成发射核导弹的代码(。

  2. 销毁foo后不要使用foo_copy,因为销毁foo时,将删除基础指针(除非 foo 放弃了基础指针的所有权,并且基础指针尚未通过其他方式删除(。这是免费后使用的罪过,它也有UB。

搬家是unique_ptr放弃所有权的一种方式。一旦你搬出unique_ptr,它就不再指向任何东西(这就是搬家的全部意义;当你从A走到B时,你不再在A,因为只有一个人,你决定位于B(。我相信尝试在空unique_ptr上使用 -> 运算符调用方法也是 UB。

似乎你应该做的是

  1. vector<unique_ptr<Base>> v;
  2. Derived* ob = v[i].get();

让我重申,这有点危险和不寻常。

切线:我发现你没有使用虚拟方法是非常可疑的;虚拟确实应该是默认值(有点像默认值的双精度,而不是浮点数,即使浮点数看起来像并且应该是默认值(。实际上,我发现您正在使用继承是可疑的。继承是有史以来最被高估的功能之一。我怀疑这可能是你的麻烦的根源。例如,Go 语言甚至没有继承,但它确实具有多态性(即同一接口的不同实现(。

PS:请不要通过调用UB来意外地消灭人类。

相关文章: