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

C++后置自增运算符赋值行为解惑:obj1++=obj2为何合法?

关于C++前置/后置自增运算符左值特性的疑问

我正在阅读Deitel的C++教材,书中提到:

后置自增运算符通常返回一个包含自增前对象原始值的临时对象。C++将这类对象视为右值,不能用于赋值操作的左侧。前置自增运算符返回自增后的实际对象及其新值,该对象可作为左值用于后续表达式。

为验证这段内容,我编写了重载前置和后置自增运算符的Counter类测试程序:

#include <iostream>

class Counter {
private:
    int count;

public:
    Counter(int initialCount = 0) : count(initialCount) {}

    Counter& operator++() {
        ++count;
        return *this;
    }

    Counter operator++(int) {
        Counter temp(*this);
        ++count;
        return temp;
    }

    void display() const {
        std::cout << "Count: " << count << std::endl;
    }
};

int main() {
    Counter obj1(5);
    Counter obj2(10);

    ++obj1 = obj2;
    std::cout << "After ++obj1 = obj2; we get: " << std::endl;
    obj1.display();

    std::cout << std::endl;

    obj1++ = obj2;
    std::cout << "After obj1++ = obj2; we get: " << std::endl;
    obj1.display();

    return 0;
}

不同编译器上的输出一致:

After ++obj1 = obj2; we get: 
Count: 10

After obj1++ = obj2; we get: 
Count: 11

我的疑问:语句obj1++ = obj2;中,我们是否将obj1++用作了左值?根据教材内容这应该是不允许的,能否解释该行为并澄清此场景下左值与右值的概念?


核心解释

首先明确:你的代码中obj1++ = obj2;确实把后置自增的返回值(临时对象)当作了左值,但这是类类型与内置类型的规则差异导致的——内置类型的后置自增返回右值,绝对不能放在赋值左侧(比如i++ = 10;会直接编译报错),但类类型的右值在C++中允许调用成员函数(包括赋值运算符)。

为什么代码能编译运行?

执行obj1++ = obj2;时,实际步骤是:

  1. 调用obj1.operator++(int),创建一个包含obj1自增前值(此时为10)的临时Counter对象;
  2. 调用这个临时对象的默认赋值运算符,将obj2的值(10)赋给它;
  3. 临时对象在语句结束后立即销毁,完全不影响原obj1——这就是你看到obj1最终值为11的原因:后置自增已经把obj1的count从10加到11,赋值操作只修改了那个被销毁的临时对象,没有实际意义。

教材内容的正确性

教材的描述针对的是内置类型,以及符合最佳实践的运算符重载:
按照惯例,我们应该让类的后置自增行为和内置类型一致,禁止将其作为左值。可以通过限制赋值运算符只能用于左值来实现:

class Counter {
    // ... 其他成员 ...
    // 仅允许左值调用赋值运算符
    Counter& operator=(const Counter&) &;
};

这样obj1++ = obj2;就会编译报错,和内置类型的行为对齐。

左值与右值的澄清

  • 左值:可以取地址、能出现在赋值左侧的表达式,代表持久存在的对象(比如obj1、++obj1返回的引用)。
  • 右值:不能取地址、通常是临时存在的对象或字面量(比如5、obj1++返回的临时对象)。
    类类型的右值虽然可以调用成员函数,但这并不改变它是右值的本质——临时对象会被快速销毁,对它的赋值没有实际价值。

内容的提问来源于stack exchange,提问作者Osmium

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 21:22:48