C++ 智能指针运算符=

C++ 智能指针运算符=,c++,operator-overloading,smart-pointers,C++,Operator Overloading,Smart Pointers,我见过一些智能指针以两种方式实现操作符=: A)将原始指针分配给另一个原始指针的指针: SmartPointer& operator=(const SmartPointer& rhs) { delete m_ptr; m_ptr = rhs.m_ptr; return *this; } B)以及在赋值后使右侧指针为空的指针: SmartPointer& operator=(SmartPointer& rhs) { delete m_ptr

我见过一些智能指针以两种方式实现
操作符=

A)将原始指针分配给另一个原始指针的指针:

SmartPointer& operator=(const SmartPointer& rhs)
{
   delete m_ptr;
   m_ptr = rhs.m_ptr;
   return *this;
}
B)以及在赋值后使右侧指针为空的指针:

SmartPointer& operator=(SmartPointer& rhs)
{
   delete m_ptr;
   m_ptr = rhs.m_ptr;
   rhs.m_ptr = nullptr
   return *this;
}
我的问题是,哪一个更适合使用?我对B)的问题是,如果想要进一步操作第二个智能指针(参见下面的代码),程序将崩溃(如果不检查空指针)或什么也不做。这似乎不太好:)

SmartPointer p1(新的MyClass());
智能指针p2(新MyClass());
p1=p2;
p2->someMethod();//介绍
如果您希望您的智能指针是可复制的,那么声明(A)就可以了;请记住,您不能两次解除分配存储,这意味着必须有某种方式来表明复制的智能指针并不真正拥有它所引用的资源


危险,危险! 然而,声明(B)是错误的,因为它不遵循语言中的任何语义;奇怪的是,在操作之外的右侧,当它仅仅作为赋值的源时,会被修改

如果计划将数据从一端移动到另一端,则应使用接受右值引用的重载。所述引用只能绑定到一个临时引用或已明确声明为类似于临时引用的对象(即,开发人员知道的对象在操作后可能具有未确定的值)

是在C++11中引入的,其实现可能如下所示

SmartPointer& operator=(SmartPointer&& rhs) // (B), move assign
{
   delete m_ptr;        // release currently held resource
   m_ptr = rhs.m_ptr;   // assign new resource
   rhs.m_ptr = nullptr; // prevent `rhs` from deleting our memory, it's no longer in charge 
   return *this;
}
SmartPointer p1(新的MyClass());
智能指针p2(新MyClass());
p1=p2;//格式错误,(B)不适用;无法将左值绑定到右值引用
p1=std::move(p2)//合法

标准是什么? 在C++11库中,我们使用和


查看它们的实现应该有助于更好地理解智能指针是如何工作的,以及语义上的差异如何决定所编写代码中的差异。

智能指针有几种风格。例如,
唯一\u ptr
弱\u指针
共享\u ptr
。你指的是哪一个?第二个类似于
auto_ptr
,不推荐使用。如果没有充分的理由,不要重新实施它们。(你的人无法处理
p1=p1
)@EdHeal我对智能指针的了解非常有限,现在正在谷歌上搜索和“stackoverflow”它们的实现方式。我会查找你提到的类型:)@BryanChen所以我想B)是不可能的:)如果你这样做
p1=p1
,两个版本都会做错误的事情。我相信这一点,加上对独特、共享和弱ptr存在的认识,是OP想要做的正确答案。他想做的任何事。
SmartPointer& operator=(SmartPointer&& rhs) // (B), move assign
{
   delete m_ptr;        // release currently held resource
   m_ptr = rhs.m_ptr;   // assign new resource
   rhs.m_ptr = nullptr; // prevent `rhs` from deleting our memory, it's no longer in charge 
   return *this;
}