赋值运算操作符

   一般情况下,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;
}

 

 

posted @ 2013-01-09 15:32  拿枪的程序员  阅读(196)  评论(0编辑  收藏  举报