将unique_ptr对象移到vector对象中并继续使用
C++ Move a unique_ptr to a vector and continue using it
我开始玩std::unique_ptr
,我只是不想把事情搞砸。
在我的代码中,我创建了一个std::unique_ptr
,将其存储在vector
上以供以后在另一个上下文中使用,并继续使用指针:
#include <iostream>
#include <string>
#include <memory>
#include <vector>
class MyClass {
public:
void doWhatever ()
{
std::cout << "Var = " << variable << std::endl;
}
int variable = 0;
};
class Controller {
public:
std::vector<std::unique_ptr<MyClass>> instances;
};
class OtherClass {
public:
void myFunction()
{
Controller control;
std::unique_ptr<MyClass> p(new MyClass);
control.instances.push_back(std::move(p));
// Continue using p.
p->doWhatever(); // Is this valid ?
p->variable = 10; // Is this valid ?
p->doWhatever(); // Is this valid ?
}
};
int main()
{
OtherClass cl;
cl.myFunction();
}
代码可以编译,但是在执行时出现分段错误。
我想象在将指针移动到向量后调用p
是无效的....如果是这样,解决方案是什么?
OBS:我无法使用指针移动到之后的向量。在实际应用中,这将在多线程环境中运行,其中一个磁头使用向量数据,而另一个继续使用原始指针p
。
唯一指针的名称说明了一切。这意味着它是完全唯一的,所以当它超出作用域时,它可以被安全地删除。
当你在指针上使用std::move
时,它将其强制转换为右值引用,然后调用move构造函数,这意味着它被移动,而不是复制。这就像如果你把盘子从洗碗机里移到橱柜里,它并不在洗碗机里。在代码中,这意味着被移动的unique_ptr
被设置为nullptr
选择:
- 使用refcount的
shared_ptr
。这将允许您拥有多个实例,并在删除最后一个实例后调用析构函数。使用这种方法的另一个好处是,如果vector不应该阻止对象被销毁,那么它可以存储weak_ptr
s。 - 在
unique_ptr
上使用std::move
之前缓存原始指针以将其移动到vector
中。这可能是不安全的,因为如果您试图在vector销毁之后使用该指针,它将是未定义行为,因为它将是一个悬空引用。
简而言之,不,任何对象在移动后使用都是无效的。编辑:除非你正在调用一个没有先决条件的函数(谢谢,Benjamin Lindley)。
这是因为当你std::move
a unique_ptr
时,你将该内存的所有权转移给了另一个unique_ptr
。(真正发生的是,std::move
将unique_ptr
标记为r值引用,然后另一个unique_ptr
的构造函数看到这一点并高兴地执行指针窃取)。你移到的unique_ptr
现在可以做任何它想做的事情,包括删除内存和使你拥有的任何其他引用无效。
您可以将指针解引用为原始指针(通过unique_ptr::get()
)以访问它所指向的内容,然后将唯一指针移动到vector中。然而,unique_ptr
的整体理念是唯一所有权;您的原始指针随时可能失效。
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- CMake-按正确顺序将项目与C运行时对象文件链接
- 空基优化子对象的地址
- 将对象数组的引用传递给函数
- 你能重载对象变量名本身返回的内容吗
- C++使用整数的压缩数组初始化对象
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 将对象移动到std::shared_ptr
- 代理对象的常量正确性
- 循环后如何继续阅读
- 提升 ASIO 无法识别计时器对象
- 将Ref对象作为类成员
- 将包含C样式数组的对象初始化为成员变量(C++)
- 提升序列化仅适用于主要?当我在其他对象中使用时,继续说"has no member named ‘serialize’"
- 为什么悬空指针可以继续访问对象
- c++分离线程在其关联对象被删除后继续工作
- 为什么继续使用const对象呢?
- 将unique_ptr对象移到vector对象中并继续使用
- 为什么要继续对不可变对象使用getter呢?