Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializer lists: copy constructors and assignment operators = redundancy?

It seems that initalizer lists are a good idea for your class constructors and, I'm assuming, for the copy constructor as well. For the assignment operator one has to assign each member in the body of the function. Consider the following simple block:

class Foo {
private: 
  int a,b;
public:
  Foo(int c, int d)  : a(c), b(d) {}
  Foo(const Foo & X) : a(X.a), b(X.b) {}
  Foo& operator=(const Foo& X) {
    if (this == &X) return *this;
    a = X.a;
    b = X.b;
    return *this;
  }
};

If a class has a moderate amount of data members, there are three places where one can mess up the the different assignments/initialization. By that I mean, what if the copy constructor looked like:

  Foo(const Foo & X) : a(X.a), b(X.a) {}

or a line was missing from the operator=. Since the assignment operator and the copy constructor often have the same effect (in that we copy members from one Foo to another) can I "reuse" the code from the copy constructor or the assignment operator or vice versa?

like image 541
Hooked Avatar asked Mar 03 '26 09:03

Hooked


2 Answers

Your goal should be to not write copy constructors/assignment operators at all. Your goal should be to let the compiler do it. Standard library containers are all copyable, so use them where reasonable.

If there are members that cannot be copied correctly, then use smart pointers or other RAII objects. Those objects are the ones that should need special copy constructors/assignments. And they only need them for their one member.

Everything else should not use them.

like image 81
Nicol Bolas Avatar answered Mar 04 '26 23:03

Nicol Bolas


Since the assignment operator and the copy constructor often have the same effect.

Not at all, one does initialization while the other does assignment. They are different in the initial state of the object, and their tasks are separate (though similar). The canonical assignment operator is usually done as:

Foo& operator=(Foo right) {
    right.swap( *this );
    return *this;
}
like image 39
K-ballo Avatar answered Mar 04 '26 23:03

K-ballo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!