无法理解赋值运算符的重载

时间:2016-03-22 15:50:30

标签: c++ class operator-overloading const

为了更好地理解c ++中对象的工作原理,我写了这段代码:

using namespace std;

char n[] = "\n";

class T
{
  private:
    int num;

  public:
    T ()
    {
        num = 0;
        cout << n << (long)this % 0xFF << " created without param";
    }

    T (const int param)
    {
        num = param;
        cout << n << (long)this % 0xFF << " created with param = " << param;
    }

    T (const T& obj)
    {
        num = obj.num;
        cout << n << (long)this % 0xFF << " created as copy of " << (long)&obj % 0xFF;
    }

    const T& operator= (const T& obj)
    {
        if (this == &obj)
            return *this;
        num = obj.num;
        cout << n << (long)this % 0xFF << " got assigned the data of " << (long)&obj % 0xFF;
        return *this;
    }

    ~T ()
    {
        cout << n << (long)this % 0xFF << " destroyed";
    }

    int get () const {return num;}
    void set (const int param) {num = param;}
};

T PlusTen (T obj)
{
    T newObj(5);
    newObj.set( obj.get() +10 );
    return newObj;
}

int main ()
{
    T a, b(4);
    a = b;
    a = PlusTen(b);

    cout << n;
    return 0;
}

它的工作正常,但当我删除重载赋值运算符的“return-type”和“parameter”中的const限定符时,如下所示:

T& operator= (T& obj) // const removed
{
    if (this == &obj)
        return *this;
    num = obj.num;
    cout << n << (long)this % 0xFF << " got assigned the data of " << (long)&obj % 0xFF;
    return *this;
}

然后这行主函数出错:

a = PlusTen(b);

错误信息为:

no match for 'operator=' (operand types are 'T' and 'T')
    note:
    candidate is: T& T::operator=(T&)
    no known conversion for argument 1 from 'T' to 'T&'

如果'T'和'T'的操作数类型有问题,那么它上面的那条线(a = b;)怎么会完全没问题呢?它们也是操作数类型'T'和'T'!!

我在这里发现了一个相关的问题,但那里没有有用的细节:
why must you provide the keyword const in operator overloads
那里的一个人说如果我们不在operator =中使用const,我们只能将它用于non-const个对象。但就我而言,双方都是非常规的。那为什么错误?特别是当它上面的行(操作数类型相同)编译时很好?

使用的编译器:MinGW

2 个答案:

答案 0 :(得分:2)

PlusTen(b);正在创建一个临时对象。由于非const引用不能绑定到临时对象,因此无法在此处调用operator=

a = b; b中,它不是一个临时的,它是一个可修改的对象(所谓的 l-value )。非const引用成功绑定到它,并调用operator=

为了获得额外的乐趣,请尝试按以下方式定义b

const T b(4);

答案 1 :(得分:1)

此功能

position: fixed

返回T PlusTen (T obj) { T newObj(5); newObj.set( obj.get() +10 ); return newObj; } 类型的临时对象。这个临时对象可以用常量引用绑定。

  

这很重要!这就是OP困惑的原因!   C ++中不允许对const临时对象进行非const引用!这就是为什么在T中将T提升为const T但在a = b;中失败的原因,因为后者的RHS是暂时的。

因此编译器会发出错误,因为赋值运算符的参数

a = PlusTen(b);

不是常量参考。

返回类型中的限定符T& operator= (T& obj) ^^^^^^ 不管在上下文中如何在程序中使用运算符。