注意:操作符重载可以当做==“自定义类的运算”==

1 为什么需要操作符重载?
对于基础的变量,int等,不需要重载就知道如何做,但是对于自定义类,就无法进行运算,比如复数类。

2 操作符重载总结
1)操作符重载本质上是一个函数,可以采用 友元函数或者成员函数实现。但是采用这两种函数传递参数、实现代码、应用场合均不同。

全局函数与成员函数的比较:
传递参数:全局函数中不传递this指针,成员函数默认传递this指针,因此成员函数可以少一个参数;
属性访问:成员函数可以访问私有变量,全局函数需要转化为友元函数才可以。
应用场合:正常写法采用成员函数。必须采用全局函数重载的运算符有<<和>>,必须采用成员函数重载的运算符有=、()、[ ]、->四个。

2)操作符重载的格式:

#全局函数
int operator+(const A& a1, const A& a2)
#成员函数
int operator+(const A& obj)

函数名为operator与运算符的组合(可变);
输入为对象(可变,友元函数或成员函数实现);
返回值可以为元素、对象或者引用(可变)。

3)可以重载的运算符

3 实例:实现complex类的±运算符重载

注意:
1)使用友元函数重载需要注意的是,二元运算则传递两个参数,同时添加friend关键字,使用成员函数只需要一个参数。

#include <iostream>
using namespace std;class Complex
{public:Complex(int a, int b){this->a = a;this->b = b;}friend Complex operator+(const Complex& x1, const Complex& x2);void printC(){cout << "a: " << this->a << "b:" << this->b << endl;}Complex operator-(const Complex& obj){Complex tmp(this->a - obj.a, this->b - obj.b);return tmp;}
private:int a;int b;
};//友元函数重载
Complex operator+(const Complex& x1, const Complex& x2)
{Complex tmp(x1.a + x2.a, x1.b + x2.b);return tmp;
}
void main()
{Complex x1(1, 2);Complex x2(3, 4);Complex x3 = x1 + x2;x3.printC();Complex x4 = x2 - x1;x4.printC();cout << "hello,world..." << endl;system("pause");
}

4 实例:基于3实现Complex类的前置–以及后置++

注意:
1)后置++需要在参数列表中增加占位符int,Complex operator++(Complex& obj, int)。
2)后置++先使用后++,如a++,在具体实现时就要先使用临时变量tmp暂存输入,而后++,最后返回临时变量。
3)使用成员函数实现比友元函数实现少一个参数,这个参数通过this指针传递。
4)传递的变量最好在引用&前使用const,保持变量的内存空间不能改变。

#include <iostream>
using namespace std;class Complex
{public:friend Complex operator+(const Complex& x1, const Complex& x2);friend Complex operator++(Complex& obj, int);Complex(int a, int b){this->a = a;this->b = b;}void printC(){cout << "a: " << this->a << "b:" << this->b << endl;}Complex operator-(const Complex& obj)//-{Complex tmp(this->a - obj.a, this->b - obj.b);return tmp;}//成员函数实现前置--Complex& operator--(){this->a++;this->b++;return *this;}
private:int a;int b;
};Complex operator+(const Complex& x1, const Complex& x2)
{Complex tmp(x1.a + x2.a, x1.b + x2.b);return tmp;
}//友元函数实现后置++,后置需要增加占位符
Complex operator++(Complex& obj, int)
{Complex tmp = obj;//其中如果有指针,那么需要注意浅拷贝obj.a++;obj.b++;return tmp;
}
void main()
{Complex x1(1, 2);Complex x2(3, 4);Complex x3 = x1 + x2;x3.printC(); //4,6--x3;Complex x4 = x2 - x1;x4.printC();//2,2Complex x5 = x4++;x4.printC();//3,3x5.printC();//2,2cout << "hello,world..." << endl;system("pause");
}

5 实例:实现Complex左移<<和>>右移操作符重载 (二元运算符两个参数不同的情况)

注意:
1)类似<<操作符重载,其为二元运算符,两个操作数类型不同,分别为ostream和Complex(比如)。
2)实现两个操作数类型不同的运算符重载要使用友元函数。

  • 原因是,成员函数重载operator+,调用a+1时相当于调用的a.operator(1),只能保证一种参数顺序的运算,两个参数更换位置就失败,如a+1,(a为Complex),1+a就会报没有对应的运算符重载。
  • 友元函数可以通过重载友元函数来实现,只调换换参数位置即可实现。

3)要实现链式编程,返回引用。cout<<a<<endl。

