I recently read (and unfortunately forgot where), that the best way to write operator= is like this:
foo &operator=(foo other)
{
swap(*this, other);
I generally prefer the second one from readability and 'least surprise' point of view, however I do acknowledge that the first one can be more efficient when the parameter is a temporary.
The first one really can lead to no copies, not just the single copy and it's conceivable that this may be a genuine concern in extreme situations.
E.g. Take this test program. gcc -O3 -S
(gcc version 4.4.2 20091222 (Red Hat 4.4.2-20) (GCC)) generates one call to B's copy constructor but no calls to A's copy constructor for the function f
(the assignment operator is inlined for both A
and B
). A
and B
can both be taken to be very basic string classes. Allocation and copying for data
would occur in the constructors and deallocation in the destructor.
#include
class A
{
public:
explicit A(const char*);
A& operator=(A val) { swap(val); return *this; }
void swap(A& other) { std::swap(data, other.data); }
A(const A&);
~A();
private:
const char* data;
};
class B
{
public:
explicit B(const char*);
B& operator=(const B& val) { B tmp(val); swap(tmp); return *this; }
void swap(B& other) { std::swap(data, other.data); }
B(const B&);
~B();
private:
const char* data;
};
void f(A& a, B& b)
{
a = A("Hello");
b = B("World");
}