You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何该前缀++运算符重载函数要返回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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 16:27:11