提问人:John Smith 提问时间:10/18/2008 最后编辑:Daniel DaranasJohn Smith 更新时间:7/16/2015 访问量:4913
在 C++ 中编写复制构造函数和赋值运算符的清单
Checklist for writing copy constructor and assignment operator in C++
答:
我不知道这里的例外情况,但我走这条路。让我们想象一下,它是一个模板化的数组包装器。希望对:)有所帮助
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;
}
评论
首先,确保你确实需要支持复制。大多数时候情况并非如此,因此禁用两者是要走的路。
有时,您仍然需要在多态层次结构中的类上提供复制,在这种情况下:禁用赋值运算符,编写(受保护?)复制构造函数,并提供虚拟 clone() 函数。
否则,如果你正在编写一个值类,你就回到了 Coplien 的正交规范形式。如果有一个无法简单复制的成员,则需要提供复制构造函数、析构函数、赋值运算符和默认构造函数。这条规则可以细化,例如:两大定律
我还建议查看有关赋值运算符的C++常见问题解答,以及复制和交换习惯用语以及GOTW。
评论
编译器生成的版本在大多数情况下都可以工作。
当对象包含 RAW 指针(没有 RAW 指针的参数)时,您需要更努力地思考这个问题。所以你有一个RAW指针,第二个问题是你是否拥有这个指针(它是否被你删除了)?如果是这样,那么您将需要应用 4 规则。
拥有超过 1 个 RAW 指针变得越来越难以正确完成(复杂性的增加也不是线性的 [但这是观察性的,我没有真正的统计数据来支持这一说法])。因此,如果您有 1 个以上的 RAW 指针,请考虑将每个指针包装在自己的类中(某种形式的智能指针)。
规则 4:如果对象是 RAW 指针的所有者,则需要定义以下 4 个成员,以确保正确处理内存管理:
- 构造 函数
- Copy 构造函数
- 赋值运算符
- 破坏者
如何定义这些将取决于具体情况。但需要注意的事项:
- 默认构造:将指针设置为 NULL
- 复制构造函数:使用 Copy and Swap 概念提供给“强异常保证”
- 赋值运算符:检查对自身的赋值
- 析构函数:防止异常从析构函数传播出来。
评论
试着读这个。
http://www.icu-project.org/docs/papers/cpp_report/the_anatomy_of_the_assignment_operator.html
是很好的分析赋值算子
评论