c++ - 是否可以在 C++ 中的类和向量中存储一个 unique_ptr?
问题描述
我试图保存一个指向向量(来自一个Base
类)和一个Derivated
类对象的唯一指针,所以稍后我可以为所有人调用一个方法。但是我想从类中调用方法,Derivated
所以我也需要为它们存储引用。
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();
}
这样的事情可能吗?据我了解,此代码很可能会失败。会移动地方bar2
和bar3
nullptr吗?创建一个unique_ptr
,存储一个原始指针,bar2->get()
然后push_back
工作vector
?
注意:这些对象只属于这个类,所以唯一是有意义的。
解决方案
不,unique_ptr 的全部意义在于唯一。这意味着您无法复制它。
但是,您可以复制 unique_ptr 管理的基础指针。例如
unique_ptr<Foo> foo(new Foo);
Foo* foo_copy = foo.get();
执行此操作时需要注意几件事:
不要删除
foo_copy
. 这是 unique_ptr 的工作。如果您删除 foo_copy,那么您将犯下双重删除的罪过,它具有未定义的行为(即允许编译器生成发射核导弹的代码)。不要使用
foo_copy
afterfoo
has been destroyed 因为 whenfoo
被销毁,底层指针被删除(除非 foo 已经放弃了底层指针的所有权,并且底层指针还没有被其他方式删除)。这就是free后使用的罪过,它也有UB。
移动是 unique_ptr 放弃所有权的一种方式。一旦你移出一个 unique_ptr,它就不再指向任何东西(这就是移动的全部意义;当你从 A 走到 B 时,你不再在 A,因为只有你们一个人,而且你已经决定改为位于 B)。我相信尝试在空的 unique_ptr 上使用 -> 运算符调用方法也是 UB。
看起来你应该做的是
vector<unique_ptr<Base>> v;
Derived* ob = v[i].get();
让我重申,这有点危险和不寻常。
Tangent:我发现您没有使用虚拟方法非常可疑;virtual 真的应该是默认值(有点像 double 是默认值,而不是 float,即使 float 看起来是并且应该是默认值)。实际上,我发现您使用继承很可疑。继承是有史以来最被高估的功能之一。我怀疑这可能是您的麻烦的根源。例如,Go 语言甚至没有继承,但它确实具有多态性(即同一接口的不同实现)。
PS:请不要通过调用UB意外消灭人类。
推荐阅读
- android - Android Studios 应用登录失败,应用崩溃
- ios - 在核心数据中如何保存字典或数组,如字符串数据?
- data-warehouse - 作为事实表子集的维度有什么用?
- reactjs - 如何从承诺中返回数据,然后通过反应组件中的道具传递它
- css - 如何在悬停时暂停css动画
- python - 在 Python 中为 Old Macdonald 使用列表和循环
- javascript - 使用 discord.js 为我的 discord 机器人创建 Reaction Roll 函数的最佳方法是什么?
- go - 将时间戳转换为字符串
- server - 出于什么编程原因,物联网编程设备总是需要云/服务器访问?
- javascript - OwlCarousal Camera Slider 猫头鹰项目图像,你如何改变定位左右中心?