【问题标题】:Unable to understand overloading of assignment operator无法理解赋值运算符的重载
【发布时间】:2016-03-22 15:50:29
【问题描述】:

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

它工作正常,但是当我删除重载赋值运算符的“返回类型”和“参数”中的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;
}

那么这行main函数报错:

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

【问题讨论】:

    标签: c++ class operator-overloading constants


    【解决方案1】:

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

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

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

    const T b(4);
    

    【讨论】:

      【解决方案2】:

      这个函数

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

      返回T 类型的临时对象。这个临时对象可以绑定一个常量引用。

      这很重要!这就是OP感到困惑的原因!
      C++ 中不允许对临时对象的非常量引用!!这就是为什么将T 升级为const Ta = b; 中成功但在a = PlusTen(b); 中失败,因为后者中的 RHS 是暂时的。

      所以编译器发出错误是因为赋值运算符的参数

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

      不是常量引用。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-15
        • 2018-11-13
        • 2013-03-30
        • 2013-02-14
        • 2016-08-30
        • 1970-01-01
        相关资源
        最近更新 更多