复制ctor和赋值运算符中的任何陷阱都有略微不同的语义?

Ale*_*ter 4 c++ copy-constructor assignment-operator semantics

请查看下面的代码并告诉我它是否会在将来导致问题,如果是,那么如何避免它们.

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!    
   }
   ...
};
Run Code Online (Sandbox Code Playgroud)

简而言之,我希望复制构造函数能够创建对象的精确副本,包括其(数据库)ID字段.另一方面,当我分配时,我只想复制数据字段.但我有一些担忧,因为通常复制ctor和operator =具有相同的语义.

id字段仅由Note及其朋友使用.对于所有其他客户端,赋值运算符确实创建了精确副本.用例:当我想编辑一个笔记时,我使用copy ctor创建一个副本,编辑它,然后在管理Notes的Notebook类上调用save:

 Note n(notebook.getNote(id));
 n = editNote(n); // pass by const ref (for the case edit is canceled)
 notebook.saveNote(n);
Run Code Online (Sandbox Code Playgroud)

另一方面,当我想要创建一个与现有音符具有相同内容的全新音符时,我可以这样做:

 Note n; 
 n = notebook.getNote(id); 
 n.setText("This is a copy");
 notebook.addNote(n);
Run Code Online (Sandbox Code Playgroud)

这种方法有道理吗?如果没有,请指出可能的负面后果是什么!非常感谢!

aem*_*aem 9

如果您想要的语义与赋值运算符的预期值不匹配,则不要使用它.相反,通过声明一个私有来禁用它,operator=并定义一个具有名称的函数,该函数可以清楚地显示正在发生的事情,例如copyDataFields.

  • @Alex:是的.这意味着一旦你有一个完全初始化的`Note`,它就无法分配.如果它想要数据,它将使用`copyDataFields`方法.它仍然可以构造成与另一个音符匹配:`Note othernote(firstNote);` (3认同)