重载BigInt赋值运算符后return合并语句报错,默认版本无此问题
问题拆解与解决
嘿,这个问题的核心坑点就在你手动实现的赋值运算符返回值类型上,和编译器自动生成的版本差异导致了这个奇怪的报错。
先看你写的赋值运算符:
void operator = (const BigInt&);
它返回的是void,但C编译器自动生成的赋值运算符,默认会返回BigInt&(也就是当前对象的引用)——这是C里赋值运算符的标准惯例。
为什么两种写法结果天差地别?
咱们一步步分析:
报错的写法:
return res = a.BigInt::operator - (b);- 这里的
res = ...本质是调用你写的void operator=(const BigInt&),这个表达式的结果是void类型(因为赋值运算符返回void)。 - 但你的
operator+函数要求返回BigInt类型,void根本没法转换成BigInt,编译器自然会抛出那个类型不匹配的错误。
- 这里的
正常运行的写法:
res = a.BigInt::operator - (b); return res;- 第一行只是执行赋值操作(虽然赋值返回void,但我们不需要它的返回值),第二行直接返回
res这个现成的BigInt对象,类型完全匹配,所以编译器没意见。
- 第一行只是执行赋值操作(虽然赋值返回void,但我们不需要它的返回值),第二行直接返回
怎么修复这个问题?
按照C++的标准规范,赋值运算符应该返回当前对象的引用,这样既支持链式赋值(比如a = b = c),也能解决你遇到的这个问题。把你的赋值运算符改成:
// 声明 BigInt& operator = (const BigInt&); // 实现 BigInt& BigInt::operator = (const BigInt &p) { this->vec = p.vec; this->neg = p.neg; return *this; // 返回当前对象的引用 }
修改之后,return res = a.BigInt::operator - (b);就能正常工作了——因为res = ...现在返回的是BigInt&,可以直接匹配operator+的返回值要求(即使函数返回BigInt,引用也会被自动拷贝成临时对象)。
额外补充
编译器自动生成的赋值运算符严格遵循C++的最佳实践,返回对象引用,所以用自动生成版本时,res = ...的结果是BigInt&,可以直接作为return的返回值,自然不会报错。你手动写的void返回版本打破了这个惯例,才触发了这个问题。
内容的提问来源于stack exchange,提问作者H-005
相关产品推荐
相关产品推荐

