cpp类型不写const报错error: cannot bind non-const lvalue reference of type的可能原因

当一个函数的形参为非const类型,而一个参数以非const传入,编译器一般会认为程序员会在该函数里修改该参数,而且该参数返回后还会发挥作用。

此时如果你把一个临时变量当成非const引用传进来,由于临时变量的特殊性,程序员无法对改临时变量进行操作,同时临时变量可能随时会消失,修改临时变量也毫无意义,因此,编译器规定:临时变量不能被“非const引用”绑定,即使我们不在函数中改变它,编译器也会报错。尤其临时变量存的值作为函数参数传入的时候,该函数参数表中相应的参数类型必须定义为const,否则报错error: cannot bind non-const lvalue reference of type xxxxxxxxxxxxx,报错原因比较隐蔽,debug困难。

下面是报错的代码:(截取部分相关的)

//大致是一个student类,有自定义的构造函数和拷贝构造函数
//代码报错于“使用构造函数定义对象数组”的代码行,但错误定位于“拷贝构造函数”那一块
student::student(char* in_str, float in_g1, float in_g2)
{
    name = new char[strlen(in_str) + 1];
    strcpy(name, in_str);
    g1 = in_g1;
    g2 = in_g2;
    cout << "construct " << name <<endl;
}

student::student(student& in_obj)  // 【问题所在】 参数不加const会报错 
{
    name = (char*)"liu";
    g1 = in_obj.g1 - 10;
    g2 = in_obj.g2 - 10;
    cout << "copy " << name <<endl;
}

int main(){
    student st[] = {student((char*)"zhang", 80, 70), student((char*)"wang", 90, 80)};  // error
    //main函数中的其余部分省略
}

报错如下:

【分析】:

代码报错于“使用构造函数定义对象数组”的代码行,但错误定位于“拷贝构造函数”那一块。

报错的大致含义是:不能把非const的左值引用绑定到student类的右值上(“右值”指的是“只能读取不能被写”的变量,直观理解是“只能放在表达式右边的值”)。就是说:不能把非const的左值引用绑定到“只能读不能写的”(右值)对象上去(因为这样的绑定会使得可以通过引用来写右值rvalue对象

奇怪的是我只是调用了构造函数来构造student类的对象数组,并没有主动调用拷贝构造函数(另外,我还尝试单独调用拷贝构造函数创建对象(而非对象数组)和构造函数创建对象(而非对象数组),均未报错)因此,应该是“定义对象数组”的过程中,自动调用了拷贝构造函数,并且在调用时违背了前文提到的“不能把非const的左值引用绑定到student类的右值上”的原则。

“对象数组”创建的过程中,内部实现如下:先初始化产生对象(此时就把各个对象赋值到相应的各个临时变量(临时对象)中存着),各对象初始化完成后,再把各个临时变量(临时对象)赋值给数组的各个[i]对象空间,完成对象数组的初始化。而这个“赋值”的过程,是“由对象产生对象”,就会调用拷贝构造函数,所以此时如果拷贝构造函数的参数不是const类型,那么把临时变量传进去,就会报错。

【总结】:

定义对象数组并且在定义的同时完成初始化时,必须把 这个类的拷贝构造函数参数表中的那个引用参数 声明为const。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值