5. 运算符重载

5.1  加号运算符重载

 1 #include<iostream>
2 using namespace std;
3
4 // 加号运算符重载
5
6 class Person {
7 public:
8 //1. 成员函数重载“+”
9 Person operator+(Person& p) {
10 Person temp;
11 temp.m_A = this->m_A + p.m_A;
12 temp.m_B = this->m_B + p.m_B;
13 return temp;
14 }
15
16 int m_A;
17 int m_B;
18 };
19
20 //2. 全局函数重载“+”
21 Person operator+(Person& p1, Person& p2) {
22 Person temp;
23 temp.m_A = p1.m_A + p2.m_A;
24 temp.m_B = p2.m_B + p2.m_B;
25 return temp;
26 }
27
28 void test01() {
29 Person p1;
30 p1.m_A = 10;
31 p1.m_B = 20;
32
33 Person p2;
34 p2.m_A = 10;
35 p2.m_B = 20;
36
37 Person p3 = p1 + p2;
38
39 cout << "p1 + p1:" << p3.m_A << " " << p3.m_B << endl;
40
41 }
42
43 int main() {
44
45 test01();
46
47 system("pause");
48
49 return 0;
50 }
51
52
53 // 总结
54 // 对已有的运算符进行重新定义。赋予其另一种功能,以适应不同的数据类型
55 // 运算符重载也可以发生函数重载

5.2 左移运算符重载

 1 #include<iostream>
2 using namespace std;
3
4
5 class Person {
6 friend ostream& operator<<(ostream& cout, Person& p);
7 public:
8 Person(int a, int b) {
9 m_A = a;
10 m_B = b;
11 }
12 public:
13
14 //1. 利用成员函数重载“左移”运算符
15 // p.operator << (cout) 简化版本 p << cout
16 // 不会利用成员函数重载<<运算符,因为无法实现<<在左侧
17 // 故不能使用成员函数的方法!!
18
19 //int m_A; // public属性,可以类外访问
20 //int m_B;
21
22 private:
23 int m_A; //如果是私有属性,可以通过friend方法解决
24 int m_B;
25 };
26
27 //2. 利用全局函数重载“左移<<”运算符
28 ostream& operator<<(ostream& cout, Person &p) { // 本质 operator << (cout, p) 简化 cout << p
29 // cout的数据类型是ostream,可以转到定义去查看
30 cout << "m_A = " << p.m_A << " m_B = " << p.m_B;
31 return cout; //链式编程思想,返回值类型为ostream
32 }
33
34 void test01() {
35 Person p(10, 20);
36 //p.m_A = 10;
37 //p.m_B = 10;
38
39 cout << p << endl;;
40 }
41
42 int main() {
43
44 test01();
45
46 system("pause");
47
48 return 0;
49 }

5.3 递增运算符重载

 1 #include<iostream>
2 using namespace std;
3
4 // 递增(递减)运算符重载
5
6 class MyInteger {
7 friend ostream& operator<<(ostream& cout, MyInteger myint);
8 public:
9 MyInteger() {
10 m_Num = 0;
11 }
12
13 // 重载前置++运算符
14 // 返回引用是为了一直对一个数据进行递增操作
15 MyInteger& operator++() {
16 // 先进行++运算
17 m_Num++;
18
19 //再将自身返回
20 return *this;
21 }
22
23 // 重载后置++运算符, int代表占位参数,区分前置与后置递增
24 // 后置递增返回值,不能返回引用,因为是个局部变量,不能返回局部变量的引用
25 MyInteger operator++(int) {
26 // 先记录当时结果
27 MyInteger temp = *this;
28
29 // 后 递增操作
30 m_Num++;
31 // 最后,将记录的结果返回
32
33 return temp;
34 }
35
36 private:
37 int m_Num;
38
39 };
40
41 // 全局函数实现“<<”运算符重载
42 ostream& operator<<(ostream& cout, MyInteger myint) {
43 cout << myint.m_Num;
44 return cout;
45
46 }
47
48 void test01() {
49
50 MyInteger myint;
51
52 cout << ++myint << endl;
53
54 }
55
56 void test02() {
57 MyInteger myint;
58
59 cout << myint++ << endl;
60 cout << myint << endl;
61
62 }
63
64 int main() {
65
66 //test01();
67 test02();
68
69 system("pause");
70
71 return 0;
72 }

