任何陷阱在复制构造函数和分配运营者具有稍微不同的语?
-
18-09-2019 - |
题
请看以下代码告诉我,如果这将导致在未来的问题,如果是,如何避免他们。
class Note
{
int id;
std::string text;
public:
// ... some ctors here...
Note(const Note& other) : id(other.id), text(other.text) {}
void operator=(const Note& other) // returns void: no chaining wanted
{
if (&other == this) return;
text = other.text;
// NB: id stays the same!
}
...
};
总之,我想的复制的构造,以创建一个精确复制的对象,包括其中的(数据库)的ID领域。另一方面,当我给我想要的只是复制的数据字段。但是我有一些担忧,因为通常的复制构造函数和操作人员=具有相同的语义。
Id领域只被用的注意和它的朋友。对于所有其他客户,分配运营商创建一个精确复制。使用的情况下:当我需要编辑注意,我创建了一个副本,使用复制构造函数、编辑,然后呼吁保存在笔记本上级管理注:
Note n(notebook.getNote(id));
n = editNote(n); // pass by const ref (for the case edit is canceled)
notebook.saveNote(n);
当在另一方面,我想创建一个全新的地注意到同一内容作为一个现有的注意,我可以这样做:
Note n;
n = notebook.getNote(id);
n.setText("This is a copy");
notebook.addNote(n);
是这种方法合理?如果没有,请指出哪些可能产生的负面后果。非常感谢!
解决方案
如果你想不匹配什么从赋值运算符预期的语义,那么就不要使用它。取而代之的是,通过声明的私人operator=
禁用它,并确定与明确这是怎么回事,像copyDataFields
名称的功能。
其他提示
虽然这可能会为您的特定情况下的工作,我不会推荐它一般。
库如STL预期拷贝构造函数和赋值操作符的工作“像他们应该”。如果你违反了C ++语法,那么你会发现你的对象的那STL容器将无法正常工作。该STL将同时调用你的拷贝构造函数和你的赋值运算符,根据不同情况,这取决于在容器上。
这很容易,当你的代码没有你想象的那样得到完全糊涂了。
从技术上讲,它是可行的和在技术上将工作,但是我不会做这种方式。这问题我看到的是:
你改变"自然"的语义转让的运营商已知通过C++的人口。
两个双操作、复制构造和分配,是不一致的,因为不同的语义。
该方案是容易出错的,因为它很容易不小心呼叫 copy constructor 即使它看起来如分配。如果你的程序员编写第二次使用的情况下这种方式:
Note n = notebook.getNote(id);
然后再复制的构造是所谓, 不配, 所以你得
n
作为不同的对象超过预期。
为什么不让你的意图只是清楚和明确的:
Note& Notebook::editNote(int id);
Note Notebook::createNote(int id);