Chapter 10. Copy Constructors and Assignment Operators

Suppose you have a class MyClass that looks something like this:

class MyClass {
 public:
  // Constructors

  // Copy-constructor
  MyClass(const MyClass& that)
  : int_data_(that.int_data_),
    dbl_data_(that.dbl_data_),
    str_data_(that.str_data_) {
  }

  // Assignment operator
  MyClass& operator = (const MyClass& that) {
    if(this != &that) {
      int_data_ = that.int_data_;
      dbl_data_ = that.dbl_data_;
      str_data_ = that.str_data_;
    }
    return *this;
 }

 // Some other methods here
private:
  Int int_data_;
  Double dbl_data_;
  string str_data_;
  // Each time you add a new data member in here,
  // do not forget to add corresponding code to the
  // copy-constructor and assignment operators!
};

What is wrong with this class? It is summarized in the comment at the end of the private section. You’ll remember from the Preface that if we find ourselves saying this, we open up the code to errors and should consider alternatives. And indeed, if you don’t write a copy-constructor or assignment operator, C++ will write a “default version” for you. The default version of the copy-constructor of your class will call copy-constructors for all data members (or simply copy the built-in types), and the default version of an assignment operator will call assignment operators for each data member or simply copy the built-in types.

Because of that, the copy constructor and the assignment operator in the previous example are totally unnecessary. Even worse, they are a potential source of errors because they make your code fragile, i.e., it might break if someone tries to modify it. Therefore, in this case it is a good idea to avoid writing copy-constructors and assignment operators altogether.

In general, regarding these two functions, you have the following choices:

  • Rely on default versions created for you automatically by a compiler.

  • Prohibit copies of any kind by declaring the copy constructor and assignment operator as private, and do not provide an implementation.

  • Write your own versions.

For the reasons just discussed, avoid the last option as much as possible. If you find yourself writing copy constructors and assignment operators for some class, ask yourself whether it is really necessary. Maybe you can avoid doing it and switch to the first option (using default versions created by compiler) or use some other methods, such as smart pointers. If you are not sure, use the second option—if there is no copying of any kind, there is no way to make errors. However, be aware that some types of usage of your class (e.g., in vector<MyClass>) require a copy constructor and an assignment operator, so prohibiting copies of any kind should be used sparingly, with the understanding that it limits your options when using your class.

Rules for this chapter to avoid errors in copy-constructors and assignment operators:

  • Whenever possible, avoid writing a copy-constructor or assignment operator for your classes.

  • If the default versions do not work for you, consider prohibiting the copying of instances of your class by declaring the copy-constructor and assignment operator private.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.71.115