C++非常量引用初始化无效错误:自定义string类拷贝构造问题
问题分析与修复方案
核心原因
你的代码出现编译错误的本质是:
s1 + s2返回的是临时对象(右值),而你的拷贝构造函数参数是chaine &(非const左值引用)。C++语法规定,右值无法绑定到非const的左值引用,因此chaine s3 = s1 + s2;这种拷贝初始化方式会触发invalid initialization of non-const reference错误。- 而
chaine s3; s3 = s1 + s2;是先通过默认构造函数创建s3,再调用赋值运算符。只要赋值运算符的参数能接受右值(比如参数是const引用或值传递),就能正常执行。
修复步骤
需要对两个函数进行修改:
1. 修改拷贝构造函数为const引用参数
将拷贝构造函数的参数改为const chaine &,这样既可以接受左值,也能接受右值(临时对象):
chaine(const chaine &chaine_obj){ char* str_cpy = new char[chaine_obj.len +1]; str_cpy[chaine_obj.len] = '\0'; this->len = chaine_obj.len; for(int i = 0; i < chaine_obj.len; i++){ str_cpy[i] = chaine_obj.str[i]; } this->str = str_cpy; }
2. 修改operator+的参数与成员函数限定符
operator+不应该修改当前对象或传入的对象,因此需要:
- 将参数改为
const chaine &,支持const对象的拼接 - 给成员函数添加
const限定符,表明该函数不会修改当前类的成员变量
修改后的代码:
chaine operator+(const chaine &chaine_obj) const { chaine res; res.len = this->len + chaine_obj.len; char *str_cpy = new char[this->len + chaine_obj.len + 1]; str_cpy[this->len + chaine_obj.len] = '\0'; for(int i = 0; i < this->len + chaine_obj.len; ++i){ if(i < this->len) str_cpy[i] = this->str[i]; else str_cpy[i] = chaine_obj.str[i-this->len]; } res.str = str_cpy; return res; }
补充说明
修改后,chaine s3 = s1 + s2;会正常触发拷贝构造(或在编译器优化下直接构造,即NRVO),两种写法都能正常编译运行。同时,const对象也可以调用operator+,代码的健壮性得到提升。
内容的提问来源于stack exchange,提问作者Mohamed Mahdi
相关产品推荐
相关产品推荐

