• 【第四天]C++高级类和对象:运算符重载、string类和智能指针的深度解析


     

    目录

    一、运算符重载 

    1、可以重载的运算符

    2、重载<<运算符(全局函数实现) 

    3、重载输入>>运算符 

     4、重载加法运算符+(全局函数实现)

    5、重载加法运算符+(成员函数实现 推荐)

    6、重载==运算符(成员函数实现 )

    7、重载++运算符

    (1)重载后置++

    (2)重载前置++

    8、重载函数调用运算符()

    二、string类

    三、智能指针


    一、运算符重载 

            运算符重载 是对已有的运算符 指定新功能,不能创建新运算符。

    运算符重载关键字operator

    语法:operator@        (@表示被重载的运算符)

    思路:

    1、弄懂 函数的参数中参数个数取决于运算符是一元还是二元

    2、弄懂运算符左边的运算对象 是类的对象 还是其他.

            类的对象:全局函数实现(一元是一个参数,二元是两个参数)

                              成员函数实现(一元没有参数,二元是一个参数)--推荐

            其他:只能是全局函数实现 

    1、可以重载的运算符

    2、重载<<运算符(全局函数实现) 

    3、重载输入>>运算符 

     4、重载加法运算符+(全局函数实现)

    1. #include<iostream>
    2. #include<string>
    3. using namespace std;
    4. class Person
    5. {
    6. friend ostream& operator<<(ostream& out, Person ob);
    7. friend istream& operator>>(istream &in, Person &ob);
    8. friend Person operator+(Person ob1, Person ob2);
    9. private:
    10. int num;
    11. string name;
    12. float score;
    13. public:
    14. Person() {}
    15. Person(int num, string name, float score) :num(num), name(name), score(score) {}//初始化列表
    16. };
    17. ostream& operator<<(ostream& out, Person ob)
    18. {
    19. out << ob.num << " " << ob.name << " " << ob.score << endl;
    20. return out;
    21. }
    22. istream& operator>>(istream &in, Person &ob)
    23. {
    24. in >> ob.num >> ob.name >> ob.score;
    25. return in;
    26. }
    27. Person operator+(Person ob1, Person ob2)
    28. {
    29. Person tmp;
    30. tmp.num = ob1.num + ob2.num;
    31. tmp.name = ob1.name + ob2.name;
    32. tmp.score = ob1.score + ob2.score;
    33. return tmp;
    34. }
    35. int main(int argc, char* argv[])
    36. {
    37. Person lucy(100, "lucy", 85.5f);
    38. Person bob(101, "bob", 95.5f);
    39. Person tom(102, "tom", 75.5f);
    40. cout << lucy + bob + tom << endl;
    41. return 0;
    42. }

    5、重载加法运算符+(成员函数实现 推荐)

    1. #include<iostream>
    2. #include<string>
    3. using namespace std;
    4. class Person
    5. {
    6. friend ostream& operator<<(ostream& out, Person ob);
    7. friend istream& operator>>(istream &in, Person &ob);
    8. private:
    9. int num;
    10. string name;
    11. float score;
    12. public:
    13. Person() {}
    14. Person(int num, string name, float score) :num(num), name(name), score(score) {}//初始化列表
    15. //成员函数重载+
    16. Person operator+(Person ob)
    17. {
    18. Person tmp;
    19. tmp.num = this-> num + ob.num;
    20. tmp.name = this-> name + ob.name;
    21. tmp.score = this-> score + ob.score;
    22. return tmp;
    23. }
    24. };
    25. ostream& operator<<(ostream& out, Person ob)
    26. {
    27. out << ob.num << " " << ob.name << " " << ob.score << endl;
    28. return out;
    29. }
    30. istream& operator>>(istream &in, Person &ob)
    31. {
    32. in >> ob.num >> ob.name >> ob.score;
    33. return in;
    34. }
    35. int main(int argc, char* argv[])
    36. {
    37. Person lucy(100, "lucy", 85.5f);
    38. Person bob(101, "bob", 95.5f);
    39. Person tom(102, "tom", 75.5f);
    40. cout << lucy + bob + tom << endl;
    41. return 0;
    42. }

    6、重载==运算符(成员函数实现 )

    1. #include<iostream>
    2. #include<string>
    3. using namespace std;
    4. class Person
    5. {
    6. friend ostream& operator<<(ostream& out, Person ob);
    7. friend istream& operator>>(istream &in, Person &ob);
    8. private:
    9. int num;
    10. string name;
    11. float score;
    12. public:
    13. Person() {}
    14. Person(int num, string name, float score) :num(num), name(name), score(score) {}//初始化列表
    15. //成员函数重载==
    16. bool operator==(Person& ob)
    17. {
    18. if (num == ob.num && name == ob.name && score == ob.score)
    19. return true;
    20. return false;
    21. }
    22. };
    23. ostream& operator<<(ostream& out, Person ob)
    24. {
    25. out << ob.num << " " << ob.name << " " << ob.score << endl;
    26. return out;
    27. }
    28. istream& operator>>(istream &in, Person &ob)
    29. {
    30. in >> ob.num >> ob.name >> ob.score;
    31. return in;
    32. }
    33. int main(int argc, char* argv[])
    34. {
    35. Person lucy(100, "lucy", 85.5f);
    36. Person bob(101, "bob", 95.5f);
    37. if (lucy == bob)
    38. {
    39. cout << "相等" << endl;
    40. }
    41. else
    42. {
    43. cout << "不相等" << endl;
    44. }
    45. return 0;
    46. }

    7、重载++运算符

    (1)重载后置++

    ++a(前置++),它就调用operator++(a)

    a++(后置++),它就会去调用operator++(a,int)//int为占位参数。

    1. #include<iostream>
    2. #include<string>
    3. using namespace std;
    4. class Person
    5. {
    6. friend ostream& operator<<(ostream& out, Person ob);
    7. friend istream& operator>>(istream &in, Person &ob);
    8. private:
    9. int num;
    10. string name;
    11. float score;
    12. public:
    13. Person() {}
    14. Person(int num, string name, float score) :num(num), name(name), score(score) {}//初始化列表
    15. //重载后置++ 普通全局函数为operator++(a,int)
    16. //成员函数
    17. Person operator++(int)
    18. {
    19. //先保存 旧的值
    20. Person old = *this;//*this == lucy
    21. //lucy++自增
    22. this-> num = this-> num + 1;
    23. this-> name = this-> name + this-> name;//(自定义操作)
    24. this-> score = this-> score + 1;
    25. return old;//返回旧值
    26. }
    27. };
    28. ostream& operator<<(ostream& out, Person ob)
    29. {
    30. out << ob.num << " " << ob.name << " " << ob.score << endl;
    31. return out;
    32. }
    33. istream& operator>>(istream &in, Person &ob)
    34. {
    35. in >> ob.num >> ob.name >> ob.score;
    36. return in;
    37. }
    38. int main(int argc, char* argv[])
    39. {
    40. Person lucy(100, "lucy", 85.5f);
    41. Person bob;
    42. //先使用 后++
    43. bob = lucy++;
    44. cout << bob << endl;
    45. cout << lucy << endl;
    46. return 0;
    47. }

    (2)重载前置++

    1. #include<iostream>
    2. #include<string>
    3. using namespace std;
    4. class Person
    5. {
    6. friend ostream& operator<<(ostream& out, Person ob);
    7. friend istream& operator>>(istream &in, Person &ob);
    8. private:
    9. int num;
    10. string name;
    11. float score;
    12. public:
    13. Person() {}
    14. Person(int num, string name, float score) :num(num), name(name), score(score) {}//初始化列表
    15. //重载后置++ 普通全局函数为operator++(a,int)
    16. //成员函数
    17. Person operator++(int)
    18. {
    19. //先保存 旧的值
    20. Person old = *this;//*this == lucy
    21. //lucy++自增
    22. this-> num = this-> num + 1;
    23. this-> name = this-> name + this-> name;//(自定义操作)
    24. this-> score = this-> score + 1;
    25. return old;//返回旧值
    26. }
    27. //重载前置++ 普通全局函数为operator++(a)
    28. //成员函数
    29. Person operator++(int)
    30. {
    31. //++
    32. this-> num = this-> num + 1;
    33. this-> name = this-> name + this-> name;//(自定义操作)
    34. this-> score = this-> score + 1;
    35. //后使用
    36. return *this;
    37. }
    38. };
    39. ostream& operator<<(ostream& out, Person ob)
    40. {
    41. out << ob.num << " " << ob.name << " " << ob.score << endl;
    42. return out;
    43. }
    44. istream& operator>>(istream &in, Person &ob)
    45. {
    46. in >> ob.num >> ob.name >> ob.score;
    47. return in;
    48. }
    49. int main(int argc, char* argv[])
    50. {
    51. Person lucy(100, "lucy", 85.5f);
    52. Person bob;
    53. ///++ 后使用
    54. bob = ++lucy;
    55. cout << bob << endl;
    56. cout << lucy << endl;
    57. return 0;
    58. }

    8、重载函数调用运算符()

            重载()运算符 一般用于 为算法 提供策略。

    二、string类

            string类完成重载输入输出、重载中括号运算符、重载+运算符、重载=赋值运算符(深拷贝)、重载>运算符等运算

    mystring.h

    1. #ifndef MYSTRING_H
    2. #define MYSTRING_H
    3. #include <iostream>
    4. using namespace std;
    5. class MyString
    6. {
    7. friend ostream& operator<<(ostream &out, MyString ob);
    8. friend istream& operator>>(istream &in, MyString &ob);
    9. private:
    10. char *str;
    11. int size;
    12. public:
    13. MyString();
    14. MyString(char *str);
    15. MyString(const MyString &ob);//构造拷贝
    16. ~MyString();
    17. int getSize() const;
    18. //成员函数重载[]
    19. char& operator[](int pos);
    20. MyString operator+(MyString ob);
    21. MyString operator+(char *str);
    22. MyString& operator=(MyString ob);
    23. MyString& operator=(char *str);
    24. bool operator>(MyString ob);
    25. bool operator>(char *str);
    26. // bool operator<(MyString ob);
    27. // bool operator<(char *str);
    28. // bool operator==(MyString ob);
    29. // bool operator==(char *str);
    30. // bool operator!=(MyString ob);
    31. // bool operator!=(char *str);
    32. };
    33. #endif // MYSTRING_H

    mystring.cpp

    1. #include "mystring.h"
    2. #include <string.h>
    3. int MyString::getSize() const
    4. {
    5. return size;
    6. }
    7. char& MyString::operator[](int pos)
    8. {
    9. if(pos<0 || pos>=size)
    10. {
    11. cout<<"元素位置不合法"<<endl;
    12. exit(‐1);
    13. }
    14. return str[pos];
    15. }
    16. MyString MyString::operator+(MyString ob)
    17. {
    18. MyString tmp;
    19. tmp.size = size+ob.size;
    20. tmp.str = new char[tmp.size+1];
    21. memset(tmp.str, 0, tmp.size+1);
    22. strcpy(tmp.str, str);
    23. strcat(tmp.str, ob.str);
    24. return tmp;
    25. }
    26. MyString MyString::operator+(char *str)
    27. {
    28. MyString tmp;
    29. tmp.size = size+strlen(str);
    30. tmp.str = new char[tmp.size+1];
    31. memset(tmp.str, 0, tmp.size+1);
    32. strcpy(tmp.str, this‐>str);
    33. strcat(tmp.str, str);
    34. return tmp;
    35. }
    36. MyString &MyString::operator=(MyString ob)
    37. {
    38. //str2 = str1;
    39. if(this‐>str != NULL)
    40. {
    41. delete [] this‐>str;
    42. this‐>str = NULL;
    43. }
    44. this‐>size = ob.size;
    45. this‐>str = new char[this‐>size+1];
    46. memset(this‐>str, 0, this‐>size+1);
    47. strcpy(this‐>str, ob.str);
    48. return *this;
    49. }
    50. MyString &MyString::operator=(char *str)
    51. {
    52. //str2 = str1;
    53. if(this‐>str != NULL)
    54. {
    55. delete [] this‐>str;
    56. this‐>str = NULL;
    57. }
    58. this‐>size = strlen(str);
    59. this‐>str = new char[this‐>size+1];
    60. memset(this‐>str, 0, this‐>size+1);
    61. strcpy(this‐>str, str);
    62. return *this;
    63. }
    64. bool MyString::operator>(MyString ob)
    65. {
    66. if(str==NULL || ob.str == NULL)
    67. {
    68. exit(‐1);
    69. }
    70. if(strcmp(this‐>str, ob.str) > 0)
    71. {
    72. return true;
    73. }
    74. return false;
    75. }
    76. bool MyString::operator>(char *str)
    77. {
    78. if(this‐>str==NULL || str == NULL)
    79. {
    80. exit(‐1);
    81. }
    82. if(strcmp(this‐>str, str) > 0)
    83. {
    84. return true;
    85. }
    86. return false;
    87. }
    88. MyString::MyString()
    89. {
    90. str=NULL;
    91. size=0;
    92. }
    93. myString::MyString(char *str)
    94. {
    95. size = strlen(str);
    96. this‐>str = new char[size+1];
    97. memset(this‐>str, 0, size+1);
    98. strcpy(this‐>str, str);
    99. }
    100. MyString::MyString(const MyString &ob)
    101. {
    102. size = ob.size;
    103. str = new char[size+1];
    104. memset(str, 0, size+1);
    105. strcpy(str, ob.str);
    106. }
    107. myString::~MyString()
    108. {
    109. if(str != NULL)
    110. {
    111. delete [] str;
    112. str=NULL;
    113. }
    114. }
    115. //全局函数实现 <<重载
    116. ostream& operator<<(ostream &out, MyString ob)
    117. {
    118. out<<ob.str;
    119. return out;
    120. }
    121. //全局函数实现 >>重载
    122. istream& operator>>(istream &in, MyString &ob)
    123. {
    124. char buf[1024]="";
    125. cin>>buf;
    126. if(ob.str != NULL)//ob已经有字符串
    127. {
    128. delete [] ob.str;
    129. ob.str = NULL;
    130. }
    131. ob.size = strlen(buf);
    132. ob.str = new char[ob.size+1];
    133. memset(ob.str, 0,ob.size+1);
    134. strcpy(ob.str, buf);
    135. return in;
    136. }

    三、智能指针

            智能指针:通过重载* 和->运算符。解决 堆区空间的对象 释放问题

    1. class Data
    2. {
    3. public:
    4. Data()
    5. {
    6. cout<<"无参构造"<<endl;
    7. }
    8. ~Data()
    9. {
    10. cout<<"析构函数"<<endl;
    11. }
    12. void func()
    13. {
    14. cout<<"func函数"<<endl;
    15. }
    16. };
    17. class SmartPointer//智能指针类
    18. {
    19. private:
    20. Data *p;
    21. public:
    22. SmartPointer(){}
    23. SmartPointer(Data *p)
    24. {
    25. this‐>p = p;
    26. }
    27. ~SmartPointer()
    28. {
    29. delete p;
    30. }
    31. //重载*和->
    32. Data& operator*()
    33. {
    34. return *p;
    35. }
    36. Data* operator‐>()
    37. {
    38. return p;
    39. }
    40. };
    41. void test02()
    42. {
    43. SmartPointer ob(new Data);
    44. (*ob).func();//ob.operator *().func();
    45. ob‐>func();//ob.operator ‐>()‐>func();
    46. }

  • 相关阅读:
    谷歌上架,账号被封,怎么判断是账号还是代码/包的问题?
    使用VsCode调试UE5的PuerTs(实践测试来啦)
    Spring事务隔离级别
    【RabbitMQ】——主题模式(Topics)
    数据结构与算法之美学习笔记:29 | 堆的应用:如何快速获取到Top 10最热门的搜索关键词?
    【MySQL基础】如何安装MySQL?如何将MySQL设置成服务?
    OneFlow源码解析:Eager模式下的SBP Signature推导
    c语言如何设置随机数
    校园网免认证登录的方法-利用udp53端口
    selenium 等待方式
  • 原文地址:https://blog.csdn.net/m0_75045191/article/details/132204323