当前位置: 首页 > article >正文

C++学习笔记(二十)——类之运算符重载

一、 运算符重载

作用:
运算符重载(Operator Overloading) 允许我们为自定义类赋予运算符(+ - * / == != [] () 等)的特殊功能,使其像内置数据类型一样操作对象

特点:

  • 提高代码可读性,使类的对象能够像内置类型一样使用运算符。
  • 可以定义新的行为,如两个 Complex 类对象的相加 (c1 + c2)。
  • 不能创建新的运算符,只能重载已有运算符。
  • 部分运算符必须作为成员函数或友元函数

二、基本语法和重载的运算符

(1)基本语法

返回类型 operator运算符 (参数) {
    // 重载实现
}
  • 返回类型:通常返回当前类的对象(支持链式调用)。
  • operator 关键字:用于声明或定义运算符重载。
  • 参数:一元运算符通常无参数,二元运算符有一个参数(通常为同类型对象)。

(2)推荐重载的运算符

运算符作用
+ - * /算术运算
++ --自增/自减
>> <<输入/输出
== != < >逻辑比较
[]数组访问
()仿函数

(3)不能重载的运算符

C++ 不能重载以下运算符:

  • . 成员访问
  • .* 成员指针访问
  • :: 作用域解析
  • sizeof 求大小
  • typeid 获取类型

三、重载 + 运算符(成员函数)

作用:
+ 运算符可以用于算术运算

示例 ——重载 + 实现两个 Complex 对象相加:

#include <iostream>
using namespace std;

class Complex {
private:
    double real, imag;

public:
    Complex(double r = 0, double i = 0) : real(r), imag(i) {}

    // 重载 + 运算符
    Complex operator+(const Complex& other) 
    {
        return Complex(real + other.real, imag + other.imag);
    }

    // 显示函数
    void display() 
    {
        cout << real << " + " << imag << "i" << endl;
    }
};

int main() {
    Complex c1(3, 4), c2(1, 2);
    Complex c3 = c1 + c2;  // 等价于 c1.operator+(c2)

    c3.display();  // 输出:4 + 6i

    system("pause");
    return 0;
}

注意:

  • operator+ 重载 +,返回新的 Complex 对象。
  • c1 + c2 等价于 c1.operator+(c2)

四、重载 ++ 运算符(成员函数)

作用:

运算符语法特点
前置递增++obj先递增,再返回修改后的值
后置递增obj++先返回当前值,再递增(带int占位符)

示例1 ——前置++重载:

#include <iostream>
using namespace std;

class Counter {
private:
    int value;

public:
    Counter(int v = 0) : value(v) {}

    // 前置递增:++obj
    Counter& operator++() 
    {
        ++value;  // 先增加值
        return *this;  // 返回当前对象
    }

    void show() 
    { 
        cout << "Value: " << value << endl; 
    }
};

int main() {
    Counter c(5);
    ++c;   // 先递增,再返回
    c.show();  // 输出 Value: 6

    system("pause");
    return 0;
}

注意:

  • 直接修改 value,然后返回当前对象的引用(*this)。
  • 返回Counter&允许连续递增(如++++c;)。

示例2 ——后置++重载:

#include <iostream>
using namespace std;

class Counter {
private:
    int value;

public:
    Counter(int v = 0) : value(v) {}

    // 后置递增:obj++
    Counter operator++(int) 
    {
        Counter temp = *this;  // 先保存当前值
        value++;  // 再递增
        return temp;  // 返回原值的副本
    }

    void show() 
    {
        cout << "Value: " << value << endl; 
    }
};

int main() {
    Counter c(5);
    Counter old = c++;  // 先返回旧值,再递增
    old.show();  // Value: 5 (旧值)
    c.show();    // Value: 6 (递增后)

    system("pause");
    return 0;
}

注意:

  • operator++(int) 参数 int 是占位符,无实际意义。
  • 返回Counter的副本,确保obj++先返回原值,再递增。

五、重载 << 运算符(友元函数)

作用:
由于 << 运算符的左操作数是 ostream 类型不能作为成员函数,因此需要定义友元函数

