C++基础知识(五:运算符重载)

文章讲述了C++中运算符重载的原理、基本原则,包括如何重载二元、一元、赋值、转换、I/O流等运算符,以及成员函数和全局函数的重载格式。通过实例展示了如何使自定义类参与运算,强调了重载的合理性和一致性。
摘要由CSDN通过智能技术生成

运算符重载是C++中的一项强大特性,它允许程序员为自定义类型(如类或结构体)重新定义标准运算符的行为,使得这些运算符能够适用于自定义类型的操作。这样做可以增强代码的可读性和表达力,使得代码更接近自然语言,同时保持了面向对象编程的封装性。

目录

基本原则

重载类型

【1】运算符重载函数名格式

【2】运算符重载的目的

【3】运算符重载函数的格式

【4】算数运算符的重载

示例:

【5】赋值运算符的重载

示例:

【6】条件运算符的重载

示例:

【7】()运算符的重载

示例:

【8】自增自减运算符的重载

示例:

【9】不能重载的运算符


基本原则

  1. 保留原有语义:重载的运算符应当保持其原有的基本意义,比如加号+通常用于表示相加或组合的概念。
  2. 不要滥用:虽然运算符重载很灵活,但过度或不恰当的使用会使得代码难以理解和维护。
  3. 一致性:运算符的行为应与内置类型或大家公认的约定保持一致,以减少学习和使用的障碍。
  4. 明确性:确保重载的运算符在其上下文中具有明确的意义,避免引起混淆。

重载类型

  • 二元运算符:如+-*/等,需要至少两个操作数。
  • 一元运算符:如++--!等,只涉及一个操作数。
  • 赋值运算符:如=+=-=*=/=等,有特殊的规则,比如需要考虑自赋值的情况。
  • 转换运算符:如operator T(),允许类的对象隐式或显式转换为另一种类型。
  • I/O流运算符:如<<>>,用于与标准输入输出流集成,增强类的可读性和可写性。
  • 条件运算符:如<>==等,用于比较操作。
  • 下标运算符[]:使得对象可以像数组那样通过索引访问。
  • 函数调用运算符():允许对象像函数一样被调用。

【1】运算符重载函数名格式

返回值  operator运算符(参数)
{
   //函数体
}

【2】运算符重载的目的

让自己定义的类也能直接参与运算

运算符重载的要求:

  1. 不能创造运算符,必须对已有的运算符重载
  2. 不能更改运算符本身的功能,+运算重载后实现乘法运算

【3】运算符重载函数的格式

  1. 成员函数的格式:给哪个类重载运算符,就把重载函数定义为哪个类的成员函数
  2. 全局函数的格式:需要在类内声明全局函数为友元函数

成员函数版的运算符重载一定比全局函数版的运算符重载一个参数,成员函数本身提供了一个类对象

【4】算数运算符的重载

算术运算都是双目运算:

格式:L # R  ---->需要两个类对象作为参数

结果:右值

参数:运算过程中不需要修改操作数,可以定义为const

示例:

#include <iostream>

class Complex {
public:
    // 默认构造函数
    Complex() : real(0), imag(0) {}

    // 带参数的构造函数
    Complex(double r, double i) : real(r), imag(i) {}

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

    // 显示复数的方法
    void display() const {
        std::cout << real << " + " << imag << "i" << std::endl;
    }

private:
    double real;   // 实部
    double imag;   // 虚部
};

int main() {
    Complex num1(3, 4);  // 创建复数 3 + 4i
    Complex num2(1, 2);  // 创建复数 1 + 2i

    Complex sum = num1 + num2;  // 使用重载的 "+" 运算符

    std::cout << "Sum of the two complex numbers: ";
    sum.display();  // 输出相加后的复数

    return 0;
}

【5】赋值运算符的重载

operator= :拷贝赋值函数

+=、-=···运算符的重载

格式:L # R

结果:对左操作数的修改,是一个左值

参数:左操作数运算过程中可以修改,右操作数不能修改

示例:

// 赋值运算符重载
Complex& operator=(const Complex& other) {
    if (this != &other) {  // 防止自我赋值
        real = other.real;
        imag = other.imag;
    }
    return *this;
}

【6】条件运算符的重载

<   >·····

格式:L # R

结果:bool类型的真值或者假值

参数:运算过程中不需要修改操作数,可以定义为const

bool operator>(Complex &c1,Complex &c2)

{}

示例:

// 小于运算符重载
bool operator<(const Complex& other) const {
    return (real < other.real) || ((real == other.real) && (imag < other.imag));
}

【7】()运算符的重载

  1. 对()运算符,调用函数的性质重载
  2. 对()强转的性质重载    float a;  int(a);

格式:operator 数据类型(){}    ---->因为强转类型已经明确了返回值类型

示例:

// 下标运算符重载
double& operator[](int index) {
    if (index == 0) return real;
    else if (index == 1) return imag;
    else throw std::out_of_range("Index out of range for Complex number.");
}

【8】自增自减运算符的重载

a++、 ++a、

前自增:

成员函数:Complex &operator++(){}

全局函数:Complex &operator++(Complex &c1){}

后自增: ----->需要使用哑元和前自增区分

成员函数:Complex &operator++(int){}

全局函数:Complex &operator++(Complex &c1,int){}

示例:

// 自增运算符前置版本
Complex& operator++() {
    ++real;
    ++imag;
    return *this;
}

// 自增运算符后置版本
Complex operator++(int) {
    Complex temp(*this);
    ++(*this);
    return temp;
}

// 自减运算符前置版本
Complex& operator--() {
    --real;
    --imag;
    return *this;
}

// 自减运算符后置版本
Complex operator--(int) {
    Complex temp(*this);
    --(*this);
    return temp;
}

【9】不能重载的运算符

  1. sizeof()
  2. 成员访问运算符.    
  3. 指针访问运算符  *  ---->对指针访问
  4. ::  域限定符
  5. a?a:b    
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笨笨小乌龟11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值