为何该前缀++运算符重载函数要返回Month对象?
问题:前缀递增运算符重载为何需要返回值?
我正在阅读Bjarne Stroustrup所著的《C++编程原理与实践》,在第9.6章的运算符重载部分,他给出了为enum class Month定义前缀递增运算符++的示例代码:
enum class Month { Jan=1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec }; Month operator++(Month& m) // prefix increment operator { m = (m==Month::Dec) ? Month::Jan : Month(static_cast<int>(m)+1); return m; }
他说明该运算符可如下使用:
Month m = Month::Sep; ++m; // m becomes Oct ++m; // m becomes Nov ++m; // m becomes Dec ++m; // m becomes Jan (“wrap around”)
但我不解的是,既然已经通过引用传入并修改了Month对象,为何还要返回Month?我写成如下void版本的函数测试后也能正常运行,想知道自己忽略了什么:
void operator++(Month& m) // prefix increment operator { m = (m==Month::Dec) ? Month::Jan : Month(static_cast<int>(m)+1); }
回答
- 遵循内置类型的行为惯例:C++里内置类型的前缀
++(比如++i)本身就会返回递增后的对象,开发者已经习惯了这种用法——比如可以写int b = ++a;直接把递增后的值赋值给变量,或者用if (++a == 10)这类表达式。重载运算符时保持这个行为,能让你的代码符合所有人的直觉,避免出现不符合预期的使用限制。 - 支持更灵活的表达式写法:返回值后,你可以把
++m嵌入到其他表达式里,比如:
如果是Month m = Month::Nov; if (++m == Month::Dec) { // 做一些处理 } // 或者直接输出递增后的值 std::cout << static_cast<int>(++m) << std::endl;void版本,这些写法都会报错,因为void类型不能参与表达式运算。 - 保持运算符接口的一致性:C中后缀
++运算符(比如m++)要求必须返回递增前的原值,前缀++返回递增后的值,能让两个版本的运算符接口风格统一,符合C运算符重载的规范,也方便其他开发者理解和使用你的代码。
内容的提问来源于stack exchange,提问作者a_floating_point
相关产品推荐
相关产品推荐

