赋值运算操作符
一般情况下,class会有默认缺省的赋值运算操作符,当我们需要自己写一个赋值运算操作符,应该如何去写呢?
举例说明:
template<class T> // 名字和指针相关联的类的模板 class NamedPtr { public: NamedPtr(const string& initName, T *initPtr); NamedPtr& operator=(const NamedPtr& rhs); private: string name; T *ptr; };
我们需要完成operator=定义,代码应该这样写:
template<class T> NamedPtr<T>& NamedPtr<T>::operator=(const NamedPtr<T>& rhs) { if (this == &rhs) return *this; // assign to all data members name = rhs.name; // 给name 赋值 *ptr = *rhs.ptr; // 对于ptr,赋的值是指针所指的值, 不是指针本身 return *this; }
这只是一个单纯的类中赋值运算符的定义,如果有派生类就更有意思了,如下例子:
class Base { public: Base(int initialValue = 0): x(initialValue) {} private: int x; }; class Derived: public Base { public: Derived(int initialValue): Base(initialValue), y(initialValue) {} Derived& operator=(const Derived& rhs); private: int y; };
逻辑上来说,其赋值运算符应该这样写:
// erroneous assignment operator Derived& Derived::operator=(const Derived& rhs) { if (this == &rhs) return *this; y = rhs.y; // 给Derived 仅有的数据成员赋值 return *this; }
但是这样是错误的,测试下面一段代码你就会看到,Derived 对象的Base 部分的数据成员x 在赋值运算符中未受影响,赋值操作失败。
void assignmentTester() { Derived d1(0); // d1.x = 0, d1.y = 0 Derived d2(1); // d2.x = 1, d2.y = 1 d1 = d2; // d1.x = 0, d1.y = 1! }正确的写法应该是下面的代码,
Derived& Derived::operator=(const Derived& rhs) { if (this == &rhs) return *this; static_cast<Base&>(*this) = rhs; // 对*this 的Base 部分 // 调用operator= y = rhs.y; return *this; }