在下面的示例代码中,无论它是POD,class A
都有一个复制构造函数,并且赋值运算符也已重载。
foo
和bar
是类型A
的实体。取决于foo
和bar
的构造方式,当我在主代码中使用赋值运算符时,编译器会在某些情况下给出错误消息。错误消息在下面的代码片段中被注释。
我知道问题与隐式使用赋值运算符有关。但是,为什么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;
}