C++ C++;将唯一的ptr移动到向量并继续使用它

C++ C++;将唯一的ptr移动到向量并继续使用它,c++,pointers,c++11,vector,unique-ptr,C++,Pointers,C++11,Vector,Unique Ptr,我开始玩弄std::unique_ptr,我只是不想把事情搞砸 在我的代码中,我正在创建一个std::unique_ptr,将其存储在向量上,以供以后在另一个上下文中使用,并继续使用指针: #include <iostream> #include <string> #include <memory> #include <vector> class MyClass { public: void doWhateve

我开始玩弄
std::unique_ptr
,我只是不想把事情搞砸

在我的代码中,我正在创建一个
std::unique_ptr
,将其存储在
向量上,以供以后在另一个上下文中使用,并继续使用指针:

#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();
    }
#包括
#包括
#包括
#包括
类MyClass{
公众:
无效doWhatever()
{
std::cout doWhatever();//这有效吗?
}
};
int main()
{
其他类别cl;
cl.myFunction();
}
代码可以编译,但我在执行时遇到了分段错误

我认为将指针移动到向量后对
p
的调用是无效的。。。。如果是这样,这里的解决方案是什么?移动到共享的ptr

OBS:使用指针后,我无法移动到向量。在实际应用中,这将在多线程环境中运行,其中一个线程使用矢量数据,另一个继续使用原始指针
p


感谢您的帮助。

简而言之,不,在移动任何对象后,使用任何对象都是无效的。编辑:除非您调用的函数没有任何先决条件(谢谢Benjamin Lindley)

这是因为当您
std::move
a
unique\u ptr
时,您正在将该内存的所有权转移给另一个
unique\u ptr
。(真正发生的是,
std::move
将您的
unique\u ptr
标记为一个r值引用,然后另一个
unique\u ptr
的构造函数看到了这一点并愉快地执行指针窃取)。您已经移动到的
unique\u ptr
现在可以执行它想要的任何操作,包括删除内存和使您拥有的任何其他引用无效


您可以将指针解引用到原始指针中(通过
unique\u ptr::get()
)来访问它指向的对象,然后将唯一指针移动到向量中。然而,
独特的
的整个理念是唯一所有权;您的原始指针可能随时失效。

简而言之,不,在移动任何对象后,使用该对象是无效的。编辑:除非您调用的函数没有任何先决条件(谢谢Benjamin Lindley)

这是因为当您
std::move
a
unique\u ptr
时,您正在将该内存的所有权转移给另一个
unique\u ptr
。(真正发生的是,
std::move
将您的
unique\u ptr
标记为一个r值引用,然后另一个
unique\u ptr
的构造函数看到了这一点并愉快地执行指针窃取)。您已经移动到的
unique\u ptr
现在可以执行它想要的任何操作,包括删除内存和使您拥有的任何其他引用无效


您可以将指针解引用到原始指针中(通过
unique\u ptr::get()
)来访问它指向的对象,然后将唯一指针移动到向量中。然而,
独特的
的整个理念是唯一所有权;您的原始指针随时都可能变得无效。

唯一指针的名称说明了一切。它是完全唯一的,因此当它超出范围时可以安全地删除

在指针上使用
std::move
时,它将其强制转换为右值引用,然后调用move构造函数,这意味着它是移动的,而不是复制的。就像你把盘子从洗碗机移到橱柜里,它就不在洗碗机里了。在代码中,这意味着从中移动的
unique_ptr
被设置为
nullptr

备选方案:

  • 使用参考计数
    共享\u ptr
    。这将允许您拥有多个实例,在删除最后一个实例后,将调用析构函数。使用该方法的另一个好处是,如果向量不应该阻止对象被破坏,它可以存储
    弱ptr
    s
  • 缓存原始指针,然后使用
    unique\u ptr
    上的
    std::move
    将其移动到
    向量中。这可能是不安全的,因为如果在向量被销毁后尝试使用该指针,它是未定义的行为,因为它将是一个悬空引用
    
    唯一指针的名称说明了一切。它是完全唯一的,因此当它超出范围时可以安全地删除

    在指针上使用
    std::move
    时,它将其强制转换为右值引用,然后调用move构造函数,这意味着它是移动的,而不是复制的。就像你把盘子从洗碗机移到橱柜里,它就不在洗碗机里了。在代码中,这意味着从中移动的
    unique_ptr
    被设置为
    nullptr

    备选方案:

  • 使用参考计数
    共享\u ptr
    。这将允许您拥有多个实例,在删除最后一个实例后,将调用析构函数。使用该方法的另一个好处是,如果向量不应该阻止对象被破坏,它可以存储
    弱ptr
    s
  • 缓存原始指针,然后使用
    unique\u ptr
    上的
    std::move
    将其移动到
    向量中。这可能是不安全的,因为如果在向量被销毁后尝试使用该指针,它是未定义的行为,因为它将是一个悬空引用
    
    执行
    std::move(p)
    后,您将不能再使用
    p
    @天顶
    p
    本身可以(重新)使用,
    *p
    在执行
    std::move(p)
    之后,您不能再使用
    p
    @天顶
    p
    本身可以(重新)使用,
    *p
    您可以使用已从中移动的对象。只要您执行的操作没有任何先决条件。一旦你验证了前提条件,你就可以正常使用这个对象了。@BenjaminLindley:谢谢你