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. java中的ThreadLocal-learning

    为什么需要ThreadLocal 多个线程对一个变量进行写入的时候,为了保证线程安全,一般使用者在访问共享变量的时候需要进行额外的同步措施才能保证线程安全性. 而线程安全是指 当多个线程访问某个方法时 ...

  2. thrift源码分析

    1 前言 学习thrift源码主要为了弄清楚几个问题 thrift客户端和服务端的通信流程是如何的 thrift的IDL中给属性加上编号的作用是什么 thrift中require.optional和默 ...

  3. 客户端回调 Watcher ?

    客户端 SendThread 线程接收事件通知,交由 EventThread 线程回调 Watcher. 客户端的 Watcher 机制同样是一次性的,一旦被触发后,该 Watcher 就失效了.

  4. NULL 是什么意思 ?

    NULL 这个值表示 UNKNOWN(未知):它不表示""(空字符串).对 NULL 这 个值的任何比较都会生产一个 NULL 值.您不能把任何值与一个 NULL 值进行比 较,并 ...

  5. spring aop 源码解读之我见

    spring aop 都是动态代理,分为jdk代理和cglib代理.默认的情况下,如果类有实现了接口,使用jdk代理.如果没有实现接口,则使用cglib代理.在下面的代码中,我会标明对应的这段代码. ...

  6. list集合的快速筛选条件方法

    List<String> list = new ArrayList<>();list.add("张无忌");list.add("周芷若" ...

  7. 单总线协议DS1820代码

    单总线协议DS1820代码 一.DS18B20初始化 (1).数据线拉到低电平"0". (2).延时480微妙(该时间的时间范围可以从480到960微妙). (3).数据线拉到高电 ...

  8. Python中对象、类型、元类之间的关系

    Python里的对象.类型和元类的关系很微妙也很有意思. 1989年圣诞节期间,上帝很无聊,于是创造了一个世界. 对象 在这个世界的运转有几条定律. 1.一切都是对象 对象(object)是这个世界的 ...

  9. Hadoop搭建高可用的HA集群

    一.工具准备 1.7台虚拟机(至少需要3台),本次搭建以7台为例,配好ip,关闭防火墙,修改主机名和IP的映射关系(/etc/hosts),关闭防火墙 2.安装JDK,配置环境变量 二.集群规划: 集 ...

  10. JavaScript操作checkbox复选框

    运行效果: 源代码: 1 <!DOCTYPE html> 2 <html lang="zh"> 3 <head> 4 <meta char ...