Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy constructor and = operator overload in C++: is a common function possible?

Since a copy constructor

MyClass(const MyClass&); 

and an = operator overload

MyClass& operator = (const MyClass&); 

have pretty much the same code, the same parameter, and only differ on the return, is it possible to have a common function for them both to use?

like image 639
MPelletier Avatar asked Nov 14 '09 15:11

MPelletier


People also ask

Can copy constructor be overloaded?

A Copy constructor is an overloaded constructor used to declare and initialize an object from another object.

Is copy constructor and constructor overloading same?

A copy constructor constructs a new object by using the content of the argument object. An overloaded assignment operator assigns the contents of an existing object to another existing object of the same class.

Why a class should have both a copy constructor and an overloaded assignment operator?

Both the copy constructors and assignment operators copies from one object to another then why do we need both? Copyconstructor means it creates a new object and copies the contents from another exist object and assignment operator copies the contents from one existing object to the already existing object.


1 Answers

Yes. There are two common options. One - which is generally discouraged - is to call the operator= from the copy constructor explicitly:

MyClass(const MyClass& other) {     operator=(other); } 

However, providing a good operator= is a challenge when it comes to dealing with the old state and issues arising from self assignment. Also, all members and bases get default initialized first even if they are to be assigned to from other. This may not even be valid for all members and bases and even where it is valid it is semantically redundant and may be practically expensive.

An increasingly popular solution is to implement operator= using the copy constructor and a swap method.

MyClass& operator=(const MyClass& other) {     MyClass tmp(other);     swap(tmp);     return *this; } 

or even:

MyClass& operator=(MyClass other) {     swap(other);     return *this; } 

A swap function is typically simple to write as it just swaps the ownership of the internals and doesn't have to clean up existing state or allocate new resources.

Advantages of the copy and swap idiom is that it is automatically self-assignment safe and - providing that the swap operation is no-throw - is also strongly exception safe.

To be strongly exception safe, a 'hand' written assignment operator typically has to allocate a copy of the new resources before de-allocating the assignee's old resources so that if an exception occurs allocating the new resources, the old state can still be returned to. All this comes for free with copy-and-swap but is typically more complex, and hence error prone, to do from scratch.

The one thing to be careful of is to make sure that the swap method is a true swap, and not the default std::swap which uses the copy constructor and assignment operator itself.

Typically a memberwise swap is used. std::swap works and is 'no-throw' guaranteed with all basic types and pointer types. Most smart pointers can also be swapped with a no-throw guarantee.

like image 101
CB Bailey Avatar answered Nov 08 '22 00:11

CB Bailey