01 运算符重载的需求

C++ 预定义的运算符,只能用于基本数据类型的运算:整型、实型、字符型、逻辑型等等,且不能用于对象的运算。但是我们有时候又很需要在对象之间能用运算符,那么这时我们就要重载运算符,使得运算符能用于对象之间的运算。

比如,在数学上,两个复数可以直接进行+、-等运算,但在C++中,直接将+或-用于复数对象是不允许的。有时会希望,让对象也能通过运算符进行运算。这样代码就更简洁,也容易理解。

例如:

complex_a 和 complex_b 是两个复数对象,求两个复数的和,希望的能直接写成:complex_a + complex_b

这时我们就需要对 + 号运算符进行重载。


02 运算符重载的形式

运算符重载的实质就是函数重载,可以重载为普通函数,也可以重载为成员函数。运算符重载的基本形式如下:

返回值类型 operator 运算符(形参表)
{
...
}

下面举个例子,实现对复数对象的 +- 运算符重载:

class Complex // 复数类
{
public:
// 构造函数,如果不传参数,默认把实部和虚部初始化为0
Complex(double r = 0.0, double i = 0.0):m_real(r),m_imag(i) { } // 重载-号运算符,属于成员函数
Complex operator-(const Complex & c)
{
// 返回一个临时对象
return Complex(m_real - c.m_real, m_imag - c.m_imag);
} // 打印复数
void PrintComplex()
{
cout << m_real << "," << m_imag << endl;
} // 将重载+号的普通函数,定义成友元函数
// 目的是为了友元函数能访问对象的私有成员
friend Complex operator+(const Complex &a, const Complex &b); private:
double m_real; // 实部的值
double m_imag; // 虚部的值
}; // 重载+号运算符,属于普通函数,不是对象的成员函数
Complex operator+(const Complex &a, const Complex &b)
{
// 返回一个临时对象
return Complex(a.m_real + b.m_real, a.m_imag + b.m_imag);
} int main()
{
Complex a(2,2);
Complex b(1,1);
Complex c; c = a + b; // 等价于c = operator+(a,b)
c.PrintComplex(); c = a - b; // 等价于 c = a.operator-(b)
c.PrintComplex(); return 0;
}

输出结果:

3,3
1,1

从上面的例子中,我们可以知道重载为成员函数和普通函数的区别了:

  • 重载为成员函数时,参数个数为运算符目数减一。如:c = a - b; 等价于 c = a.operator-(b)
  • 重载为普通函数时,参数个数为运算符目数。如:c = a + b; 等价于c = operator+(a,b)

在上面的代码中,我把重载 + 号运算符的普通函数,在Complex复数类中定义成了友元函数,目的是为了友元函数能访问对象的私有成员,否则会编译报错。


03 +号和-号重载函数的返回值和参数表

这里还有个值得思考的问题:

  • 为什么重载-号和+号运算符函数的返回类型是Complex对象而不是Complex &呢?
  • 为什么重载-号和+号的运算符函数的参数表是const Complex & c常引用类型而不是Complex c呢?
// 重载-号运算符,属于成员函数
Complex Complex::operator-(const Complex & c)
{
// 返回一个临时对象
return Complex(m_real - c.m_real, m_imag - c.m_imag);
}

首先先说一下参数表为什么是const Complex & c常引用类型,首先如果参数表如果普通的对象形式Complex c,那么在入参的时候,就会调用默认的赋值(拷贝)构造函数,产生了一个临时对象,这会增大开销,所以就采用引用的方式,同时又为了防止引用的对象被修改,所以就定义成了const Complex & c常引用类型。

再来说一下返回值为什么是普通Complex对象,因为本次 - 号和 + 号运算符的函数执行之后,需要返回一个新的对象给到左值。


