C++:运算符重载引入

从函数重载说起

(1)函数重载是在一定作用域内,多个相同名称但不同参数列表的函数重载
(2)编译时由编译器根据实际调用时给的实参情况来判定本次实际用哪个函数,这个过程叫重载决策
(3)重载函数本质上就是多个独立函数,重载机制在编译时发生,运行时不参与
(4)函数重载的意义就是避免我们胡乱起名,方便编写类库覆盖所有可能操作,是一种语法糖

什么是运算符重载

(1)什么是运算符?譬如+ - * / %等算术运算符和> < == !=等关系运算符就是典型的可重载运算符(但不是所有的运算符都可以重载,譬如sizeof)
(2)运算符诞生于C语言中,用来对变量进行某种“预定义”的运算操作,这种预定义是编译器预制好的,编译时会翻译对应到CPU机器码
(3)面向对象时代带来新的问题:两个对象如何运算?譬如:Person a, b, c; c = a + b; 此处的+让编译器如何解读?见下面示例

运算符重载示例

(1)class coordinate, 2个属性x和y,直接对2个对象执行+,编译不通过
(2)重载+运算符后,再编译并执行,查看结果,分析结果

#include <iostream>

class Coordinate {
private:
    int x;
    int y;

public:
    // 构造函数
    Coordinate(int x = 0, int y = 0) : x(x), y(y) {}

    // 重载加法运算符
    Coordinate operator+(const Coordinate& other) const {
        return Coordinate(x + other.x, y + other.y);
    }

    // 重载减法运算符
    Coordinate operator-(const Coordinate& other) const {
        return Coordinate(x - other.x, y - other.y);
    }

    // 重载等于运算符
    bool operator==(const Coordinate& other) const {
        return x == other.x && y == other.y;
    }

    // 重载赋值运算符
    Coordinate& operator=(const Coordinate& other) {
        if (this == &other) {
            return *this;  // 处理自赋值
        }
        x = other.x;
        y = other.y;
        return *this;
    }

    // 重载输出运算符
    friend std::ostream& operator<<(std::ostream& os, const Coordinate& coord) {
        os << "(" << coord.x << ", " << coord.y << ")";
        return os;
    }
};

int main() {
    Coordinate a(3, 4);
    Coordinate b(1, 2);

    Coordinate c = a + b;
    Coordinate d = a - b;

    std::cout << "a: " << a << std::endl;
    std::cout << "b: " << b << std::endl;
    std::cout << "a + b: " << c << std::endl;
    std::cout << "a - b: " << d << std::endl;

    if (a == b) {
        std::cout << "a is equal to b" << std::endl;
    } else {
        std::cout << "a is not equal to b" << std::endl;
    }

    Coordinate e;
    e = a;
    std::cout << "e after assignment: " << e << std::endl;

    return 0;
}

运算符重载的本质

(1)表面上,运算符重载是对C++源生运算符的意义,在某个class中做重定义
(2)本质上,运算符被映射到执行相应的成员函数,所以运算符重载其实是重定义对象的运算符所对应的函数

运算符重载的意义

(1)运算符重载是一种语法特性,C++全面支持,Java不支持,python有限度的支持
(2)没有运算符重载照样写代码,所有操作全部通过显式调用相应成员函数来完成即可
(3)运算符重载是一种语法糖,可以让代码“看起来更简洁,更优雅”,将复杂实现隐藏在类的内部
(4)运算符重载机制加大了类库作者的工作量,减少了调用类库写功能的人的书写量
(5)C++支持运算符重载机制有其理念和历史原因,是对写法简洁和效率优秀的综合考量
(6)赋值运算符=重载和引用结合,可有效提升代码效率,后面会有案例详解
(7)赋值运算符=重载时要注意有指针成员时会涉及浅拷贝和深拷贝,后面会有案例详解
(8)运算符重载一定程度上体现了C++的多态性,因为同样的运算符在不同的class中表现是不同的

理解运算符重载机制的两部曲

(1)记住、理解、并且能轻松认出写出运算符重载函数的格式、名称、对应的运算符。
(2)理解在运算符重载函数中this表示谁,参数表示谁,返回值对应谁,这个是重中之重。

通过代码实践来深度理解运算符重载函数
(1)运算符+的重载中的对应关系回顾
总结:a + b; -> a.operator+(b),a对应this,b对应函数参数other,a+b的表达式的值对应函数返回值
(2)运算符=(赋值运算符)的重载中的对应关系
总结:c = a; -> c.operator=(a); c对应this,a对应other,c=a整个表达式的值(其实就是c)对应函数返回值
运算符重载总的规则:运算符左边的是this,右边的是other,运算符加操作数的整个表达式的返回值就是返回值



#include <iostream>

class Coordinate {
 private:
  int x;
  int y;

 public:
  // 构造函数
  Coordinate(int x = 0, int y = 0) : x(x), y(y) {}

  // 重载加法运算符
  Coordinate operator+(const Coordinate &other) const {
    return Coordinate(x + other.x, y + other.y);
  }

  // //重载+=
  // Coordinate operator+=(const Coordinate &other) const {
  //      return Coordinate(x + other.x, y + other.y);
  // }
  //   函数返回类型问题:+=
  //   运算符重载应该返回对当前对象的引用(*this),而不是返回一个新的
  //   Coordinate 对象。
  // 方法定义问题:+= 运算符重载方法不应该是
  // const,因为它需要修改调用对象的状态。 重载+=运算符
  Coordinate &operator+=(const Coordinate &other) {
    x += other.x;
    y += other.y;
    return *this;
  }
  // 重载减法运算符
  Coordinate operator-(const Coordinate &other) const {
    return Coordinate(x - other.x, y - other.y);
  }

  // 重载等于运算符
  bool operator==(const Coordinate &other) const {
    return x == other.x && y == other.y;
  }

  // 重载赋值运算符
  Coordinate &operator=(const Coordinate &other) {
    if (this == &other) {
      return *this;  // 处理自赋值
    }
    x = other.x;
    y = other.y;
    return *this;
  }

  // 重载输出运算符
  friend std::ostream &operator<<(std::ostream &os, const Coordinate &coord) {
    os << "(" << coord.x << ", " << coord.y << ")";
    return os;
  }
};

int test070203() {
  Coordinate a(3, 4);
  Coordinate b(1, 2);

  Coordinate c = a + b;  // c = a.operator+(b)
  Coordinate d = a - b;

  std::cout << "a: " << a << std::endl;
  std::cout << "b: " << b << std::endl;
  std::cout << "a + b: " << c << std::endl;
  std::cout << "a - b: " << d << std::endl;

  if (a == b) {
    std::cout << "a is equal to b" << std::endl;
  } else {
    std::cout << "a is not equal to b" << std::endl;
  }

  Coordinate e;
  e = a;
  std::cout << "e after assignment: " << e << std::endl;

  Coordinate f;
  f = (e = a);
  std::cout << "f after assignment: " << f << std::endl;

  Coordinate h(1, 1);
  h += a;
  std::cout << "h after assignment: " << h << std::endl;

  Coordinate i(1, 1);
  Coordinate j(1, 1);
  Coordinate k(1, 1);
  i += (k += j);
  std::cout << "i after assignment: " << i << std::endl;
  return 0;
}

总结

因为自己定义的类型不能直接使用预算符,所以需要进行运算符重载
重载运算符需要明确变量位于操作那个位置,注意返回值

学习记录,侵权联系删除。
来源:朱老师物联网大课堂

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

li星野

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

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

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

打赏作者

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

抵扣说明:

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

余额充值