赋值运算符重载(C++实现)详解
C++ 允许程序员重新定义标准运算符在与类对象一起使用时的工作方式。
正如前面所介绍的,复制构造函数的设计是为了解决包含指针的对象在通过按成员赋值的方式使用同一类的另一个对象的数据进行初始化时出现的问题。类似的问题也会出现在对象赋值中。
例如,创建一个 NumberArray 类,可以让程序如下定义该类的两个对象:
NumberArray first(3,10.5);
NumberArray second(5, 20.5);
现在,因为 C++ 允许赋值运算符(=)与类对象一起使用,所以,以下语句也是可以执行的:
first = second;
如果要将第一个对象 first 设置为与第二个对象 second 完全相同的值,此时,C++ 将再次执行按成员复制,从第二个对象复制成员到第一个对象中,这将导致两个对象中的指针指向同一内存。
由于默认的对象赋值遇到了与默认的复制构造函数相同的问题,所以有人可能会认为,程序员定义的复制构造函数也可以用来解决默认赋值所导致的问题,但事实并非如此。复制构造函数仅在创建对象并初始化对象时才起作用。特别是,复制构造函数不能在赋值中调用。
要理解初始化和赋值之间的区别,可以假设已经创建了 first 对象,然后来看以下语句:
NumberArray second = first; //复制构造函数被调用
该语句创建 second 对象,并使用 first 的值初始化它,这是一个初始化语句,它导致复制构造函数被调用来执行初始化。但是,以下语句则不一样:
second = first; //复制构造函数未被调用
该语句假定两个对象都是以前创建的,它仅仅是一个赋值语句,因此不会调用构造函数。
为了解决由对象的按成员赋值引起的问题,就需要修改赋值运算符的行为,以便在将其应用于具有指针成员的类的对象时,执行按成员赋值之外的其他操作。换句话说,就是要提供用于该类的对象的赋值运算符的不同版本。所以,这样做也可以说是要重载赋值运算符。
为给定的类重载赋值运算符的一种方式是定义一个名为 operator=
的运算符函数作为该类的成员函数。例如,要为 NumberArray 类执行此操作,则可以按如下所示编写该类的声明:
class NumberArray { private: double *aPtr; int arraySize; public: void operator = (const NumberArray & right) ;//重载运算符 NumberArray(const NumberArray &); NumberArray(int size, double value); ~NumberArray() { if (arraySize > 0) delete [ ] aPtr; } void print() const; void setValue(double value); };
现在先来看一看函数头或原型,然后再看一看运算符函数本身是如何实现的。函数头的各个主要部分可以分解如下,如图 1 所示。
发表评论