智能指针运算符=

Ios*_*riu 6 c++ smart-pointers operator-overloading

我已经看到一些智能指针operator=以两种方式实现:

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

SmartPointer& operator=(const SmartPointer& rhs)
{
   delete m_ptr;
   m_ptr = rhs.m_ptr;
   return *this;
}
Run Code Online (Sandbox Code Playgroud)

B)在赋值后使右手侧指针无效的一个:

SmartPointer& operator=(SmartPointer& rhs)
{
   delete m_ptr;
   m_ptr = rhs.m_ptr;
   rhs.m_ptr = nullptr
   return *this;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是更多建议使用哪一个?我对B)的问题是,如果有人想进一步操作第二个智能指针(参见下面的代码),程序将崩溃(如果没有检查空指针)或什么都不做.这似乎不太好:)

SmartPointer<MyClass> p1(new MyClass());
SmartPointer<MyClass> p2(new MyClass());
p1 = p2;
p2->someMethod(); // <----- BOOM!
Run Code Online (Sandbox Code Playgroud)

Fil*_*efp 6

介绍

如果你想让你的智能指针可以复制,声明(A)就可以了; 只记得你不能解除分配存储两次,这意味着必须有某种方式来表明复制的智能指针实际上并不拥有它所引用的资源.


危险,危险!

然而,声明(B)是错误的,因为它不遵循语言内的任何语义; 奇怪的是,在操作之外生活的右侧,当它仅仅作为任务的来源时会被修改.

如果您计划数据从一侧移动到另一侧,则应使用接受右值引用的重载.所述引用只能绑定到临时或者已经明确表示像一个人行事的东西(即,开发人员知道在操作之后可能具有未确定值的某些东西).

rvalue引用是在 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;
}
Run Code Online (Sandbox Code Playgroud)
SmartPointer<MyClass> p1(new MyClass());
SmartPointer<MyClass> p2(new MyClass());

p1 = p2; // ill-formed, (B) is not applicable; cannot bind lvalue to rvalue reference
p1 = std::move (p2) // legal
Run Code Online (Sandbox Code Playgroud)

标准中有什么?

C++ 11库我们std::unique_ptr,std::shared_ptrstd::weak_ptr.

查看它们的实现应该可以很好地理解智能指针的工作方式,以及语义差异如何决定所编写代码的差异.