智能指针运算符=

时间:2014-06-14 10:38:36

标签: c++ operator-overloading smart-pointers

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

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<MyClass> p1(new MyClass());
SmartPointer<MyClass> p2(new MyClass());
p1 = p2;
p2->someMethod(); // <----- BOOM!

1 个答案:

答案 0 :(得分:6)

简介

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


危险,危险!

声明(B)是错误的,因为它不遵循语言内的任何语义;很遗憾右侧在操作之外生活,当它仅仅作为作为赋值时被修改。

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

rvalue references是在 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<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

标准中有哪些内容?

C ++ 11 库中,我们std::unique_ptrstd::shared_ptrstd::weak_ptr

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