|
Behavior of operator=
In Integer.h and Byte.h,
you saw that operator= can be only a member function. It is intimately
connected to the object on the left side of the ‘=’. If it
was possible to define operator= globally, then you might attempt to
redefine the built-in ‘=’ sign:
int operator=(int, MyType); // Global = not allowed!
The compiler skirts this whole issue by
forcing you to make operator= a member function.
When you create an operator=, you
must copy all of the necessary information from the right-hand object into the
current object (that is, the object that operator= is being called for)
to perform whatever you consider “assignment” for your class. For
simple objects, this is obvious:
//: C12:SimpleAssignment.cpp
// Simple operator=()
#include <iostream>
using namespace std;
class Value {
int a, b;
float c;
public:
Value(int aa = 0, int bb = 0, float cc = 0.0)
: a(aa), b(bb), c(cc) {}
Value& operator=(const Value& rv) {
a = rv.a;
b = rv.b;
c = rv.c;
return *this;
}
friend ostream&
operator<<(ostream& os, const Value& rv) {
return os << "a = " << rv.a << ", b = "
<< rv.b << ", c = " << rv.c;
}
};
int main() {
Value a, b(1, 2, 3.3);
cout << "a: " << a << endl;
cout << "b: " << b << endl;
a = b;
cout << "a after assignment: " << a << endl;
} ///:~
Here, the object on the left side of the
= copies all the elements of the object on the right, then returns a
reference to itself, which allows a more complex expression to be
created.
This example includes a common mistake.
When you’re assigning two objects of the same type, you should always
check first for self-assignment:
is the object being assigned to itself? In some cases, such as this one,
it’s harmless if you perform the assignment operations anyway, but if
changes are made to the implementation of the class, it can make a difference,
and if you don’t do it as a matter of habit, you may forget and cause
hard-to-find bugs.
|
|