操作符重载

青旅半醒 2022-03-18 02:10 428阅读 0赞

文章目录

    • 操作符重载规则
    • 单目运算符
      • ++(左)
      • ++(右)
    • 双目操作符重载
      • + 运算符
      • +=运算符
      • <<  >> 运算符
      • = 运算符
      • 不建议重载 && 和 ||
    • ( ) 的重载
    • -> 和 * 的重载

操作符重载规则

  • 不能被重载的操作符

























符号 符号举例
. Peron.name
. Person.name=*(Person.name)
:: 作用域操作符
?: 条件操作符
  • 操作符重载不能改变操作数的个数
  • 操作符重载不改变运算顺序(依然先算 * / 后算+ -)
  • 操作符重载不改变运算的结合性
  • 操作符重载不能有默认参数
  • 操作符重载至少要有一个自定义类型
  • 操作符重载应当与原来操作符含义相似
  • 操作符重载可以是类的成员函数、类的友元函数、还可以是普通函数

单目运算符

++(左)

  • 说明: ++(左)可以进行连+

    class Point
    {
    //friend Point& operator++(Point& p);
    public:

    1. Point(int x, int y)
    2. {
    3. m_x = x;
    4. m_y = y;
    5. }
    6. Point& operator++()
    7. {
    8. ++m_x ;
    9. ++m_y ;
    10. return *this;
    11. }
    12. void Print()
    13. {
    14. cout << "(" << m_x << " " << m_y << ")" << endl;
    15. }

    private:

    1. int m_x;
    2. int m_y;

    };

    //Point& operator++(Point& p)
    //{
    // ++p.m_x;
    // ++p.m_y;

    // return p;
    //}

    int main(void)
    {

    1. Point A(1, 0);
    2. Point B(2, 2);
    3. ++++A;
    4. A.Print();//(3 2)
    5. return 0;

    }

++(右)

  • 说明:++(右)不能进行连+

    include “stdafx.h”

    include

    using namespace std;

    class Point
    {
    // friend const Point operator++(Point& p, int);
    public:

    1. Point(int x, int y)
    2. {
    3. m_x = x;
    4. m_y = y;
    5. }
    6. const Point operator++(int) //因为不能连+的,所以加个const
    7. {
    8. Point tmp = *this;
    9. m_x++;
    10. m_y++;
    11. return tmp;
    12. }
    13. void Print()
    14. {
    15. cout << "(" << m_x << " " << m_y << ")" << endl;
    16. }

    private:

    1. int m_x;
    2. int m_y;

    };

  1. //const Point operator++(Point& p, int) //返回的是临时变量,所以不能返回引用
  2. //{
  3. // Point tmp = p;
  4. // p.m_x++;
  5. // p.m_y++;
  6. // return tmp;
  7. //}
  8. int main(void)
  9. {
  10. Point A(1, 0);
  11. Point B(2, 2);
  12. A++;
  13. A.Print(); //(2 1)
  14. return 0;
  15. }

双目操作符重载

  • 重载写法两种:

    operator+(L,R) //全局
    L.operator+(R) //成员函数

+ 运算符

  • 举例:重载+操作符:将两个类相加(对应的成员变量相加)

写法1:全局函数,在类中申明为友元

  1. #include "stdafx.h"
  2. #include <iostream>
  3. using namespace std;
  4. class Point
  5. {
  6. //friend Point operator+(Point& p1, Point& p2);
  7. public:
  8. Point(int x, int y)
  9. {
  10. m_x = x;
  11. m_y = y;
  12. }
  13. Point operator+(Point& p2) //定义为成员函数,禁止返回局部变量或者它的引用
  14. {
  15. Point tmp(this->m_x + p2.m_x, this->m_y + p2.m_y);
  16. return tmp;
  17. }
  18. void Print()
  19. {
  20. cout << "(" << m_x << " " << m_y << ")" << endl;
  21. }
  22. private:
  23. int m_x;
  24. int m_y;
  25. };
  26. //Point operator+(Point& p1,Point& p2) //重载+操作符,在Point类里面申明为友元,禁止返回局部变量或者它的引用
  27. //{
  28. // Point tmp(p1.m_x + p2.m_x, p1.m_y + p2.m_y);
  29. // return tmp;
  30. //}
  31. int main(void)
  32. {
  33. Point A(1, 0);
  34. Point B(2, 2);
  35. Point C = A+B; //全局显式: operator+(A,B) //成员函数显式:A.operator+(B)
  36. C.Print();
  37. return 0;
  38. }

+=运算符

  1. #include "stdafx.h"
  2. #include <iostream>
  3. using namespace std;
  4. class Point
  5. {
  6. friend Point& operator+=(Point& p1, Point& p2); //申明全局为友元
  7. public:
  8. Point(int x, int y)
  9. {
  10. m_x = x;
  11. m_y = y;
  12. }
  13. //Point& operator+=(Point& p2) //或者申明成员函数
  14. //{
  15. // m_x += p2.m_x;
  16. // m_y += p2.m_y;
  17. // return *this;
  18. // }
  19. void Print()
  20. {
  21. cout << "(" << m_x << " " << m_y << ")" << endl;
  22. }
  23. private:
  24. int m_x;
  25. int m_y;
  26. };
  27. Point& operator+=(Point& p1, Point& p2)
  28. {
  29. p1.m_x += p2.m_x;
  30. p1.m_y += p2.m_y;
  31. return p1;
  32. }
  33. int main(void)
  34. {
  35. Point A(1, 0);
  36. Point B(2, 2);
  37. (A+=B)+=B;
  38. A.Print();
  39. return 0;
  40. }