5.4 赋值运算符重载

 1 #include<iostream>
2 using namespace std;
3
4 // 赋值运算符重载
5 class Person {
6 public:
7 Person(int age) {
8 m_Age = new int(age);
9 }
10
11 //重载 赋值运算符
12 Person& operator=(Person &p) {
13 //编译器提供的是如下的浅拷贝
14 // m_Age = p.m_Age;
15
16 //首先应该判断是否存在有属性在堆区,如果有,要先释放干啥,然后进行深拷贝
17 if (m_Age != NULL) {
18 delete m_Age;
19 m_Age = NULL;
20 }
21
22 // 然后进行深拷贝操作
23 m_Age = new int(*p.m_Age);
24
25 // 要返回对象本身
26 return *this;
27
28 }
29
30 ~Person() {
31 if (m_Age != NULL) {
32 delete m_Age;
33 m_Age = NULL;
34 }
35 }
36
37 int* m_Age;
38 };
39
40
41
42 void test01() {
43 Person p1(18);
44
45 Person p2(20);
46
47 Person p3(30);
48
49 p2 = p1; // 赋值运算操作
50
51 p3 = p2 = p1; //注意返回值类型
52
53 cout << "p1的年龄为:" << *p1.m_Age << endl;
54 cout << "p2的年龄为:" << *p2.m_Age << endl;
55 cout << "p3的年龄为:" << *p3.m_Age << endl;
56 }
57
58 int main() {
59
60 test01();
61
62 system("pause");
63
64 return 0;
65 }
66
67 // 总结
68 // C++默认给一个类添加4个函数
69 // 默认构造,默认析构函数
70 // 默认拷贝(对属性进行值拷贝)
71 //
72 // 赋值运算符operator=对属性进行值拷贝
73 //
74 // 如果有属性指向堆区,做赋值操作时会出现深浅拷贝的问题
75 // 如果出现堆区数据,要通过深拷贝方法解决
76 //

5.5 关系运算符重载

 1 #include<iostream>
2 using namespace std;
3
4 // 关系运算符重载
5 // 可以让自定义的两个类型对象进行对比操作
6
7 class Person {
8 public:
9 Person(string m_Name, int age) {
10 m_Age = age;
11 m_Name = m_Name;
12 }
13
14 //重载 == 号
15 bool operator==(Person& p) {
16 if (this->m_Name == p.m_Name && this->m_Age == p.m_Age) {
17 return true;
18 }
19 return false;
20 }
21
22 string m_Name;
23 int m_Age;
24
25 };
26
27 void test01() {
28 Person p1("Tom", 18);
29
30 Person p2("Tom", 18);
31
32 if (p1 == p2) {
33 cout << "p1和p2是相等的!" << endl;
34
35 }
36
37 }
38
39 int main() {
40
41 test01();
42
43 system("pause");
44
45 return 0;
46 }

5.6 函数调用运算符重载

 1 #include<iostream>
2 using namespace std;
3 #include<string>
4
5
6 // 函数调用()运算符重载
7 // 由于重载后使用的方式非常想函数的调用,因此也成为“仿函数”
8 // 仿函数没有固定写法,非常的灵活
9
10 class MyPrint {
11 public:
12 void operator()(string text) {
13 cout << text << endl;
14
15 }
16 };
17
18 class Myadd {
19 public:
20 int operator()(int a, int b) {
21 return a + b;
22 }
23 };
24
25 void test01() {
26 // 重载的 () 操作符 也称为仿函数
27 MyPrint myfunc;
28 myfunc("hello world");
29
30 // 匿名函数对象
31 cout << Myadd()(10, 20) << endl;
32
33 }
34
35 int main() {
36
37 test01();
38
39 system("pause");
40
41 return 0;
42 }

参考《黑马程序员》C++教程

