【问题标题】:Smart Pointer operator=智能指针运算符=
【发布时间】:2014-06-14 10:38:35
【问题描述】:

我见过一些智能指针以两种方式实现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!

【问题讨论】:

  • 智能指针有几种风格。例如。 unique_ptrweak_pointershared_ptr。你指的是哪一个?
  • 第二个类似于auto_ptr,已被弃用。并且不要在没有充分理由的情况下重新实施它们。 (你的处理不了p1 = p1
  • @EdHeal 我对智能指针的了解非常有限,现在正在谷歌搜索和“stackoverflowing”以了解它们是如何实现的。将查找您提到的类型:)
  • @BryanChen 所以我猜 B) 是不可能的 :)
  • 如果你这样做 p1 = p1 两个版本都会做错事。

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


【解决方案1】:

简介

如果你希望你的智能指针是可复制的,声明 (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

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

【讨论】:

  • 我相信这一点,以及对 unique_ptr、shared_ptr 和 weak_ptr 存在的了解,是 OP 想要做的事情的正确答案。他想做的任何事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-29
  • 1970-01-01
  • 2016-10-09
  • 1970-01-01
  • 2021-11-28
  • 2020-07-10
相关资源
最近更新 更多