【发布时间】:2010-09-17 21:52:32
【问题描述】:
请列出复制构造函数和赋值运算符在 C++ 中需要执行的任务,以保持异常安全、避免内存泄漏等。
【问题讨论】:
标签: c++ copy-constructor assignment-operator
请列出复制构造函数和赋值运算符在 C++ 中需要执行的任务,以保持异常安全、避免内存泄漏等。
【问题讨论】:
标签: c++ copy-constructor assignment-operator
首先确定您确实需要支持副本。大多数情况下并非如此,因此禁用两者是可行的方法。
有时,您仍需要从多态层次结构中为类提供重复项,在这种情况下:禁用赋值运算符,编写(受保护?)复制构造函数,并提供虚拟 clone() 函数。
否则,如果您正在编写一个值类,您将回到 Coplien 的正交规范形式的领域。如果您有一个无法简单复制的成员,则需要提供一个复制构造函数、一个析构函数、一个赋值运算符和一个默认构造函数。这条规则可以细化,例如:The Law of The Big Two
我还建议您查看C++ FAQ regarding assignment operators、copy-and-swap idiom 和GOTW。
【讨论】:
编译器生成的版本在大多数情况下都可以工作。
当你的对象包含一个 RAW 指针(一个没有 RAW 指针的参数)时,你需要更加仔细地思考这个问题。所以你有一个 RAW 指针,第二个问题是你是否拥有指针(它是否被你删除)?如果是这样,那么您将需要应用 4 的规则。
拥有超过 1 个 RAW 指针变得越来越难以正确执行(复杂性的增加也不是线性的 [但这是观察性的,我没有真实的统计数据来支持该陈述])。因此,如果您有超过 1 个 RAW 指针,请考虑将每个指针包装在自己的类中(某种形式的智能指针)。
4 规则:如果一个对象是 RAW 指针的所有者,那么您需要定义以下 4 个成员以确保您正确处理内存管理:
如何定义这些取决于具体情况。但需要注意的事项:
【讨论】:
尝试阅读这篇文章。
http://www.icu-project.org/docs/papers/cpp_report/the_anatomy_of_the_assignment_operator.html
是一个很好的分析赋值运算符
【讨论】:
我不知道这里安全异常,但我走这条路。让我们想象它是一个模板化的数组包装器。希望对你有帮助:)
Array(const Array& rhs)
{
mData = NULL;
mSize = rhs.size();
*this = rhs;
}
Array& operator=(const Array& rhs)
{
if(this == &rhs)
{
return *this;
}
int len = rhs.size();
delete[] mData;
mData = new T[len];
for(int i = 0; i < len; ++i)
{
mData[i] = rhs[i];
}
mSize = len;
return *this;
}
【讨论】: