在 C++ 中编写复制构造函数和赋值运算符的清单
请写出 C++ 中复制构造函数和赋值运算符需要执行的任务列表,以保持异常安全、避免内存泄漏等。
Please write a list of tasks that a copy constructor and assignment operator need to do in C++ to keep exception safety, avoid memory leaks etc.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
首先确保您确实需要支持复制。 大多数时候情况并非如此,因此禁用两者是正确的方法。
有时,您仍然需要在多态层次结构中的类上提供重复项,在这种情况下:禁用赋值运算符,编写(受保护的?)复制构造函数,并提供虚拟clone()函数。
否则,如果您正在编写一个值类,那么您将回到 Coplien 正交规范形式的土地。 如果您有一个无法简单复制的成员,则需要提供一个复制构造函数、一个析构函数、一个赋值运算符和一个默认构造函数。 这个规则可以被细化,例如:The Law of the Big Two
I'还建议您查看有关赋值运算符的 C++ 常见问题解答,以及 copy-and-swap 习语 和在 GOTW。
First be sure you really need to support copy. Most of the time it is not the case, and thus disabling both is the way to go.
Sometimes, you'll still need to provide duplication on a class from a polymorphic hierarchy, in that case: disable the assignment operator, write a (protected?) copy constructor, and provide a virtual clone() function.
Otherwise, in the case you are writing a value class, you're back into the land of the Orthogonal Canonical Form of Coplien. If you have a member that can't be trivially copied, you'll need to provide a copy-constructor, a destructor, an assignment-operator and a default constructor. This rule can be refined, see for instance: The Law of The Big Two
I'd also recommend to have a look at C++ FAQ regarding assignment operators, and at the copy-and-swap idiom and at GOTW.
编译器生成的版本适用于大多数情况。
当您的对象包含 RAW 指针(不具有 RAW 指针的论点)时,您需要仔细考虑一下问题。 所以你有一个RAW指针,第二个问题是你是否拥有该指针(它是否被你删除)? 如果是这样,那么您将需要应用 4 的规则。
拥有超过 1 个 RAW 指针变得越来越难以正确执行(复杂性的增加也不是线性的 [但这是观察性的,我没有真正的统计数据来支持该声明])。 因此,如果您有超过 1 个原始指针,请考虑将每个指针包装在自己的类中(某种形式的智能指针)。
规则 4:如果一个对象是 RAW 指针的所有者,那么您需要定义以下 4 个成员,以确保正确处理内存管理:
如何定义这些成员取决于具体情况。 但需要注意的事项:
The compiler generated versions work in most situations.
You need to think a bit harder about the problem when your object contains a RAW pointer (an argument for not having RAW pointers). So you have a RAW pointer, the second question is do you own the pointer (is it being deleted by you)? If so then you will need to apply the rule of 4.
Owning more than 1 RAW pointer becomes increasingly hard to do correctly (The increase in complexity is not linear either [but that is observational and I have no real stats to back that statement up]). So if you have more than 1 RAW pointer think about wrapping each in its own class (some form of smart pointer).
Rule of 4: If an object is the owner of a RAW pointer then you need to define the following 4 members to make sure you handle the memory management correctly:
How you define these will depend on the situations. But things to watch out for:
尝试读一下这个。
http://www.icu-project.org/docs/papers/ cpp_report/the_anatomy_of_the_assignment_operator.html
是对赋值运算符非常好的分析
try to read this.
http://www.icu-project.org/docs/papers/cpp_report/the_anatomy_of_the_assignment_operator.html
is a very good analysis of Assignment operator
我不知道这里的异常安全,但我走这条路。 让我们假设它是一个模板化数组包装器。 希望能帮助到你 :)
I have no idea about exception safely here but I go this way. Let's imagine it's a templated array wrapper. Hope it helps :)