<<  >> 运算符

  • 注意: >> 也不能写在成员函数内,只能写成全局函数

    include “stdafx.h”

    include

    include “person.h”

    using namespace std;

  1. class Point
  2. {
  3. friend ostream& operator<<(ostream& os, Point& p);
  4. public:
  5. Point(int x, int y)
  6. {
  7. m_x = x;
  8. m_y = y;
  9. }
  10. // ostream& operator<<(ostream& os) <<操作符禁止写成员函数,否则调用变成: A << cout , 改变本意
  11. // {
  12. // os << "(" << m_x << " " << m_y << ")";
  13. // return os;
  14. //}
  15. private:
  16. int m_x;
  17. int m_y;
  18. };
  19. ostream& operator<<(ostream& os, Point& p)
  20. {
  21. os << "(" << p.m_x << " " << p.m_y << ")" ;
  22. return os;
  23. }
  24. int main(void)
  25. {
  26. Point A(1, 0);
  27. Point B(2, 2);
  28. cout << A << B << endl;
  29. return 0;
  30. }
  • 注意: >>也不能写在成员函数内

    include “stdafx.h”

    include

    using namespace std;

    class Point
    {
    friend istream& operator>>(istream& is, Point& p);
    public:

    1. Point(int x, int y)
    2. {
    3. m_x = x;
    4. m_y = y;
    5. }
    6. void Print()
    7. {
    8. cout << "(" << m_x << "," << m_y << ")" << endl;
    9. }

    private:

    1. int m_x;
    2. int m_y;

    };

  1. istream& operator>>(istream& is, Point& p)
  2. {
  3. cout << "a:";
  4. is >> p.m_x;
  5. cout << "b:";
  6. is >> p.m_y;
  7. return is;
  8. }
  9. int main(void)
  10. {
  11. Point A(1, 0);
  12. Point B(2, 2);
  13. cin >> A >> B;
  14. A.Print();
  15. B.Print();
  16. return 0;
  17. }

= 运算符

  1. #include "stdafx.h"
  2. #include <iostream>
  3. #include <string.h>
  4. using namespace std;
  5. class Student
  6. {
  7. public:
  8. Student() //无参构造
  9. {
  10. m_id = 0;
  11. m_name = NULL;
  12. }
  13. Student(int id, const char name[]) //有参构造
  14. {
  15. m_id = id;
  16. int length = strlen(name);
  17. m_name = new char[length + 1];
  18. strcpy_s(m_name,length+1,name);
  19. }
  20. Student(const Student& another) //拷贝构造
  21. {
  22. m_id = another.m_id;
  23. int length = strlen(another.m_name);
  24. m_name = new char[length + 1];
  25. strcpy_s(m_name, length + 1, another.m_name);
  26. }
  27. Student& operator=(const Student& another) //=操作符重载,三件事
  28. {
  29. if(this==&another) return *this;//1. 防止自身赋值
  30. m_id = another.m_id;
  31. if (m_name != NULL) //2. 判断是否为空,不为空,先释放
  32. {
  33. delete[]m_name;
  34. m_name = NULL;
  35. }
  36. int length = strlen(another.m_name); //3. 开辟内存
  37. m_name = new char[length + 1];
  38. strcpy_s(m_name, length + 1, another.m_name);
  39. return *this;
  40. }
  41. void Print()
  42. {
  43. cout << m_name << ": " << m_id << endl;
  44. }
  45. ~Student()
  46. {
  47. if (m_name != NULL)
  48. {
  49. delete[] m_name;
  50. m_name = NULL;
  51. }
  52. }
  53. private:
  54. int m_id;
  55. char* m_name;
  56. };
  57. int main(void)
  58. {
  59. Student A (1, "julian");
  60. Student B (2, "mark");
  61. Student C (3, "kerr");
  62. C =A =B;
  63. C.Print(); //mark: 2
  64. return 0;
  65. }

不建议重载 && 和 ||

  • 在已有的运算结构中 &&和 || 都有短路现象:if(a&&(a=1)) 如果a是0,那么后面(a=1)应该不执行,结果还是0,但是当你重载&&的时候: object.operator&&(t1), t1作为参数传进去,肯定是执行的,所以不会发生短路现象,但是有时候需要重载又不关心短路现象的时候可以进行重载

( ) 的重载

  • 重载()叫做仿函数,调用形式和函数类似

    class Sqr
    {
    public:

    1. Sqr(int a)
    2. {
    3. this->a = a;
    4. }
    5. //想把s对象 定义成一个 带有一个参数的函数, 求出平方返回
    6. //此函数功能就是 对a求平方
    7. int operator()(int a)
    8. {
    9. return a*a; //这个a和成员变量无关
    10. }

    private:

    1. int a;

    };

  1. int main()
  2. {
  3. Sqr A(3); //定义Sqr的对象A
  4. A(2); //求2的平方,返回4
  5. }

-> 和 * 的重载

参考智能指针章节

发表评论

表情:
评论列表 (有 0 条评论,428人围观)

还没有评论,来说两句吧...

相关阅读

    相关 C++ 操作符重载

    可以重定义或重载大部分 C++ 内置的运算符。这样,就能使用自定义类型的运算符。 先在类中定义一个操作符重载 class Test3 { publi

    相关 C++操作符重载

    又看了一遍操作符的东西,感觉之前对操作符的理解还停留在很浅的认知上(仅仅会用哈哈),所以做一下笔记来加深一下印象。 文章目录 一、为什么会有操作符重载

    相关 C++中操作符重载

    一、操作符重载属于什么? 在本文开始阐述之前,首先明确,操作符重载是一个具有特殊名的“ 函数 ”。 既然作为函数,那么,就具有函数的特性,一是形参表,二是返回值。 关键字