Any errors in copying ctor and assignment operator have slightly different semantics?

Please read the following code and tell me if it will cause problems in the future, and if so, how to avoid them.

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! } ... }; 

In short, I want the copy constructor to create an exact copy of the object, including its ID (database) field. On the other hand, when I assign, I just want to copy the data fields. But I have some problems, since usually a copy of ctor and operator = have the same semantics.

The id field is used only by Note and his friends. For all other clients, the assignment operator creates an exact copy. Use case. When I want to edit a note, I create a copy using a copy of ctor, edit it, and then call save in the Notebook class that controls Notes:

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

On the other hand, I want to create a completely new note with the same contents as the existing note, I can do this:

  Note n; n = notebook.getNote(id); n.setText("This is a copy"); notebook.addNote(n); 

Is this approach believable? If not, indicate what are the possible negative consequences! Many thanks!

+4
source share
3 answers

If you need semantics that are not as expected from the assignment operator, do not use it. Instead, disable it by declaring a private operator= and define a function with a name that clearly shows what is happening, such as copyDataFields .

+9
source

Although this might work for your specific case, I would not recommend it at all.

Libraries such as the STL expect the copy constructor and assignment operator to work as they should. If you break the C ++ semantics, you may find that the STL containers of your objects will not work correctly. The STL will call both your copy constructor and your assignment operator under different circumstances depending on the container.

It is very easy to get completely confused when your code does not do what you think.

+4
source

Technically, this will work and technically, but I wouldnโ€™t. I see the following problems:

  • You are changing the "natural" semantics of the assignment operator, as the C ++ population knows.

  • Two operations with two operations, the construction and purpose of a copy, are inconsistent due to different semantics.

  • The solution is error prone because it is easy to accidentally invoke the copy constructor, even if it looks like an assignment. If the programmer writes your second use case as follows:

     Note n = notebook.getNote(id); 

    Then the copy constructor is called, not the assignment , so you get n as a different object than expected.

Why not make your intentions simply clear and explicit:

 Note& Notebook::editNote(int id); Note Notebook::createNote(int id); 
+1
source

Source: https://habr.com/ru/post/1300462/


All Articles