• 3.运算符重载


    一、操作符函数
     在C++中,编译器有能力把一个由数据、对象和操作符共同组成的表达式,解释为对一个全局或成员函数的调用。
     该全局或成员函数被称为操作符函数,通过重定义操作符函数,可以实现针对自定义类型的运算法则,并使之与内置类型一样参与各种表达式。
     
    二、双目操作符表达式
      成员函数
        形如L#R双目操作符表达式,将被编译器解释为 L.operator#(R)
        a-b+c == a.operator-(b).operator+(c)
      全局函数
        形如L#R的双目操作符表达式,将被编译器解释为 ::operator#(L,R)
        a-(b+c) == ::operator-(a,::operator+(b,c))
     
     
    三、单目操作符表达式
      成员函数
        形如#O或O#的单目操作表达式,将被编译器解释为 O.operator#(),唯一的操作数是调用对象。
      全局函数
        形如#O或O#的单目操作表达式,将被编译器解释为 ::operator#(O),唯一的操作数是调用对象。
     
     
    以下所有重载的代码实例
      1 #include <iostream>
      2 using namespace std;
      3 
      4 
      5 
      6 struct Point 
      7 {
      8     int x;
      9     int y;
     10 
     11 public:
     12     Point(int _x=0,int _y=0)
     13     {
     14         x = _x;
     15         y = _y;
     16     }
     17 
     18     Point(Point &that)
     19     {
     20         x = that.x;
     21         y = that.y;
     22     }
     23 
     24     Point &operator = (Point &that)
     25     {
     26         x = that.x;
     27         y = that.y;
     28     }
     29 
     30     void show()
     31     {
     32         cout << "x=" << x << "," << "y=" << y << endl;
     33     }
     34 
     35     Point operator - (Point &that)
     36     {
     37         Point t;
     38         t.x = x-that.x;
     39         t.y = y-that.y;
     40         return t;
     41     }
     42 
     43     Point operator +(Point &that)
     44     {
     45         Point t;
     46         t.x = x+that.x;
     47         t.y = y+that.y;
     48         return t;
     49     }
     50 
     51 /*
     52 
     53     Point& operator --(void)
     54     {
     55         --x;
     56         --y;
     57         return *this;
     58     }
     59 
     60 
     61     Point operator --(int)
     62     {
     63         Point t(*this);
     64         --x;
     65         --y;
     66         return t;
     67     }
     68 
     69 
     70 */
     71 
     72     int operator [](int index)
     73     {
     74         return !index ?x:y;
     75     }
     76 
     77 /*
     78     Point operator *(Point &that)
     79     {
     80         Point t;
     81         t.x = x*that.x;
     82         t.y = y*that.y;
     83         return t;
     84     }
     85 
     86 */
     87     friend Point operator %(Point &p1,Point &p2);
     88     friend Point operator *(Point &p1,Point &p2);
     89     friend Point &operator --(Point &p1);
     90     friend Point operator --(Point &p1,int);
     91     friend istream & operator >> (istream &is,Point &p1);
     92 
     93 
     94 };
     95 
     96 
     97 
     98 Point operator %(Point &p1,Point &p2)
     99 {
    100     Point p3(p1.x%p2.x,p1.y%p2.y);
    101     return p3;
    102 }
    103 
    104 Point operator *(Point &p1,Point &p2)
    105 {
    106     cout << "我是友元" << endl;
    107     Point p3(p1.x*p2.x,p1.y*p2.y);
    108     return p3;
    109 }
    110 
    111 
    112 Point &operator --(Point &p1)
    113 {
    114     --p1.x;
    115     --p1.y;
    116     return p1;
    117 }
    118 
    119 Point operator --(Point &p1,int)
    120 {
    121     Point t(p1);
    122     --p1.x;
    123     --p1.y;
    124     return t;
    125 }
    126 
    127 
    128 istream & operator >> (istream &is,Point &p1)
    129 {
    130     return    is >> p1.x >> p1.y;
    131 }
    132 
    133 
    134 
    135 
    136 int main()
    137 {
    138     Point p1(1,2);
    139     p1.show();
    140     Point p2(2,3);
    141     p2.show();
    142 
    143 
    144     Point p3;
    145     cin >> p3;
    146     p3.show();
    147     cout <<    p3[0] << p3[1] << endl;
    148 
    149 }
    Point重载所有运算符
     
    四、典型的双目运算符重载
     成员函数
    1  Point operator /+-*%|^& (Point& that)
    2  {
    3   Point t; // 会调用无参构造
    4   t.x = x / that.x;
    5   t.y = y / that.y;
    6   return t; // 不能返回局部对象的引用,否则会出现悬空引用
    7  }
     注意:原对象的值不变,要产生一个临时的对象
     
     1  bool operator > < >= <= == != || && (Point& that)
     2  {
     3  
     4  }
     5  
     6  Point& operator += -= *= /= (Point& that)
     7  {
     8  
     9   return *this;
    10  }
     
     注意:运算符的重载要符合情理。
     
     全局函数
     可能会访问到参数的私有成员:
      1、把成员变成公开,但会破坏类的封闭性。
      2、把全局函数声明为友元(友元不是成员),
      3、不能在友元函数中直接访问成员变量。
    1  Point operator + (Point& a,Point& b)
    2  {
    3   Point t(a.x+b.x,a.y+b.y);
    4   return t;
    5  }
     
    五、典型的单目运算符重载
     成员函数:
     前++/--
    1  Point& operator ++/-- (void)
    2  {
    3  
    4  }
     
     后++/--
    1  Point operator ++/-- (int)
    2  {
    3  
    4  }
     
     全局函数:
     前++/--
    1  Point& operator ++/-- (Point&)
    2  {
    3  
    4  }
    5  
     后++/--
    1  Point operator ++/-- (Point&,int)
    2  {
    3  
    4  }
    5  
    六、输入、输出运算符重载
     输入、输出运算符不能重载为成员函数,只能是友元。
    1  ostream& operator << (ostream& os,Point& p)
    2  {
    3  
    4  }
    5  
    6  istream& operator >> (istream& is,Point& p)
    7  {
    8  
    9  }
     
    七、特殊的运算符的重载
     
     [] 下标运算符,可以把对象当作数组来使用。
     () 函数运算符,可以把对象当作函数来使用。
     -> 成员访问运算符,可以把对象当作指针来使用。
     * 解引用运算符,可以把对象当作指针来使用。
     new/delete 也可以进行重载,但不建议使用。
      new会自动调用重载的new函数再构造函数。
      delete会先调用析构再调用重载的delete函数。
     
     只有极个别的运算符的重载对于对象来说是有意义(>>,<<)
      常考的运算符重载:前++/--,后++/--
     
    八、运算符重载的一些限制
     1、不能重载的运算符
      :: 作用域限定符
      . 成员访问运算
      .* 成员指针解引用
      ?: 三目运算符
      sizeof 字节长度运算符
      typeid 类型信息操作符
     2、运算符的重载改变不了运算符的优先级
     3、无法改变运算符的操作个数
     4、无法发明新的运算符
     5、重载运算符要注意运算符的一致性
      不要改变运算符默认的运算规则
     6、运算符的重载是为了方便使用、增强可读,不应该成功卖弄的工具。
     
     
  • 相关阅读:
    Oracle中创建视图
    SQL Server 2012 Express安装图解
    oracle学习笔记
    Oracle中视图的创建和处理方法
    DDL、DML和DCL的理解
    ROS学习--如何结合launch文件使用参数服务器
    stm32多块开发板can总线互联卡死问题
    ROS CAN总线设备接入(二)can总线数据提取和以ros topic形式发布
    ROS CAN总线设备接入(一)Linux动态库的显式调用
    ROS .so载入undefined reference to `dlopen'问题
  • 原文地址:https://www.cnblogs.com/LyndonMario/p/9524417.html
Copyright © 2020-2023  润新知