C++ 运算符重载的基本概念的更多相关文章

  1. C++学习26 运算符重载的概念和语法

    所谓重载,就是赋予新的含义.函数重载(Function Overloading)可以让一个函数名有多种功能,在不同情况下进行不同的操作.运算符重载(Operator Overloading)也是一个道 ...

  2. C++学习之路—运算符重载(一)概念、方法及规则

    (根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 1    什么是运算符重载 先来说下什么是重载吧 ...

  3. PoEduo - C++阶段班【Po学校】-Lesson03-5_运算符重载- 第7天

    PoEduo - Lesson03-5_运算符重载- 第7天 复习前面的知识点 空类会自动生成哪些默认函数 6个默认函数    1  构造  2  析构   3  赋值  4 拷贝构造  5 oper ...

  4. C++中的运算符重载

    首先思考以下几个问题: 1.什么是运算符重载? 2.为什么要重载运算符,它有什么用? 3.可以重载哪些运算符? 4.重载运算符有哪些规则? 一.基本概念 我们在程序中使用各种操作符,比如加(+).赋值 ...

  5. C++学习笔记之运算符重载

    一.运算符重载基本知识 在前面的一篇博文 C++学习笔记之模板(1)——从函数重载到函数模板 中,介绍了函数重载的概念,定义及用法,函数重载(也被称之为函数多态)就是使用户能够定义多个名称相同但特征标 ...

  6. swift:高级运算符(位运算符、溢出运算符、优先级和结合性、运算符重载函数)

    swift:高级运算符 http://www.cocoachina.com/ios/20140612/8794.html 除了基本操作符中所讲的运算符,Swift还有许多复杂的高级运算符,包括了C语和 ...

  7. C++之------运算符重载

    ①  什么是运算符重载? 何为C++的运算符重载呢? 其实就是运算符给它重新赋予新的含义或者多重含义.让它有另外一种新的功能. 为什么需要运算符重载? 面向对象中为了实现类的多态性,我们就引用了运算符 ...

  8. 04737_C++程序设计_第9章_运算符重载及流类库

    例9.1 完整实现str类的例子. #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> ...

  9. C++_基础_运算符重载2

    内容: (1)只能用成员形式重载的运算符 (2)new/delete操作符的重载 (3)封装和继承的初识 (4)继承的特性 (5)子类及其函数的特性 (6)多重继承和虚继承 1.只能用成员形式重载的运 ...

随机推荐

  1. zabbix 分布式监控及优化

    1..zabbix分布式监控,模拟多机房实现监控? 1.有多机房时,需要用到proxy 1.网络不通 2.网络延迟 2.当监控的主机较多时,也可以用proxy来缓解压力 1.安装proxy [root ...

  2. http请求post,文件导出兼容IE10+

    1.post的方法里要加responseType: 'blob'参数,不然下载的excel会乱码 2.使用{type: "application/vnd.ms-excel"}的写法 ...

  3. ie11 SCRIPT5011:不能执行已释放Script的代码

    依照我遇到的问题为例: (我的页面结构为:父页面中嵌套有iframe子页面) 1.造成这种情况的原因是:父页面初始化声明变量a为数组(数组对象是引用类型,赋值传递的是地址),创建iframe子页面后给 ...

  4. Android 亮度调节功能开发思路整理

    做 Android 音视频播放器开发的时候,我们基本都会遇到一类需求:音量 & 亮度 调节.其中做亮度调节功能的时候,发现还是有一定复杂度的. Android亮度调节分为两个类,分别是: An ...

  5. Playbook剧本小结

    1.Playbook剧本小结 1.什么是playbook,playbook翻译过来就是"剧本",那playbook组成如下 play: 定义的是主机的角色task: 定义的是具体执 ...

  6. Linux:VIM编辑器的使用

    打开vim编辑器 命令格式: vim 文件路径 vim编辑器的工作模式 进入编辑器后 默认为命令模式 进入输入模式 a 在光标后插入 o 换行插入 i 在光标前插入 返回命令模式 esc 键 进入末行 ...

  7. python redis的连接及相关操作

    1.redis连接.及存取值 import redis r = redis.Redis(host='192.168.2.22',port=6379,db=2,password= 'redis') r. ...

  8. AtCoder Regular Contest 99

    传送门 C - Minimization 第一次可能有多种选择,我们枚举所有的选择,然后两边贪心取即可. Code #include <bits/stdc++.h> #define MP ...

  9. MVC、MTV、FBV、CBV、母版和继承:

    cookie session cookie的定义: 保存在浏览器上的一组组键值对 (请求头) 为什么要有? http协议是无状态,每次的请求之间是相互独立的,没有办法保存状态. Django中操作co ...

  10. plsql查询数据显示为乱码解决方案

    1.首先安装plsql之后连接数据库,发现使用sql查询出来的中文数据是??,即乱码.原因,因为数据库的编码与本地的编码不一致,plsql默认加载的是本机win10的编码. 2.解决办法: 参数如下: ...