C++中用户自定义类型与内置类型的临时对象赋值差异问询
关于C++临时对象赋值的疑问解答
1. 为何用户自定义类型的非const临时对象可被赋值?
C++中,内置类型的右值(比如函数返回的int)是纯值,无法作为赋值操作的左操作数——赋值运算符要求左操作数是可修改的左值(lvalue),而内置类型的右值不满足这个要求,所以f(10,5)=12会编译失败。
但对于用户自定义类型(UDT)的临时对象,情况不同:
- UDT的临时对象是右值,但它本质是一个对象实例,而非纯值。
- 类的成员函数(包括默认的赋值运算符
operator=)默认情况下可以被右值对象调用,除非你显式将赋值运算符限定为仅能被左值调用(比如使用&引用限定符:Rational& operator=(const Rational&) &;)。 - 所以
(a*b)=c中,a*b返回的临时Rational对象可以调用赋值运算符,将c的值赋给它——虽然这个临时对象随后就会被销毁,修改的结果不会被保留,但语法上是合法的。
2. 这种行为的一致性与实践建议
一致性
这种行为是C标准明确允许的,属于语言规则的一部分,不同编译器(GCC、Clang、MSVC)都会一致支持,不存在兼容性问题。但它和内置类型的行为确实存在差异,这是因为C对UDT和内置类型的右值处理逻辑不同:UDT的右值是对象,支持成员函数调用;内置类型的右值是值,不支持赋值。
实践建议
强烈建议避免这种写法,原因如下:
- 临时对象赋值后会立即被销毁,赋值操作没有任何实际意义,无法保留修改后的结果,纯粹是无效操作。
- 这种写法会降低代码的可读性,其他开发者看到时会困惑你的意图,甚至误以为存在逻辑错误。
- 如果确实需要对表达式的结果进行修改,应该先将结果存储到一个左值变量中,再进行赋值操作,比如:
Rational temp = a * b; temp = c;
内容的提问来源于stack exchange,提问作者sam
相关产品推荐
相关产品推荐

