Overloading assignment
A common source of confusion with new C++
programmers is assignment. This is no doubt because the = sign is such a
fundamental operation in programming, right down to copying a register at the
machine level. In addition, the
copy-constructor
(described in Chapter 11) is also sometimes invoked when the
= sign is
used:
MyType b;
MyType a = b;
a = b;
In the second line, the object a
is being defined. A new object is being created where one didn’t
exist before. Because you know by now how defensive the C++ compiler is about
object initialization, you know that a constructor must always be called at the
point where an object is defined. But which constructor? a is being
created from an existing MyType object (b, on the right side of
the equal sign), so there’s only one choice: the copy-constructor. Even
though an equal sign is involved, the copy-constructor is
called.
In the third line, things are different.
On the left side of the equal sign, there’s a previously initialized
object. Clearly, you don’t call a constructor for an object that’s
already been created. In this case MyType::operator= is called for
a, taking as an argument whatever appears on the right-hand side. (You
can have multiple operator= functions to take different types of
right-hand arguments.)
This behavior is not restricted to the
copy-constructor. Any time you’re initializing an
object using an = instead of the ordinary function-call form of the
constructor, the compiler will look for a constructor that accepts whatever is
on the right-hand side:
//: C12:CopyingVsInitialization.cpp
class Fi {
public:
Fi() {}
};
class Fee {
public:
Fee(int) {}
Fee(const Fi&) {}
};
int main() {
Fee fee = 1; // Fee(int)
Fi fi;
Fee fum = fi; // Fee(Fi)
} ///:~
When dealing with the = sign,
it’s important to keep this distinction in mind: If the object
hasn’t been created yet, initialization is required; otherwise the
assignment operator= is used.
It’s even better to avoid writing
code that uses the = for initialization; instead, always use the explicit
constructor form. The two constructions with the equal sign then
become:
Fee fee(1);
Fee fum(fi);
This way, you’ll avoid confusing
your
readers.