拷贝构造函数形参用const
修饰
出问题的情况:
代码:
#include<iostream>
using namespace std;
class exam{
int x, y;
public:
exam(int a){x = a;cout<<"constructor1 called"<<endl;}
exam(int a,int b){x = a; y = b;cout<<"constructor2 called"<<endl;}
exam(exam &p){x = p.x; y = p.y;cout<<"copy constructor called"<<endl;}
void print(){cout << x << " " << y << endl;}
};
int main()
{
exam ob[]={1,2};//这两句有问题
exam ob1[]={exam(1,2),exam(3,4)};//这两句有问题
exam a(1,2);
exam b=a;
return 0;
}
错误信息:
[{
"resource": "/d:/Code/C++/copyTest2.cpp",
"owner": "cpptools",
"severity": 8,
"message": "cannot bind non-const lvalue reference of type 'exam&' to an rvalue of type 'exam'",
"source": "gcc",
"startLineNumber": 14,
"startColumn": 17,
"endLineNumber": 14,
"endColumn": 17
}]
[{
"resource": "/d:/Code/C++/copyTest2.cpp",
"owner": "C/C++6",
"code": "334",
"severity": 8,
"message": "类 \"exam\" 没有适当的复制构造函数",
"source": "C/C++",
"startLineNumber": 15,
"startColumn": 17,
"endLineNumber": 15,
"endColumn": 21
}]
原因分析:
引用的问题。exam &p是非常量左值引用,而exam(1,2)是一个右值。不能将一个右值绑定到一个非常量左值引用。
问题可以类比为:
int &a=1;//这句代码也报错
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zHB9tuM5-1680067994034)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230329124639336.png)]
但将代码改为
const int &a=1;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jjKmq0Qh-1680067994035)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230329124808585.png)]
不再报错
总结
加上const
修饰符是为了让拷贝构造函数能够接受以右值方式传入的临时对象,并保证不对其进行修改。如果拷贝构造函数没有加const
修饰符,当对象被以右值的方式传入拷贝构造函数时,函数内部的非常量引用无法绑定到右值,因为右值是临时对象,是不可修改的,无法通过引用修改它的值,因此编译器会报错。
右值:右值(Rvalue
)是表达式的属性之一,表示的是一个临时的、无名的、不可修改的值,通常在语法上体现为表达式的结果值,比如常量、临时变量、函数返回值等。没有内存空间。
左值:左值(lvalue
)通常指的是可以出现在赋值语句左侧的表达式,例如变量、数组元素、类成员、等等。左值通常可以被取地址,也可以被修改。有内存空间。