我已经在Unity上工作了一段时间,然后回来使用Visual Studio 2015做一些C++.我遇到了这个类定义
class A
{
public:
A();
virtual ~A();
A(const A&) = delete;
A& operator=(const A&) = delete;
private:
…
}
Run Code Online (Sandbox Code Playgroud)
此类动态分配如下:
ObjPtr obj = ObjPtr(new A());
Run Code Online (Sandbox Code Playgroud)
where ObjPtr是一个定义的类型,如下所示:
typedef std::unique_ptr<A> objPtr;
Run Code Online (Sandbox Code Playgroud)
并将这些创建的对象添加到std::vector<ObjPtr>使用中std::move.在一个点上,我需要遍历对象的列表,如果我找到的东西,满足我的标准,保持它的一个副本.
ObjPtr keep;
for(auto& object : GetObjectList() )
{
if(/*check if its the object I want*/)
{
keep = object;
}
}
Run Code Online (Sandbox Code Playgroud)
GetObjectList返回的位置const std::vector<ObjPtr>&.
但我得到了"试图引用删除的功能".我做了一些谷歌搜索并试图删除该= delete部分,甚至评论了2行.我甚至试图这样做
ObjPtr keep = std::move(object);
Run Code Online (Sandbox Code Playgroud)
但我仍然得到删除的功能错误.任何人都可以看到我做错了什么或指向一些可以帮助的资源吗?
5go*_*der 10
A std::unique_ptr无法复制.即使托管对象可以(但你的不能).
你有几个选择(都有不同的效果):
将类型更改keep为非拥有原始指针(aka A *)并使用keep = object.get();.这是安全的,当且仅当你知道你不会使用keep长于ObjectList(或者更准确地说,你把地址的对象)的存在.
移动std::unique_ptr从容器中,即使用keep = std::move(object);.当然,现在你有一个差距ObjectList.(我知道你已经编辑你的问题说ObjectList的const,这意味着你不能修改,因此无法移动的物体出来.)
改变的类型ObjPtr来std::shared_ptr<A>,如果你想共享所有权的语义.
如果你绝对想要一个对象的副本,你可以添加一个virtual成员函数,以A多态方式克隆该对象.
class A
{
public:
virtual std::unique_ptr<A> clone() = 0;
…
};
Run Code Online (Sandbox Code Playgroud)
然后,您可以在class派生自的每个叶子中实现该功能A.在循环中,然后使用keep = object->clone();.为此,您可能想要制作复制构造函数,protected但不要这样做delete.
不要使用,keep = std::make_unique<A>(*object);因为它不会尊重对象的实际(动态)类型,并始终切片到A.(因为你A的副本不可复制,所以无论如何都不行.)
唯一指针之所以“唯一”,是因为指向一个对象只能存在一个这样的指针。如果您制作了唯一指针的副本,那么您将拥有两个事物,每个事物都拥有基础对象。当每一个被销毁时,该对象都会被销毁,从而导致双重删除。
如果您需要多个所有权,请使用shared_ptr. 如果您不需要保留副本的代码的所有权,则不要保留副本,而是保留指针或引用。
| 归档时间: |
|
| 查看次数: |
9218 次 |
| 最近记录: |