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:
3.145.71.115