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

Unable to understand overloading of assignment operator

本文关键字:重载 赋值运算符      更新时间:2023-10-16

为了更好地理解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;
}

它工作正常,但当我删除重载赋值运算符的"返回类型"answers"参数"中的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"answers"T"的操作数类型有问题,为什么它上面的行(a = b;)完全可以?它们也是操作数类型"T"answers"T"


我在这里找到了一个相关的问题,但没有有用的细节:
为什么必须在运算符重载中提供关键字const
那里的一个人说,如果我们在运算符=中不使用const,我们只能将其用于non-const对象。但在我的情况下,双方也都不意外。那为什么会出错呢?尤其是当它上面的行(操作数类型相同)编译得很好时?


使用的编译器:MinGW

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

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

为了获得额外的乐趣,请尝试将您的b定义如下:

const T b(4);

此函数

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

返回类型为CCD_ 11的临时对象。这个临时对象可以与常量引用绑定。

这很重要!这就是OP困惑的原因
C++中不允许对临时对象进行非常数引用!!在a = PlusTen(b);的情况下,由于PlusTen(b)是一个临时值,函数operator=无法将参数obj绑定到PlusTen(b)值,因为obj是非常量,而PlusTen(b)只能是常量。

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

T& operator= (T& obj)
              ^^^^^^

不是一个常量引用。

返回类型中的限定符const在上下文中与运算符在程序中的使用方式无关。