作为成员函数时,左操作数必须是 class 对象(obj),无法让cout作为左操作数,即会出现obj << cout;的情况)。

示例——重载 << 实现 cout << Complex

#include <iostream>
using namespace std;

class Complex {
private:
    double real, imag;

public:
    Complex(double r = 0, double i = 0) : real(r), imag(i) {}

    // 友元函数重载 <<
    friend ostream& operator<<(ostream& out, const Complex& c) 
    {
        out << c.real << " + " << c.imag << "i";
        return out;  // 允许链式调用
    }
};

int main() {
    Complex c1(5, 6);
    cout << "复数: " << c1 << endl;  // 调用 operator<<

    system("pause");
    return 0;
}

注意:

  • friend 关键字允许 operator<< 访问 Complex 的私有成员
  • 必须返回 ostream&,支持 cout << c1 << c2; 链式调用

六、重载 [] 运算符

作用:
[] 运算符可以用于封装数组访问

示例——重载 [] 访问数组:

#include <iostream>
using namespace std;

class Array {
private:
    int data[5];

public:
    Array() 
    { 
        for (int i = 0; i < 5; i++) 
            data[i] = i * 10; 
    }

    // 重载 []
    int& operator[](int index) 
    {
        if (index < 0 || index >= 5) {
            cout << "索引超出范围!" << endl;
            exit(1);
        }
        return data[index];
    }
};

int main() {
    Array arr;
    cout << arr[2] << endl;  // 输出 20
    arr[2] = 99;
    cout << arr[2] << endl;  // 输出 99

    system("pause");
    return 0;
}

注意:

  • 返回 int& 允许修改数组元素(支持 arr[2] = 99)。
  • 防止越界访问,如果索引超出范围,直接 exit(1) 终止程序。

七、重载 () 运算符

作用:
() 允许对象像函数一样被调用,用于仿函数(Function Object)

示例——重载 ()

#include <iostream>
using namespace std;

class Multiply {
public:
    int operator()(int a, int b) 
    {
        return a * b;
    }
};

int main() {
    Multiply multiply;
    cout << "3 × 4 = " << multiply(3, 4) << endl;  // 输出 12

    system("pause");
    return 0;
}

注意:

  • operator() 允许对象 multiply 像函数一样被调用

八、重载 == 运算符

作用:
== 运算符可以用于比较两个对象是否相同

示例——重载 == 比较 Person 是否相同:

#include <iostream>
using namespace std;

class Person {
private:
    string name;
    int age;

public:
    Person(string n, int a) : name(n), age(a) {}

    // 重载 ==
    bool operator==(const Person& other) 
    {
        return (name == other.name) && (age == other.age);
    }
};

int main() {
    Person p1("Alice", 25), p2("Alice", 25), p3("Bob", 30);

    cout << (p1 == p2) << endl;  // 输出 1(true)
    cout << (p1 == p3) << endl;  // 输出 0(false)

    system("pause");
    return 0;
}

注意:

  • operator== 比较 nameage 是否相同

http://www.kler.cn/a/587974.html

相关文章:

  • 代码随想录算法训练营第32天 | 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯
  • 【数据分析】读取文档(读取Excel)
  • Varjo:为战场各兵种综合训练提供XR技术支持
  • DeepSeek-R1大模型微调技术深度解析:架构、方法与应用全解析
  • 【论文阅读】Cross-View Fusion for Multi-View Clustering
  • Flash Attention原理讲解
  • 【Linux】:socket编程——UDP
  • 传输层tcp/udp
  • 287. 寻找重复数
  • Python实现万年历
  • DAY34 贪心算法Ⅲ
  • C++模版(复习)
  • C++|类和对象
  • Android 拍照开发——移动虚拟机摄像头
  • java简单基础学习
  • 关于离子滤波小记
  • 数据库管理-第302期 国产类RAC架构数据库网络连接方式(20250314)
  • RabbitMQ:业务幂等、死信交换机
  • C++基础——从C语言快速入门
  • matlab 自适应模糊PID在反应釜温度控制中的应用