摘要:运算符能给程序员提供一种书写数学公式的感觉,本质上运算符也是一种函数,因此有类内部运算符和全局运算符之分,通过重载,运算符的“动作”更加有针对性,编写代码更像写英文文章。

1、C++标准允许将运算符重载为类成员或者全局的,一般如果是全局的话,为了效率,都是把它们定义为类友元函数。

 1 /*
 2 ** 重载全局运算符“+”、“-”,代码如下:
 3 */
 4 #include <iostream>
 5
 6 using namespace std;
 7
 8 //class Complex;
 9 //Complex operator+(const Complex &c1, const Complex &c2);
10 //Complex operator-(const Complex &c1, const Complex &c2);
11 // 我的疑问:声明为全局的有什么好处的,或者说有什么必要的么?
12 class Complex
13 {
14 public:
15     Complex(double real = 0.0, double image = 0.0)
16     {
17         this->real = real;
18         this->image = image;
19     }
20 public:
21     void displayComplex()
22     {
23         if(image >= 0)
24             cout << "(" << real << '+' << image << 'i' << ")";
25         else
26             cout << "(" << real << image << 'i' << ")";
27     }
28     friend Complex operator+(const Complex &c1, const Complex &c2);
29     friend Complex operator-(const Complex &c1, const Complex &c2);
30 private:
31     double real;
32     double image;
33 };
34
35 Complex operator+(const Complex &c1, const Complex &c2)
36 {
37     Complex complexTemp;
38     complexTemp.real = c1.real + c2.real;
39     complexTemp.image = c1.image + c2.image;
40     return complexTemp;
41 }
42 Complex operator-(const Complex &c1, const Complex &c2)
43 {
44     Complex complexTemp;
45     complexTemp.real = c1.real - c2.real;
46     complexTemp.image = c1.image - c2.image;
47     return complexTemp;
48 }
49 int main()
50 {
51     Complex c, c1(1.1, 2.2), c2(3.3, 4.4);
52     c = c1 + c2;
53     c = c1 - c2; // operator-(c1, c2);
54     c1.displayComplex();
55     cout << "-";
56     c2.displayComplex();
57     cout << "=";
58     c.displayComplex();
59     cout << endl;
60
61     int i;
62     cin >> i;
63     return 0;
64 }

重载为友元函数

2、运算符重载的一些基本规则:

禁止用户发明C++语言运算符之外的其他运算符

不要试图改变重载运算符的语义,保持重载后的运算语义与内置运算符语义一致,否则会带来思维上的混乱

不能重载.、.*、::、?:

不能重载#、##

不能重载sizeof()、typeid()

不能重载static_cast<>、dynamic_cast<>、const_cast<>、reinterpret_cast<>

3、运算符重载时,它的返回值类型会有程序运行效率和使用重载运算符方便程度的差别

当返回值为对象时,拷贝构造函数会构建一个临时对象

当返回值为对象引用时,不会引起构造函数的调用,其返回值可以作为左值

当返回值为对象指针时,不会引发构造函数的调用,其返回值可以作为左值

 1 /*
 2 ** 重载运算符,返回不同类型的差别
 3 */
 4 #include <iostream>
 5
 6 using namespace std;
 7
 8 class Complex
 9 {
10 public:
11     Complex(double real = 0.0, double image = 0.0)
12     {
13         this->real = real;
14         this->image = image;
15     }
16     Complex(const Complex &c) // 拷贝构造函数
17     {
18         real = c.real;
19         image = c.image;
20         cout << "copy constructing..." << endl;
21     }
22 public:
23     Complex operator+(const Complex &c)
24     {
25         Complex complexTemp;
26         complexTemp.real = real + c.real;
27         complexTemp.image = image + c.image;
28         return complexTemp; // 此时会调用拷贝构造函数,构造一个临时对象
29     }
30     Complex& operator-(const Complex &c)
31     {
32         real -= c.real;
33         image -= c.image;
34         return *this;
35     }
36     void displayComplex()
37     {
38         if(image >= 0)
39             cout << "(" << real << "+" << image << "i" << ")";
40         else
41             cout << "(" << real << image << "i" << ")";
42     }
43 private:
44     double real;
45     double image;
46 };
47 int main()
48 {
49     Complex c, c1(1.1, 2.2), c2(3.3, 4.4);
50     (c1 + c2).displayComplex();
51     cout << "Before c1 - c2" << endl;
52     c1.displayComplex();
53     cout << endl;
54     cout << "After c1 - c2" << endl;
55     (c1 - c2).displayComplex();
56     cout << endl;
57     int i;
58     cin >> i;
59     return 0;
60 }