C++基础-5-运算符重载(加号,左移,递增,赋值,关系,函数调用)的更多相关文章

  1. C++学习6-面向对象编程基础(运算符重载、类的派生与继承、命名空间)

    运算符重载 重载的运算符是具有特殊名字的函数:它们的名字由关键字operator和其后要定义的运算符号共同组成.重载的运算符是遵循函数重载的选择原则,根据不同类型或不同参数来选择不同的重载运算符. 运 ...

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

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

  3. C++_基础_运算符重载

    内容: (1)输入输出运算符重载 (2)友元类和友元函数 (3)双目运算符重载 (4)单目运算符重载 (5)不能被重载的运算符 (6)只能定义为成员形式的运算符 1.输入输出运算符重载如: int n ...

  4. C++语言基础(17)-运算符重载

    运算符重载的格式为: 返回值类型 operator 运算符名称 (形参表列){ //TODO: } 一.在类里面实例运行符重载 #include <iostream> using name ...

  5. C++学习(12)—— 运算符重载

    运算符重载概念:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型 1.加号运算符重载 作用:实现两个自定义数据类型相加的运算 #include <iostream> #i ...

  6. C++之运算符重载(1)

    在前一节中曾提到过,C++中运行时的多态性主要是通过虚函数来实现的,而编译时的多态性是由函数重载和运算符重载来实现的.这一系列我将主要讲解C++中有关运算符重载方面的内容.在每一个系列讲解之前,都会有 ...

  7. [转]C++之运算符重载(1)

    在前一节中曾提到过,C++中运行时的多态性主要是通过虚函数来实现的,而编译时的多态性是由函数重载和运算符重载来实现的.这一系列我将主要讲解C++中有关运算符重载方面的内容.在每一个系列讲解之前,都会有 ...

  8. C/C++编程笔记:C++入门知识丨运算符重载

    本篇要学习的内容和知识结构概览 运算符重载使用场景 常规赋值操作 我们现在有一个类 想要实现这种赋值操作 具体实现如下: 所以说呢,我们在使用运算符进行运算的时候, 实际上也是通过函数来实现运算的. ...

  9. 《挑战30天C++入门极限》C++运算符重载函数基础及其值返回状态

        C++运算符重载函数基础及其值返回状态 运算符重载是C++的重要组成部分,它可以让程序更加的简单易懂,简单的运算符使用可以使复杂函数的理解更直观. 对于普通对象来说我们很自然的会频繁使用算数运 ...

随机推荐

  1. 为什么redis 需要把所有数据放到内存中?

    答:Redis 为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数 据写入磁盘.所以 redis 具有快速和数据持久化的特征.如果不将数据放在内存中, 磁盘 I/O 速度为严重影响 red ...

  2. EMQX_AUTH_USERNAME 使用

    emqx_auth_username 它通过比对每个终端的接入的 username 和 password 与 EMQ X 中存储的是否一致来实现终端接入的控制.其功能逻辑如下: emqx_auth_u ...

  3. session与cookie的区别? 如果客户端禁止 cookie session 还能用吗?

    一.session与cookie的区别 session:Session 是存放在服务器端的,类似于Session结构来存放用户数据,当浏览器 第一次发送请求时,服务器自动生成了一个Session和一个 ...

  4. 学习MFS(六)

    一.文件系统选型 在一般的生产环境中,NFS共享存储算是比较常用的,简单.方便,但随着业务的不断扩展,数据量也是承爆发式的增长,因而对存储这些数据的文件系统要求也越来越高了,分存式.可扩展.大容量,这 ...

  5. Python中的numpy库介绍!

    转自:https://blog.csdn.net/codedz/article/details/82869370 机器学习算法中大部分都是调用Numpy库来完成基础数值计算的.安装方法: pip3 i ...

  6. c++中的左值和右值的理解

    1.左值和右值的概念 C++中左值(lvalue)和右值(rvalue)是比较基础的概念,虽然平常几乎用不到,但C++11之后变得十分重要,它是理解 move/forward 等新语义的基础. 左值与 ...

  7. css3中什么时候用transition什么时候用animation实现动画

    在css3中transition和animation都可以实现动画效果,但是我们什么时候用transition,什么时候用animation. 当有事件触发动画的时候我们就用transition.比如 ...

  8. 有关placeholder在ie9中的一点折腾

    有关placeholder在ie9中的一点折腾. placeholder属性定义: placeholder 属性规定可描述输入字段预期值的简短的提示信息(比如:一个样本值或者预期格式的短描述). 问题 ...

  9. 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)

    概述 最近,有客户向我们请求开发一个前端下拉控件,需求是显示了一个列表,其中包含可由用户单独选择的项目控件,该控件将在下拉列表中显示多选TreeView(树形图). 如今WijmoJS已经实现了该控件 ...

  10. 前端每日实战:116# 视频演示如何用 CSS 和原生 JS 开发一个监控网络连接状态的页面

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/oPjWvw 可交互视频 此视频是可 ...