运算符重载 Operator Overload

可以为运算符增加一些新的功能

class Point {
private:int m_x;int m_y;
public:Point(int x, int y) :m_x(x), m_y(y) {}void display() {cout << "(" << m_x << ", " << m_y << ")" << endl;}
};
  • 直接将两个Point类相加得到新的点

    比如Point p3 = p1 + p2;,这样就要使用运算符重载,因为平常加号两端不可以是Point类的

class Point {
friend Point operator+(const Point &, const Point &);
private:int m_x;int m_y;
public:Point(int x, int y) :m_x(x), m_y(y) {}void display() {cout << "(" << m_x << ", " << m_y << ")" << endl;}
};Point operator+(const Point &p1, const Point &p2) {return Point(p1.m_x + p2.m_x, p1.m_y + p2.m_y);
}
// 1. 传入的Point类最好加上引用,避免产生不必要的中间变量
// 2. 最好加上const,这样const和非const对象都可以传入,接受范围大一些
// 3. 加上const和引用后,友元函数传入参数也要加const和引用int main() {Point p1(10, 20);Point p2(20, 30);Point p3 = p1 + p2;// 相当于 Point p3 = operator+(p1, p2);
}

为运算符加号’+'增加新的功能,返回一个point。

这样是把运算符重载函数放在类外面,如果放到里面变成一个成员函数,就只要传入一个Point对象就可以了,并且也不需要声明友元函数了。

class Point {
private:int m_x;int m_y;
public:Point(int x, int y) :m_x(x), m_y(y) {}void display() {cout << "(" << m_x << ", " << m_y << ")" << endl;}// 最左边的const为了防止返回的Point被赋值 (p1 + p2 = p3是不允许的)// 最右边的const为了const返回值又可以调用operator+ (但要允许p1 + p2 + p3)const Point operator+(const Point &point) const{return Point(this->m_x + point.m_x, this->m_y + point.m_y);// 或者省略this// return Point(m_x + point.m_x, m_y + point.m_y);}
};
int main() {Point p1(10, 20);Point p2(20, 30);p1 + p2;// 相当于 p1.operator+(p2);
}

所以,全局函数、成员函数都支持运算符重载

返回值最好是个const对象,返回值不允许再被赋值,但加上const之后就不允许连续相加了。所以要再加一个const。

  • 再实现一下+=
class Point {
private:int m_x;int m_y;
public:Point(int x, int y) :m_x(x), m_y(y) {}void display() {cout << "(" << m_x << ", " << m_y << ")" << endl;}// 最左边的const为了防止返回的Point被赋值// 最右边的const为了const返回值又可以调用operator+const Point operator+(const Point &point) const{return Point(this->m_x + point.m_x, this->m_y + point.m_y);// 或者省略this// return Point(m_x + point.m_x, m_y + point.m_y);}    // 为了能够再赋值,返回是当前对象而不是地址,所以返回*this而不是this,返回this就是返回当前对象的地址// 加引用是为了防止产生中间变量,如果将类里面返回的函数拿到另一个函数中用,会重新拷贝构造出一个新的对象Point &operator+=(const Point &point) {m_x += point.m_x;m_y += point.m_y;return *this;}
};
int main() {Point p1(10, 20);Point p2(20, 30);p1 += p2;// 相当于 p1.operator+=(p2);(p1 += p2) = Point(50, 60);// p1 = p1 + p2;// p1 = Point(50, 60);
}
  • 完成-p1的操作(单目运算符)
const Point operator-() const {return Point(-m_x, -m_y);
}
  • 前置++和后置++
// 前置++, ++p
Point &operator++() {m_x++;m_y++;return *this;
}// 后置++(加一个int,只能是int,无论内部是什么样),p++
const Point operator++(int) {Point old(m_x, m_y);m_x++;m_y++;return old;
}
  • 注意:

    • 前置++可以被赋值,后置++不可以

      比如:

      ++a = 20; // 可以
      (a++) = 20; // 不可以
      

      所以前置++返回是一个对象的引用

      后置++返回的是const Point

  • 左移,实现 cout << p1 << endl;

    // 不能写 void operator<<()
    // 因为<<不是单目运算符
    // 下面这个写法相当于
    // p1 << 10;
    // p1.operator<<(10)
    void operator<<(int a) {}
    // 但我们要实现的是cout << p1 << endl; 传入point
    // 它就不能是成员函数,必须是全局函数,所以要将其加入Point的友元函数
    // cout也是对象,是ostream对象(output stream)
    // 如果要实现cout << p1 << p2;
    // 就要返回cout,这很重要!
    // 但cout的返回值是不能再被赋值的,可以把这个函数放到private中,这样就不会再被赋值
    ostream &operator<<(ostream &cout, const Point& point) {cout << "(" << point.m_x << ", " << point.m_y << ")";return cout;
    }
    
  • 右移,实现输入

    // input stream -> istream
    istream &operator>>(istream &cin, Point &point) {cin >> point.m_x;cin >> point.m_y;return cin;
    }
    
  • 调用父类的运算符重载函数

  • 运算符重载注意点

    • 有些运算符不可以被重载

      • 对象成员访问运算符:.
      • 域运算符:::
      • 三目运算符:?:
      • sizeof
    • 有些运算符只能写在类里面重载为成员函数,比如

      • 赋值运算符:=
      • 下标运算符:[]
      • 函数运算符:()
      • 指针访问运算符:->