#include <iostream>
using namespace std;class Complex
{public:friend ostream& operator<<(ostream& out, const Complex& obj);friend Complex operator+(const Complex& x1, int i);friend Complex operator+(int i, const Complex& x1);friend istream& operator>>(istream& in, Complex& obj);Complex(int a, int b){this->a = a;this->b = b;}void printC(){cout << "a: " << this->a << "b:" << this->b << endl;}Complex operator-(int i) //成员函数重载-{Complex tmp(this->a - i, this->b - i);return tmp;}private:int a;int b;
};Complex operator+(const Complex& x1, int i) //友元函数重载+  (1)
{Complex tmp(x1.a + i, x1.b + i);return tmp;
}
Complex operator+(int i, const Complex& x1)//友元函数重载+   (2)
{Complex tmp(x1.a + i, x1.b + i);return tmp;
}//友元函数实现重载<<左移操作符,输出,且只能采用友元函数
ostream& operator<<(ostream& out, const Complex& obj)//此处将ostream类型的out变量本身返回,以便后续的连续操作
{cout << obj.a << " + " << obj.b << "i" << endl;return out;
}#原来自己是这么实现的,但是不支持cin>>x1>>x2的链式编程的情况
// void operator>>(istream& in, Complex& obj)
// {//  in >> obj.a;
//  in >> obj.b;
// }
istream& operator>>(istream& in, Complex& obj)
{in >> obj.a;in >> obj.b;return in;
}
void main()
{Complex x1(1, 2);Complex x2(2, 3);cout << x1 + 1 << endl;cout << 1 + x1 << endl;cout << x1 - 2 << endl;cin >> x1 >> x2;cout << x1 << endl;cout << "hello,world..." << endl;system("pause");
}

6 重载=等号操作符
有指针的类定义的对象,在等号=赋值时,采用C++的赋值,进行的是浅拷贝,导致两个对象的指针指向同一个内存空间,释放的时候出现问题。

#include <iostream>
using namespace std;class Name
{public:Name(const char* p)//“asdb”{if (p == NULL){this->m_len = 0;this->m_p = new char[this->m_len + 1];strcpy(this->m_p, "");}else{this->m_len = strlen(p);this->m_p = new char[this->m_len + 1];strcpy(this->m_p, p);}}Name(const Name& obj){this->m_len = obj.m_len;this->m_p = new char[this->m_len + 1];strcpy(this->m_p, obj.m_p);}~Name(){if (this->m_len != NULL){delete[] this->m_p;this->m_p = NULL;this->m_len = 0;}}Name& operator=(const Name& obj)//重载等号操作符,实现连等,返回一个引用{if (this->m_p!=NULL) //先释放旧的指针{delete[] this->m_p;this->m_p = NULL;this->m_len = 0;}this->m_len = obj.m_len;this->m_p = new char[this->m_len + 1];strcpy(this->m_p, obj.m_p);return *this; }
protected:
private:char* m_p;int m_len;
};void main()
{Name obj("asdf");//双引号代表字符串,单引号代表字符,并且其可转化为int的ASCII码Name obj2("sdgf");Name obj3 = obj2;obj2 = obj;cout << "hello,world..." << endl;system("pause");
}

注意:
字符串传递使用双引号;
定义字符串变量或者形参,都要使用const关键字修饰;
在进行赋值时,要先释放旧的指针指向的空间,再赋值。

7 数组类案例

链接:数组类

8 字符串类案例

链接:字符串类

9 重载()操作符

重载()操作符,在定义对象后,可以使用f(),类似于f.operator()操作。这种重载和python中的__call_ _()函数很像,可以给对象传参数,输出结果。

#include <iostream>
using namespace std;
class F
{public:int operator()(int a, int b){return a + b;}
};
void main()
{F f;f(2, 4);cout << "hello,world..." << endl;system("pause");
}

10 不要重载&&以及||

作用于基础类型的&&和||有短路规则,但是经过重载后,就没有短路规则了,原因是重载是一种函数。

class Test
{public:Test(int i = 0){this->i = i;}Test&  operator+(const Test& obj){this->i = this->i + obj.i;return *this;}bool operator&&(const Test& obj){return this->i && obj.i;}int getData(){return this->i;}
private:int i;
};
void main()
{Test t1(1);Test t2(2);t1 && (t1 + t2);//重载&&cout << "hello,world..." << endl;system("pause");
}

此处重载&&,但是仍然先计算+加号重载的操作符,后计算&&重载,而不是先判断t1。