重载返回值不同类型的差别

4、运算符重载示例:

赋值运算符

 1 /*
 2 ** 赋值运算符“=”重载
 3 */
 4 #include <iostream>
 5 #include <cstring>
 6
 7 using namespace std;
 8
 9 class Student
10 {
11 public:
12     Student(char *name = "")
13     {
14         pName = new char[strlen(name) + 1];
15         strcpy(pName, name);
16     }
17     ~Student()
18     {
19         delete pName;
20         pName = NULL;
21     }
22 public:
23     Student &operator=(const Student &student)
24     {
25         cout << "assignment called..." << endl;
26         // 若为同一个对象则直接返回即可
27         if(this == &student) // 注意这里需要用指针比较,因为没有实现对象比较的运算符呢
28         {
29             cout<< "\tExact the same object." << endl;
30             return *this;
31         }
32         delete pName; // 否则,先释放资源
33         pName = new char[strlen(student.pName) + 1];
34         strcpy(pName, student.pName);
35         return *this;
36     }
37     void show()
38     {
39         cout << pName << endl;
40     }
41 private:
42     char *pName;
43 };
44
45 int main()
46 {
47     Student s1, s2("zhangsan");
48     s1 = s1;
49
50     s1 = s2;
51     s1.show();
52
53     int i;
54     cin >> i;
55     return 0;
56 }

赋值运算符重载示例

函数符

 1 /*
 2 ** 函数符“()”重载
 3 */
 4 #include <iostream>
 5
 6 using namespace std;
 7
 8 class Student
 9 {
10 public:
11     Student(int chinese, int math, int english)
12     {
13         this->chinese = chinese;
14         this->math = math;
15         this->english = english;
16     }
17     ~Student()
18     { }
19 public:
20     void operator()(int index = 0)
21     {
22         switch(index)
23         {
24         case 0:
25             cout << "chinese:" << chinese << endl;
26             break;
27         case 1:
28             cout << "math:" << math << endl;
29             break;
30         case 2:
31             cout << "english:" << math << endl;
32             break;
33         default:
34             cout << "not found" << endl;
35         }
36     }
37 private:
38     int chinese;
39     int math;
40     int english;
41 };
42 int main()
43 {
44     Student student(80, 90, 92);
45     student();
46     student(0);
47     student(1);
48     student(2);
49     student(3);
50     student(4);
51
52     int i;
53     cin >> i;
54     return 0;
55 }

函数调用符重载示例

下标运算

 1 /*
 2 ** 下表运算符“[]”重载
 3 */
 4 #include <iostream>
 5
 6 using namespace std;
 7
 8 class UserString
 9 {
10 public:
11     UserString(char *str)
12     {
13         len = strlen(str);
14         this->str = new char[len + 1];
15         strcpy(this->str, str);
16     }
17     ~UserString()
18     {
19         delete str;
20         str = NULL;
21     }
22 public:
23     char operator[](int index)
24     {
25         if(index >= 0 && index < len) // 判断越界
26             return str[index];
27         else
28         {
29             cout << "beyond scope..." << endl;
30             return ' ';
31         }
32     }
33     int getLength()
34     {
35         return len;
36     }
37 private:
38     char *str;
39     int len;
40 };
41
42 int main()
43 {
44     UserString us("zhangsan");
45     cout << "\"zhangsan\" length:" << us.getLength() << endl;
46     int length = us.getLength();
47     int i;
48     for(i = 0;i < length;i++)
49         cout << us[i]; // 使用[]访问
50     cout << endl;
51     cout << us[i];
52
53     cin >> i;
54     return 0;
55 }