【C++】运算符重载 Operator Overload相关推荐

  1. C++——运算符重载operator

    C++--运算符重载operator C++ prime plus第11章,运算符重载是C++的一种多态.运算符重载格式如下: operator运算符(argument-list) 1.做普通函数重载 ...

  2. 第11章 运算符重载与约定

    第11章 运算符重载与约定 我们在<第2章 Kotlin 语法基础>中已经学习过关于运算符的相关内容,本章将继续深入探讨Kotlin中的运算符的重载与约定. 通常一门编程语言中都会内置预定 ...

  3. C++之运算符重载(上)

    1.概念 所谓重载,就是重新赋予新的含义.函数重载就是对一个已有的函数赋予新的含义,使之实现新功能,因此,一个函数名就可以用来代表不同功能的函数,也就是"一名多用". 运算符也可以 ...

  4. C++语言运算符重载

    概念 在C语言中,运算符只能用于基本数据类型,例如,可以用==判断两个整数是否相等,但不能用于判断字符串是否相等,也不能用于判断结构体,也不能用于判断类. 在C++中,运算符的重载就是把运算符的符号赋 ...

  5. C++基础::运算符重载

    [][]:不在其内 楔子 std::string str = "hello "; str += "world!"; std::cout << str ...

  6. 音视频开发(十九):运算符重载、继承、多态、模版

    目录 类和对象的重要知识点 运算符重载 继承 多态 模版 一.类和对象的重要知识点 1.1 深拷贝与浅拷贝 浅拷贝:简单的赋值拷贝操作,拷贝构造 深拷贝:在堆区重新申请空间,进行拷贝操作 1.2 th ...

  7. 音视频开发系列(46)运算符重载、继承、多态、模版

    一.类和对象的重要知识点 1.1 深拷贝与浅拷贝 浅拷贝:简单的赋值拷贝操作,拷贝构造 深拷贝:在堆区重新申请空间,进行拷贝操作 1.2 this指针 this指针指向被调用的成员函数所属的对象. 本 ...

  8. C++入门:构造函数,析构函数,拷贝构造函数,运算符重载详解

    目录 类的6个默认成员函数 一.构造函数 1.概念 2.特征如下: (1) 函数名与类名相同. (2)无返回值. (3)对象实例化时编译器自动调用对应的构造函数. (4)构造函数可以重载. (5)如果 ...

  9. C++的拷贝构造函数、operator=运算符重载,深拷贝和浅拷贝、explicit关键字

    1.在C++编码过程中,类的创建十分频繁. 简单的功能,当然不用考虑太多,但是从进一步深刻理解C++的内涵,类的结构和用法,编写更好的代码的角度去考虑,我们就需要用到标题所提到的这些内容. 最近,在看 ...

最新文章

  1. constrain to margins
  2. PWA(Progressive Web App)入门系列:消息通讯
  3. Cable:360实现的新虚拟网络架构
  4. mysql数据库技术方案,MySql数据库优化方案
  5. oracle开机时间,[20201106]了解oracle数据库启动时间.txt
  6. php int 设置超时,php如何设置超时时间
  7. html隐藏并失效,如果元素开始隐藏,css过渡将不起作用
  8. 【英语学习】【WOTD】wiseacre 释义/词源/示例
  9. 类名引用static变量好处
  10. 视觉slam学习笔记以及课后习题《第三讲李群李代数》
  11. python generator转为list_Python中的 List Comprehension 以及 Generator
  12. 锁住余额,为何还会更新异常?
  13. Excel VBA(Visual Basic)编程入门
  14. 暴走漫画系列之高仿淘宝收货地址(附demo)
  15. 计算机科学与技术研究生课表,计算机科学与技术(一级学科)硕士研究生培养方案...
  16. c#操作.mpp文件
  17. c语言 虚拟示波器软件下载,虚拟示波器软件(示波器工具)V3.1 官方版
  18. 同事把实数作为 HashMap 的key,领导心态崩了
  19. Hinton介绍胶囊理论的论文
  20. Rademacher复杂度和VC-维

热门文章

  1. 化工原理少学时答案解析_化工原理 少学时 思考题答案
  2. android后台时不显示,Android后台下载问题
  3. 抓包mysql协议_Mysql 通信协议抓包分析
  4. 为什么非全站升级HTTPS不可?
  5. 千万千万不要运行的 Linux 命令
  6. linux应用程序接收文件,Linux应用程序学习之文件编程
  7. oracle删除后电脑卡,彻底删除oracle服务 -电脑资料
  8. ie浏览器怎样查看html,查看IE浏览器历史记录的方法
  9. java 最小堆_Java最小堆实现
  10. python登录代码思路_终于找到一个思路比较清晰的可以模拟登录百度的代码!