C++黑马程序员——P121-123. + << ++运算符重载
- P121. 类和对象——C++运算符重载——加号运算符重载
- P122. 类和对象——C++运算符重载——左移运算符重载
- P123. 类和对象——C++运算符重载——递增运算符重载
- P121. 加号运算符重载
运算符重载概念:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型
加号运算符重载 作用:实现两个自定义数据类型相加的运算
通过全局函数重载+号:
1 //加号运算符重载
2 class Person
3 {
4 public:
5 int m_a;
6 int m_b;
7 };
8
9 //2. 通过全局函数重载+号
10 Person operator+(Person& p1, Person& p2)
11 {
12 Person temp;
13 temp.m_a = p1.m_a + p2.m_a;
14 temp.m_b = p1.m_b + p2.m_b;
15 return temp;
16 }
17
18 //函数重载
19 Person operator+(Person& p1, int a)
20 {
21 Person temp;
22 temp.m_a = p1.m_a + a;
23 temp.m_b = p1.m_b + a;
24 return temp;
25 }
26
27 void test01()
28 {
29 Person p1;
30 p1.m_a = 10;
31 p1.m_b = 10;
32 Person p2;
33 p2.m_a = 10;
34 p2.m_b = 10;
35 38 //全局函数重载的本质调用
39 //Person p3 = operator+(p1, p2);
40 //成员函数重载+运算符 和 全局函数重载+运算符 都可以简化成 Person p3 = p1 + p2;
41 Person p3 = p1 + p2;
42 //运算符重载也可以发生函数重载(函数名相同,参数不同)
43 Person p4 = p1 + 100;
44
45 cout << "p3.m_a = " << p3.m_a << endl;
46 cout << "p3.m_b = " << p3.m_b << endl;
47
48 cout << "p4.m_a = " << p4.m_a << endl;
49 cout << "p4.m_b = " << p4.m_b << endl;
50 }
51
52 int main()
53 {
54 test01();
55 return 0;
56 }
运行结果:
通过成员函数重载+号:
1 class Person
2 {
3 public:
4 //通过成员函数重载+号
5 Person operator+(Person& p)
6 {
7 Person temp;
8 temp.m_a = this->m_a + p.m_a;
9 temp.m_b = this->m_b + p.m_b;
10 return temp;
11 }
12 int m_a;
13 int m_b;
14 };
15
16 //成员函数重载的本质调用
17 //Person p3 = p1.operator+(p2); 参考上面的test01()函数
对于内置的数据类型的表达式的运算符是不可能改变的
- P122. 左移运算符重载
左移运算符:<<
作用:可以输出自定义数据类型
1 //左移运算符重载
2 class Person
3 {
4 public:
5 //如果利用成员函数重载<<运算符:
6 //void operator<<(cout)
7 //{
8 // ...
9 //}
10 //p.operator<<(cout) 简化版本是 p<<cout,而我们想要的效果是 cout<<p
11 //所以不利用成员函数重载<<运算符,因为无法实现 cout 在左侧
12 int m_A;
13 int m_B;
14 };
15
16 //只能利用全局函数重载左移运算符
17 ostream& operator<<(ostream& cout, Person& p) //本质 operator<<(cout,p) 简化为 cout<<p
18 {
19 cout << "m_A = " << p.m_A << " m_B = " << p.m_B;
20 return cout;
21 } //返回 cout 是为了链式编程(cout<<...<<...),如果返回值为void或其他,则cout之后只能使用一次<<,连续使用就会报错
22
23 void test01()
24 {
25 Person p;
26 p.m_A = 10;
27 p.m_B = 10;
28
29 cout << p.m_A << endl;
30 cout << p << endl;
31 }
32
33 int main()
34 {
35 test01();
36 return 0;
37 }
运行结果:
- P123. 递增运算符重载
(这节自己有疑问,没彻底搞懂)
(《C++程序设计基础(上)》p201:自增和自减运算符有前置和后置两种形态。...C++规定,前置形式重载为一元运算符函数,后置形式重载为二元运算符函数)
前置自增表达式:
++Aobject
若用成员函数重载,则编译器解释为:
Aobject.operator++()
若用友元函数重载,则编译器解释为:
operator++(Aobject)
后置自增表达式:
Aobject++
成员函数的重载解释为:
Aobject.operator++(int)
友元函数的重载解释为:
operator(Aobject,int)
递增运算符:++
作用:通过重载递增运算符,实现自己的整型数据
1 //重载递增++运算符
2 //自定义整型
3 class MyInteger
4 {
5 friend ostream& operator<<(ostream& cout, MyInteger myint);
6 public:
7 MyInteger()
8 {
9 m_Num = 0;
10 }
11 //重载++运算符:分为两种:前置递增,后置递增
12 //重载前置++ 返回引用为了一直对一个数据进行递增操作
13 MyInteger& operator++()
14 {
15 //先递增
16 m_Num++;
17 //再返回
18 return *this;
19 } //我自己的疑问:为什么这样写重载是前置递增呢?按照前两节的内容,调用这个函数的本质不是 p.operator++ 吗?然后简化成 p++,那怎么就变成 ++p 了呢?
20 //重载后置++
21 //operator++(int) int代表占位参数 可以用于区分前置和后置递增
22 //后置递增返回的是值,前置递增返回的是引用
23 //为什么后置递增返回的是值不是引用:temp是局部变量,函数运行完就被释放了,如果返回的是引用,在调用完函数之后再进行后续操作就是非法的
24 MyInteger operator++(int)
25 {
26 //先记录结果
27 MyInteger temp = *this;
28 //后递增
29 m_Num++;
30 //最后将记录结果返回
31 return temp;
32 }
33 private:
34 int m_Num;
35 };
36
37 //重载左移运算符
38 ostream& operator<<(ostream& cout, MyInteger myint)
39 {
40 cout << "myint.m_Num = " << myint.m_Num;
41 return cout;
42 }
43
44 void test01()
45 {
46 MyInteger myint;
47 cout << ++(++myint) << endl;
48 cout << myint << endl;
49 }
50
51 void test02()
52 {
53 MyInteger myint2;
54 cout << myint2++ << endl;
55 cout << myint2 << endl;
56 }
57
58 int main()
59 {
60 test01();
61 test02();
62 return 0;
63 }
运行结果:
前置递增返回引用,后置递增返回值
(〃>_<;〃)(〃>_<;〃)(〃>_<;〃)