【C++】操作符重载相关推荐

  1. C++拾趣——有趣的操作符重载

    操作符重载是C++语言中一个非常有用的特性.它可以让我们比较优雅的简化代码,从而更加方便的编写逻辑. 为什么要使用操作符重载 一种常见的用法是重载<<运算符,让标准输出可以输出自定义的类型 ...

  2. 操作符重载——C/C++学习笔记

    此篇文章来自于网上,作为自己学习中的笔记,若有侵权行为,请告之,24小时之内必删除!下面就转入正题吧! 一.什么是操作符重载? 一看到重载,很容易就让人联想到成员函数重载,函数重载可以使名称相同的函数 ...

  3. C++——构造函数(拷贝构造,拷贝复制),析构函数,操作符重载

    C++--构造函数(拷贝构造,拷贝复制),析构函数,操作符重载 构造函数与析构函数:: 涉及构造函数还可以看这篇文章C++搞懂深拷贝初始化=与赋值=的区别 1.声明和定义构造函数和析构函数 构造函数在 ...

  4. 【Groovy】map 集合 ( map 集合操作符重载 | 使用 << 操作符添加一个元素 | 代码示例 )

    文章目录 一.使用 " << " 操作符添加一个元素 二.代码示例 一.使用 " << " 操作符添加一个元素 对 map 集合 使用 ...

  5. 【Groovy】map 集合 ( map 集合操作符重载 | *. 展开操作符 | 代码示例 )

    文章目录 一.map 集合 " *. " 展开操作符 二.代码示例 一.map 集合 " *. " 展开操作符 对 map 集合使用 " *. &qu ...

  6. 【Groovy】map 集合 ( map 集合操作符重载 | - 操作符重载 | 代码示例 )

    文章目录 一.map 集合 " - " 操作符重载 二.完整代码示例 一.map 集合 " - " 操作符重载 对 map 集合 使用 " - &qu ...

  7. 【Groovy】map 集合 ( map 集合操作符重载 | + 操作符重载 | 代码示例 )

    文章目录 一.map 集合 " + " 操作符重载 二.代码示例 一.map 集合 " + " 操作符重载 对 map 集合使用 " + " ...

  8. 【Groovy】集合遍历 ( 操作符重载 | 集合中的 “ << “ 操作符重载 | 使用集合中的 “ << “ 操作符添加一个元素 | 使用集合中的 “ << “ 操作符添加一个集合 )

    文章目录 一.集合中的 " << " 操作符重载 1.使用集合中的 " << " 操作符添加一个元素 2.使用集合中的 " & ...

  9. 【Groovy】集合遍历 ( 操作符重载 | 集合中的 “ + “ 操作符重载 | 集合中的 “ - “ 操作符重载 | 代码示例 )

    文章目录 一.集合中的 " + " 操作符重载 二.集合中的 " - " 操作符重载 三.完整代码示例 一.集合中的 " + " 操作符重载 ...

  10. C++中逗号操作符重载的分析

    1,关注逗号操作符重载后带来的变化: 2,逗号操作符: 1,逗号操作符(,)可以构成都好表达式:exp1, exp2, exp3, ..., expN 1,逗号表达式用于将多个表达式连接为一个表达式: ...

最新文章

  1. URAL 1055 Combinations
  2. git commit --amend 改写提交
  3. 远程连接MySQL数据库失败
  4. VTK:Rendering之FlatVersusGouraud
  5. 涡轮流量计说明书_实际应用中超声波流量计与电磁流量计哪个更好用
  6. 童程童美机器人编程上海虹口校区_呼市童程童美少儿编程学习中心
  7. 2.2 理解 mini-batch 梯度下降法
  8. 手机/邮箱等帐号判断
  9. WEB控件没有什么所谓好不好,而是用得好不好
  10. EA 反向工程 导入oracle中表结构
  11. 面试 其实就是短时间内展现出你最好的自我
  12. 数据库增删改查工具类 以及C3P0开源的JDBC连接池操作
  13. Mysql集群方案简介
  14. 翁凯java进阶_翁凯-----java课程入门与进阶1
  15. 川土微电子|数字隔离器替代光耦817
  16. 全国省市区街道区域信息 API 接口
  17. 图形库LVGL v8.2版本移植
  18. AutoCAD.NET实现CAD截图
  19. android键盘坏了怎么办,手机虚拟键盘失灵怎么办
  20. Anaconda下载安装以及Tensorflow和Pytorch的安装

热门文章

  1. 倒水问题题解(勿喷)
  2. 智能硬件产品的测试经验总结
  3. Synaptics操作指南
  4. 巨富笔记:上者劳人,中者劳智,下者劳力
  5. css鼠标滑过图标显示_CSS和jQuery教程:苹果风格的花式图标滑出导航
  6. 开发高性能的Socket服务器
  7. 字典学习中的特征选择
  8. 使用vs2010生成64位的dll文件
  9. Invoking “cmake“ failed 没有安装serial 包
  10. LAZADA上传产品,“Seller is not verified”没有通过.产品审核是什么原因?怎么办?