是否可以在类中存储unique_ptr,并在C++中存储向量?
Is it possible to store an unique_ptr both in class and vector in C++?
我试图持有一个指向向量(来自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();
}
这样的事情可能吗?据我了解,这段代码很可能会失败。会将第bar2
和bar3
的地方移动到 nullptr 吗?创建一个unique_ptr
,存储一个带有bar2->get()
的原始指针,然后push_back
vector
工作?
注意:这些对象只属于此类,因此唯一性是有意义的。
No.unique_ptr的全部意义在于独一无二。这意味着您无法复制它。
但是,您可以复制unique_ptr管理的基础指针。
例如unique_ptr<Foo> foo(new Foo);
Foo* foo_copy = foo.get();
执行此操作时,您需要注意几件事:
不要删除
foo_copy
。这是unique_ptr的工作。如果你删除foo_copy,那么你将犯双重删除的罪,它具有未定义的行为(即允许编译器生成发射核导弹的代码(。销毁
foo
后不要使用foo_copy
,因为销毁foo
时,将删除基础指针(除非 foo 放弃了基础指针的所有权,并且基础指针尚未通过其他方式删除(。这是免费后使用的罪过,它也有UB。
搬家是unique_ptr放弃所有权的一种方式。一旦你搬出unique_ptr,它就不再指向任何东西(这就是搬家的全部意义;当你从A走到B时,你不再在A,因为只有一个人,你决定位于B(。我相信尝试在空unique_ptr上使用 -> 运算符调用方法也是 UB。
似乎你应该做的是
vector<unique_ptr<Base>> v;
Derived* ob = v[i].get();
让我重申,这有点危险和不寻常。
切线:我发现你没有使用虚拟方法是非常可疑的;虚拟确实应该是默认值(有点像默认值的双精度,而不是浮点数,即使浮点数看起来像并且应该是默认值(。实际上,我发现您正在使用继承是可疑的。继承是有史以来最被高估的功能之一。我怀疑这可能是你的麻烦的根源。例如,Go 语言甚至没有继承,但它确实具有多态性(即同一接口的不同实现(。
PS:请不要通过调用UB来意外地消灭人类。
- 创建一个数组,以允许用户输入存储并稍后在代码中使用
- 是否可以将具有不同签名的 lambda 存储在 std::vector 中并在函数中执行它们(使用各自的参数)?
- 是否可以在类中存储unique_ptr,并在C++中存储向量?
- 是否可以将多个结构作为一个数据包存储在一个函数中,然后传递给其他函数并在那里提取?
- 将25个甚至整数存储到一个名为intlist的整数阵列中,然后在屏幕上显示数组,并在屏幕上显示名为fivintegers
- 存储在全局变量中的函数指针在进入函数时设置为 0,并在退出函数时返回到以前的状态
- 从数组中提取元音,并在另一个数组中存储ND打印
- 对整个垫子图像进行排序并在 OpenCV 中存储索引
- 存储可变参数模板参数并在另一个类中使用它们
- 以数组的形式存储组合框项,并在 WPF 中检索 SelectedId
- 无法存储 stdin 状态并在C++中进行比较
- 存储一个函数的迭代结果,并在被另一个函数调用时使用它们
- 尝试输入整数行并在以矢量作为存储的函数的插入排序类型中排序
- 存储数据和访问,并在C++中执行后从内存中更新
- 在像素GLSL中存储(并读取)大量数据
- 从文件中获取输入并在其中存储平均值
- 通过OCI调用Oracle存储过程,并在C++中使用out-ref游标返回结果
- 如何使用链表来存储表,并在表中搜索项
- 如何存储数据,并在firefox / chrome javascript插件中添加按钮
- 我如何在GPU内存中连续存储矩阵并在需要时使用它