下表运算符重载示例

运算符++、--

 1 /*
 2 ** 运算符“++、--”重载
 3 */
 4 #include <iostream>
 5
 6 using namespace std;
 7
 8 class Integer
 9 {
10 public:
11     Integer(int data)
12     {
13         this->data = data;
14     }
15     Integer(const Integer &i)
16     {
17         this->data = i.data;
18     }
19     ~Integer()
20     { }
21 public:
22     Integer operator++(int)
23     {
24         Integer temp(*this);
25         data++;
26         return temp;
27     }
28     Integer operator++()
29     {
30         data++;
31         return *this;
32     }
33     void show()
34     {
35         cout << data << endl;
36     }
37 private:
38     int data;
39 };
40
41 int main()
42 {
43     Integer x(1);
44     (x++).show();
45     (++x).show();
46
47     int i;
48     cin >> i;
49     return 0;
50 }

++、--运算符重载示例

类型转换

 1 /*
 2 ** 类型转换运算符重载,从对象到内置类型
 3 */
 4 #include <iostream>
 5
 6 using namespace std;
 7
 8 class Complex
 9 {
10 public:
11     Complex(double real, double image)
12     {
13         this->real = real;
14         this->image = image;
15     }
16 public:
17     operator double()
18     {
19         return real;
20     }
21 private:
22     double real;
23     double image;
24 };
25
26 int main()
27 {
28     double d = 1.1;
29     Complex c(4.0, 5.0);
30
31     d += c; // 此时c.operator double()返回4.0
32     cout << d << endl;
33
34     int i;
35     cin >> i;
36     return 0;
37 }

类型转换-从对象到内置类型

 1 /*
 2 ** 类型转换运算符重载,从内置类型到对象
 3 */
 4 #include <iostream>
 5
 6 using namespace std;
 7
 8 class Complex
 9 {
10 public:
11     Complex(double real, double image)
12     {
13         this->real = real;
14         this->image = image;
15     }
16     Complex(const Complex &c)
17     {
18         real = c.real;
19         image = c.image;
20         cout << "copy constructor called..." << endl;
21     }
22     Complex(double real)
23     {
24         this->real = real;
25         this->image = 0;
26         cout << "one parameter called..." << endl;
27     }
28     ~Complex()
29     {}
30 public:
31     Complex& operator+=(const Complex &c)
32     {
33         real += c.real;
34         image += c.image;
35         cout << "overload operator+= called..." << endl;
36         return *this;
37     }
38     void show()
39     {
40         cout << real;
41         if(image >= 0)
42             cout << "+" << image << "i" << endl;
43         else
44             cout << image << "i" << endl;
45     }
46 private:
47     double real;
48     double image;
49 };
50
51 int main()
52 {
53     Complex c1(0, 1.1);
54     c1 += 3.3;
55     c1.show();
56
57     int i;
58     cin >> i;
59     return 0;
60 }

类型转换-从内置类型到对象

5、运算符重载规则

运算符 规则
所有单目运算符 建议重载为非static成员函数
=、()、[]、->、* 建议重载为非static成员函数
+=、-=、/=、*=、&=、|=、~=、%=、>>=、<<= 建议重载为非static成员函数
所有其他运算符 建议重载为全局函数或类的友元函数

