[英]Is it necessary to block the assignment operator and the copy constructor when using smart pointers?
I've seen in several places the advice to either define your own assignment operator/copy constructor, or to block the default ones by declaring them private. 我在很多地方都看到过建议,要么定义自己的赋值运算符/副本构造函数,要么通过将默认值声明为私有来阻止默认值。
However, the only danger I've been able to find was the problem of creating copies of pointers that could be dangling pointers later. 但是,我唯一发现的危险是创建指针副本的问题,该副本以后可能会悬空指针。
In modern C++ pointers are rare, and most classes just use smart pointers (eg from boost or from the std library in C++11). 在现代C ++指针中很少见,大多数类仅使用智能指针(例如,来自boost或来自C ++ 11中的std库)。 Is it still necessary to declare the assignment operator and the copy constructor for classes that have no raw pointers? 对于没有原始指针的类,仍然需要声明赋值运算符和复制构造函数吗?
And mainly: What are the dangers of not doing that? 主要是:不这样做的危险是什么? What kind of unexpected behavior can occur? 会发生什么样的意外行为?
Not it's not necessary to hide those operators. 不必隐藏那些运算符。 std::unique_ptr
already is noncopyable(you can only move it). std::unique_ptr
已经是不可复制(你只能移动)。 And other kinds - std::shared_ptr
will increment internal ref count, std::weak_ptr
will do nothing since it has lock
method. 其他类型std::shared_ptr
会增加内部引用计数, std::weak_ptr
不会执行任何操作,因为它具有lock
方法。 You can read more here (Boost libs) 您可以在这里阅读更多内容(增强库)
This is explained in the question What is The Rule of Three? 在“ 什么是三法则 ”问题中对此进行了解释。
Also there is a very good explanation on the following website: 在以下网站上也有很好的解释:
Can I trust the Compiler-Generated Copy Constructor and Assignment Operator? 我可以信任编译器生成的副本构造函数和赋值运算符吗?
Compiler-generated code is your best friend, provided that you adhere to good style OO practices and know the rules. 编译器生成的代码是您最好的朋友,只要您遵守良好的OO风格惯例并了解规则。 As explained in part I, the compiler- generated copy constructor and assignment operator perform member-wise copying of user-declared data members. 如第I部分所述,编译器生成的复制构造函数和赋值运算符对用户声明的数据成员执行逐成员复制。 By replacing low-level datatypes -- raw pointers and char arrays for instance -- with their high-level Standard Library counterparts std::tr1::shared_ptr and std::string, not only are you eliminating the onerous bugs associated with manual resource management, you're also guaranteeing that the compiler-generated copy constructor and assignment operator will do the right thing. 通过将低级数据类型(例如,原始指针和char数组)替换为其对应的高级标准库std :: tr1 :: shared_ptr和std :: string,不仅可以消除与手动资源相关的繁琐错误在管理方面,您还保证了编译器生成的副本构造函数和赋值运算符将做正确的事情。
The danger with not defining your own assignment operator/copy/move constructor is the possibility of unexpected behavior. 不定义自己的赋值运算符/复制/移动构造函数的危险是可能发生意外行为。 These operations are very easily invoked without you being aware of that, causing the unexpected behavior. 这些操作很容易被调用,而无需您意识到,从而导致意外的行为。 Declaring them as private will result in compilation error on such occasions. 在这种情况下,将它们声明为私有将导致编译错误。
Also note that not everywhere smart pointers are used. 另请注意,并非在所有地方都使用智能指针。 There are more restricted environments (such as kernel, embedded etc.) that generally won't have STL or boost. 还有更多受限制的环境(例如内核,嵌入式等),这些环境通常没有STL或boost。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.