关于C++类重载运算符代码输出为135的技术疑问
为什么这段C++代码的输出是135?
让我们一步步拆解这段代码的执行流程,把每个环节的细节理清楚,你就能明白为什么结果是135了。
第一步:初始化对象v
首先看V v{6};:
- 类
V的构造函数是V(int a = 3, int b = 7) : v{a + b} { },这里你传入了6作为第一个参数a,第二个参数b用默认值7。 - 所以对象
v的成员变量v的值是6 + 7 = 13,这部分你已经搞对了。
第二步:解析表达式(-v - v)
这个表达式要分两步计算,遵循运算符优先级:一元负号-的优先级高于二元减法-,所以先算-v,再用结果减去v。
1. 计算-v(一元负号运算)
这里调用的是类V中重载的一元负号运算符:
V operator-() { return 2 * v; }
- 这里的
v是原对象的成员值13,所以2*13=26。但注意:这个函数的返回类型是V,不是int! - 当你返回一个
int值26时,C++会自动触发隐式类型转换,调用V的构造函数把这个int转成V对象:用26作为a,b用默认值7,所以这个临时V对象的成员变量v是26 + 7 = 33。
2. 计算临时对象(v=33) - v(v=13)(二元减法运算)
现在是两个V对象之间的减法,优先调用类V中重载的二元减法运算符:
V operator-(const V& rop) const { return (3 * v) + (2 * rop.v) + 3; }
- 这里的
v是当前临时对象的成员值33,rop.v是原对象v的成员值13。 - 计算表达式:
3*33 + 2*13 +3 = 99 +26 +3 = 128。同样,返回类型是V,所以128会再次调用构造函数转成V对象:a=128,b=7,得到的临时对象成员变量v是128 +7 =135。
第三步:调用print()
最后对这个成员值为135的临时对象调用print()方法,自然就输出135了。
关于你误解的点
你以为第一个-v返回26后会调用全局的运算符重载,但实际上:
- 一元负号返回的是
V对象(不是int),所以接下来的减法是两个V对象之间的操作,只会调用类的二元减法重载,轮不到全局的operator-(int, const V&)。 - 你忽略了返回值类型的隐式转换:只要重载运算符的返回类型是
V,返回的int都会被自动转换成V对象,调用构造函数计算成员值。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

