跳转到内容

C++ 自增自减运算符重载

来自代码酷

C++自增自减运算符重载[编辑 | 编辑源代码]

自增(++)和自减(--)运算符是C++中常用的单目运算符,用于对变量进行加1或减1操作。在C++中,我们可以通过运算符重载(Operator Overloading)为自定义类定义这些运算符的行为,使其支持类似内置类型的操作。

介绍[编辑 | 编辑源代码]

自增和自减运算符有两种形式:

  • 前缀形式(如 ++x--x):先执行运算,再返回结果。
  • 后缀形式(如 x++x--):先返回当前值,再执行运算。

在重载时,C++通过一个额外的int类型参数来区分前缀和后缀形式。如果没有该参数,则为前缀形式;如果有(即使不使用),则为后缀形式。

语法[编辑 | 编辑源代码]

自增和自减运算符的重载语法如下:

// 前缀自增
ReturnType operator++();

// 后缀自增
ReturnType operator++(int);

// 前缀自减
ReturnType operator--();

// 后缀自减
ReturnType operator--(int);

代码示例[编辑 | 编辑源代码]

以下是一个完整的示例,展示如何为自定义的 Counter 类重载自增和自减运算符:

#include <iostream>

class Counter {
private:
    int count;

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

    // 前缀自增
    Counter& operator++() {
        ++count;
        return *this;
    }

    // 后缀自增
    Counter operator++(int) {
        Counter temp = *this;
        ++count;
        return temp;
    }

    // 前缀自减
    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 c(5);

    // 前缀自增
    ++c;
    c.display(); // 输出: Count: 6

    // 后缀自增
    Counter c2 = c++;
    c.display();  // 输出: Count: 7
    c2.display(); // 输出: Count: 6

    // 前缀自减
    --c;
    c.display(); // 输出: Count: 6

    // 后缀自减
    Counter c3 = c--;
    c.display();  // 输出: Count: 5
    c3.display(); // 输出: Count: 6

    return 0;
}

输出[编辑 | 编辑源代码]

Count: 6
Count: 7
Count: 6
Count: 6
Count: 5
Count: 6

解释[编辑 | 编辑源代码]

1. **前缀自增(++c)**:直接修改 count 并返回当前对象的引用。 2. **后缀自增(c++)**:先保存当前状态到临时对象,再修改 count,最后返回临时对象(旧值)。 3. 自减运算符的逻辑与自增类似。

实际应用场景[编辑 | 编辑源代码]

自增和自减运算符重载常用于以下场景: 1. **迭代器**:STL迭代器通过重载 ++-- 实现遍历。 2. **自定义计数器**:如示例中的 Counter 类。 3. **资源管理**:例如智能指针的引用计数增减。

迭代器示例[编辑 | 编辑源代码]

class ListIterator {
    Node* current;

public:
    ListIterator(Node* node) : current(node) {}

    // 前缀++
    ListIterator& operator++() {
        current = current->next;
        return *this;
    }

    // 后缀++
    ListIterator operator++(int) {
        ListIterator temp = *this;
        current = current->next;
        return temp;
    }
};

注意事项[编辑 | 编辑源代码]

1. **返回值类型**:前缀形式通常返回引用(Counter&),后缀形式返回临时对象(Counter)。 2. **性能**:后缀运算符会创建临时对象,因此在性能敏感场景优先使用前缀形式。 3. **一致性**:重载的运算符行为应与内置类型一致,避免混淆。

总结[编辑 | 编辑源代码]

通过重载自增和自减运算符,可以使自定义类的行为更直观。关键点:

  • 前缀形式无参数,后缀形式带 int 参数。
  • 前缀返回引用,后缀返回临时对象。
  • 确保重载的语义清晰且符合预期。

graph TD A[开始] --> B{选择形式} B -->|前缀| C[直接修改值并返回引用] B -->|后缀| D[保存旧值, 修改值, 返回旧值] C --> E[结束] D --> E