为什么使用 class 的引用或唯一指针成员是一件坏事?

Why is using a reference or unique pointer member of a class a bad thing?

Herb Sutter 和 Andrei Alexandrescu 在书中 "C++ Coding Standards. 101 Rules, Guidelines, and Best Practices" 的规则 52 中,最后的引用是:

"In rare cases, classes that have members of strange types (e.g., references, std::auto_ptrs) are an exception because they have peculiar copy semantics. In a class holding a reference or an auto_ptr, you likely need to write the copy constructor and the assignment operator, but the default destructor already does the right thing. (Note that using a reference or auto_ptr member is almost always wrong.)"

很明显为什么使用引用作为成员不是一个好主意(这个问题的答案在这个post:Should I prefer pointers or references in member data?

  1. 关于现代 C++,这是否也意味着使用 unique_ptr 作为 class 成员通常是一件坏事?或者这只是 auto_ptr 的问题并且可能缺少移动语义?
  2. shared_ptr 应该用于多态行为吗?

提前致谢!

  1. With regard to a modern C++, does it also mean that using unique_ptr as a class member is usually a bad thing?

这并不意味着,使用唯一指针并不是一件坏事。

Or was it a problem only of auto_ptr and missing move semantics maybe?

主要问题是复制 auto_ptr 会转移指向资源的所有权。这就是作者用 "peculiar copy semantics".

所指的

鉴于 const auto_ptr 不能被复制,它不像 non-const 那样危险。它有小众用途,但 non-copyable 类型的用途非常有限 pre-C++11.

唯一指针没有特殊的复制语义。事实上,唯一指针根本不可复制。在类型可以移动的 C++11 中,这不是什么大问题。独特的指针涵盖了 auto_ptr 可用的所有用例,以及 auto_ptr 不可靠的其他用例。

  1. Should shared_ptr be used for a polymorphic behavior then?

可以使用共享指针,但不是必须的。

P.S。 auto_ptr 在 C++11 中被弃用,并在 C++17 中完全从标准库中删除。

使用 unique_ptr 成员并不是一个坏习惯,因为它所属的 class 是分配对象的所有者。但是,它会使包含它的 class 的处理方式变得复杂,因为它会阻止 class 被复制。因此,如果 class 包含任何其他 non-trivial 成员,那么您将必须为 class.

编写移动构造函数、移动赋值运算符和析构函数

相反,我认为使用 shared_ptr 作为 class 成员是一种不好的做法,因为它并不暗示任何类型的所有权并导致 non-deterministic 对象 life-time 在您的代码中,因为您不知道 shared_ptr 持有的对象的最后一个实例何时被释放。