C++面向对象程序设计的一些知识点(5)相关推荐

  1. 《面向对象程序设计R19》 知识点

    第3章 Java的基本语法元素 考点:标识符.关键字.注释.基本数据类型.常量与变量.运算符和表达式 1.标识符的命名规范.满足的条件 -- 由字母.下划线_.美元符号$.数字组成 关键字不能作为标识 ...

  2. 谭浩强《C++面向对象程序设计》知识点总结

    1 C++初步知识 1.1 C++的输入输出 输入:采用标准输入流对象istream和提取运算符cin>> 输出:采用标准输出流对象ostream和插入运算符cout<< 1. ...

  3. java面向对象程序设计第三版耿祥义pdf_java基础知识干货——封装

    很多java初学者,在学到Java面向对象方面的知识点的时候,会觉得这块的知识点真的蛮绕的,一个知识点一个知识点的往外冒,对于初学者来说区分构造器和方法就花费了一整天的时间.现在小编带大家重新过一遍知 ...

  4. java红牛农场答案_Java面向对象程序设计实验指导与习题解答(21世纪高等学校计算机专业实用规划教材)...

    导语 <Java面向对象程序设计实验指导与习题解答>是<Java面向对象程序设计>(作者耿祥义,清华大学出版社出版,2010)的配套实验指导和习题解答,目的是通过一系列实验练习 ...

  5. 201771010112罗松《面向对象程序设计(java)》第三周学习总结

    实验三  Java基本程序设计 201771010112  罗松 1.实验目的与要求 (1)进一步掌握Eclipse集成开发环境下java程序开发基本步骤: (2)熟悉PTA平台线上测试环境: (3) ...

  6. 程序设计语言基础-知识点

    程序设计语言基础-知识点 程序设计语言就是人类跟计算机沟通的语言 分类 1.高级低级之分 高级 c/c++,java 等 低级 机器语言 汇编等 2.工作方式之分 编译程序:编译成目标程序后再执行.c ...

  7. 分数计算器java报告_20182307 2019-2020-1 《数据结构与面向对象程序设计》实验四报告...

    20182307 2019-2020-1 <数据结构与面向对象程序设计>实验四报告 课程:<程序设计与数据结构> 班级: 1823 姓名: 陆彦杰 学号:20182307 实验 ...

  8. 201871010134-周英杰《面向对象程序设计(Java)》第四周学习总结

    201871010134-周英杰<面向对象程序设计(Java)>第四周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这 ...

  9. 红牛农场java代码_Java面向对象程序设计实验指导模板代码(171页)-原创力文档...

    PAGE 1 PAGE 24 Java面向对象程序设计实验指导代码 内容简介 本书是<Java面向对象程序设计>的配套实验指导和习题解答.本书的第一部分为16次上机实践的内容,每次上机实践 ...

最新文章

  1. 庆祝一下,基于JXTA的P2P文件共享传输文件测试成功。
  2. jQuery获取Select选择的Text和 Value
  3. 外星人计算机产品介绍,你对外星人电脑了解吗?感兴趣快看看!
  4. 台湾大学林轩田机器学习技法课程学习笔记15 -- Matrix Factorization
  5. HDFS设计思路,HDFS使用,查看集群状态,HDFS,HDFS上传文件,HDFS下载文件,yarn web管理界面信息查看,运行一个mapreduce程序,mapreduce的demo
  6. 我们凭什么相信 5G 很安全?
  7. mysql联合索引顺序调整_MySQL 关于联合索引的字段顺序规则讨论
  8. C++:38---final关键字和禁止类继承
  9. oracle查询语句大全(oracle 基本命令大全一)
  10. 菜鸟进阶必修课-主板插线小百科(图)
  11. CPython对象模型:基础
  12. cocos2d-x 学习笔记——瓦片地图TiledMap
  13. oracle数据库管理和日常维护,oracle数据库管理与维护
  14. 个人笔记-C#txt文本分割器
  15. 联想集团“2022年及未来10大科技趋势”预测
  16. BAT文件中如何注释
  17. 互联网产品的前世今生
  18. JAVAFX的table样式修改
  19. gimp 抠图_GMIC(gimp 快速抠图)V1.5.2.4 免费版
  20. 腾讯产品策划运营类笔经(带题目)

热门文章

  1. 华为代码质量军规 (1) 数组访问,必须进行越界保护
  2. Ubuntu16 安装Jira
  3. 构建之法 学习笔记06
  4. C语言设计ATM存取款界面
  5. 清除 Xcode 项目缓存
  6. int数组,找小于右边所有数,大于左边所有数的数
  7. Struts2升级注意事项
  8. Design Pattern - Adapter Pattern
  9. 29 个你必须知道的 Linux 命令
  10. 十大开源安卓应用程序的开发框架