在C ++中正确使用赋值运算符重载函数?

时间:2018-08-21 00:44:55

标签: c++

在下面的示例代码中,无论它是POD,class A都有一个复制构造函数,并且赋值运算符也已重载。 foobar是类型A的实体。取决于foobar的构造方式,当我在主代码中使用赋值运算符时,编译器会在某些情况下给出错误消息。错误消息在下面的代码片段中被注释。

我知道问题与隐式使用赋值运算符有关。但是,为什么foo1=bar1;没问题,而foo2=bar2;没问题?

编辑:从注释中可以清楚地看出,编译器将A foo();解释为函数声明而不是ctor。这解释了为什么我的代码中出现第一条和第二条错误消息。但是,在行A foo4 = A(2,3);上出现错误消息的原因有所不同。它与复制构造函数的设计有关,并且对象必须为const

(请参阅: Why C++ copy constructor must use const object?

我更正了复制构造函数,如下所示: A(const A &a) {x =a.x; y=a.y;}

编辑2:之后 toby-speight的注释,我通过在c ++ 17上使用gcc编译器,重新编译了相同的代码(具有没有'const'对象即A(A &a) {x =a.x; y=a.y;}的复制构造函数)。 A foo4 = A(2,3);行的错误消失了。这表明在gcc中实现了保证的复制省略(至少在我一直使用的版本gcc 7.3.1中)。

#include <iostream>

class A{
 public:
    int x;
    int y;

    A(): x(0),y(0) {  }
    A(int xval, int yval): x(xval),y(yval) {  }

    //Copy constructor.
    A(A &a) {x =a.x; y=a.y; }

    //Assgnment operator overloading
    A& operator=(A &a){
        if (this !=&a){
            x=a.x;
            y=a.y;
        }
        return *this;
    }
};

int main(){

  A foo1(2,3);
  A bar1;
  foo1 = bar1;

  A foo2();
  A bar2();
  foo2 = bar2;  // error: cannot convert ‘A()’ to ‘A()’ in assignment

  A foo3(2,3);
  A bar3();
  foo3 = bar3;  // error: no match for ‘operator=’ (operand types are ‘A’ and ‘A()’)

  A foo4 = A(2,3); //<--- // error: cannot bind non-const lvalue reference of type ‘A&’ to an rvalue of type ‘A’
  A bar4;  //ok.          // note:   initializing argument 1 of ‘A::A(A&)’
  foo4 = bar4;

   return 0;
}

0 个答案:

没有答案