zoukankan      html  css  js  c++  java
  • C++ 运算符重载

    C++ 运算符重载

    什么是运算符的重载?

             运算符与类结合,产生新的含义。 

    为什么要引入运算符重载?

             作用:为了实现类的多态性(多态是指一个函数名有多种含义)

    怎么实现运算符的重载?

    方式:类的成员函数友元函数(类外的普通函数)

    规则:不能重载的运算符有 .   .* ?: ::  sizeof

    友元函数和成员函数的使用场合:一般情况下,建议一元运算符使用成员函数,二元运算符使用友元函数

            1、运算符的操作需要修改类对象的状态,则使用成员函数。如需要做左值操作数的运算符(如=+=++

            2、运算时,有数和对象的混合运算时,必须使用友元

            3、二元运算符中,第一个操作数为非对象时,必须使用友元函数。如输入输出运算符<<>>

    具体规则如下:

    运算符

    建议使用

    所有一元运算符

    成员函数

    ( ) [ ]  ->

    必须是成员函数

    += -= /= *= ^= &= != %= >>= <<= , 似乎带等号的都在这里了.

    成员函数

    所有其它二元运算符, 例如: –,+,*,/

    友元函数

    << >>

    必须是友元函数

    2. 参数和返回值

         当参数不会被改变,一般按const引用来传递(若是使用成员函数重载,函数也为const).

         对于返回数值的决定:

         1) 如果返回值可能出现在=号左边, 则只能作为左值, 返回非const引用。

         2) 如果返回值只能出现在=号右边, 则只需作为右值, 返回const型引用或者const型值。

         3) 如果返回值既可能出现在=号左边或者右边, 则其返回值须作为左值, 返回非const引用。

    运算符重载举例:

    + -运算符的重载:

    1.  class Point    

    2.  {    

    3.  private:    

    4.      int x;   

    5.  public:    

    6.      Point(int x1)  

    7.      {   x=x1;}    

    8.      Point(Point& p)     

    9.      {   x=p.x;}  

    10.     const Point operator+(const Point& p);//使用成员函数重载加号运算符  

    11.     friend const Point operator-(const Point& p1,const Point& p2);//使用友元函数重载减号运算符  

    12. };    

    13.   

    14. const Point Point::operator+(const Point& p)  

    15. {  

    16.     return Point(x+p.x);  

    17. }  

    18.   

    19. Point const operator-(const Point& p1,const Point& p2)  

    20. {  

    21.     return Point(p1.x-p2.x);  

    22. }  

    class Point 

    private: 

      int x;

    public: 

      Point(int x1)

      {    x=x1;} 

      Point(Point& p)  

      {    x=p.x;}

      const Point operator+(const Point& p);//使用成员函数重载加号运算符

      friend const Point operator-(const Point& p1,const Point& p2);//使用友元函数重载减号运算符

    }; 

     

    const Point Point::operator+(const Point& p)

    {

      return Point(x+p.x);

    }

     

    Point const operator-(const Point& p1,const Point& p2)

    {

      return Point(p1.x-p2.x);

    }

    调用:

    1.  Point a(1);    

    2.  Point b(2);  

    3.  a+b;  //正确,调用成员函数  

    4.  a-b;  //正确,调用友元函数  

    5.  a+1;  //正确,先调用类型转换函数,把1变成对象,之后调用成员函数  

    6.  a-1;  //正确,先调用类型转换函数,把1变成对象,之后调用友元函数  

    7.  1+a;  //错误,调用成员函数时,第一个操作数必须是对象,因为第一个操作数还有调用成员函数的功能  

    8.  1-a;  //正确,先类型转换 后调用友元函数  

    Point a(1); 

    Point b(2);

    a+b;  //正确,调用成员函数

    a-b;  //正确,调用友元函数

    a+1;  //正确,先调用类型转换函数,把1变成对象,之后调用成员函数

    a-1;  //正确,先调用类型转换函数,把1变成对象,之后调用友元函数

    1+a;  //错误,调用成员函数时,第一个操作数必须是对象,因为第一个操作数还有调用成员函数的功能

    1-a;  //正确,先类型转换 后调用友元函数

    总结:

    1、由于+ -都是出现在=号的右边,如c=a+b,即会返回一个右值,可以返回const型值
    2
    、后几个表达式讨论的就是,数和对象混合运算符的情况,一般出现这种情况,常使用友元函数

    3双目运算符的重载:

          重载运算符函数名:operator@(参数表)

          隐式调用形式:obj1+obj2

          显式调用形式:obj1.operator+(OBJ obj2)---成员函数

                                      operator+(OBJ obj1OBJ obj2)---友元函数

          执行时,隐式调用形式和显式调用形式都会调用函数operator+()

    ++--运算符的重载:

    1.  class Point    

    2.  {    

    3.  private:    

    4.      int x;   

    5.  public:    

    6.      Point(int x1)  

    7.      {   x=x1;}    

    8.      Point operator++();//成员函数定义自增  

    9.      const Point operator++(int x); //后缀可以返回一个const类型的值  

    10.     friend Point operator--(Point& p);//友元函数定义--   

    11.     friend const Point operator--(Point& p,int x);//后缀可以返回一个const类型的值  

    12. };    

    13.   

    14. Point Point::operator++()//++obj   

    15. {  

    16.     x++;  

    17.     return *this;  

    18. }  

    19. const Point Point::operator++(int x)//obj++   

    20. {  

    21.     Point temp = *this;  

    22.     this->x++;  

    23.     return temp;  

    24. }  

    25. Point operator--(Point& p)//--obj   

    26. {  

    27.     p.x--;  

    28.     return p;  

    29.          //前缀形式(--obj)重载的时候没有虚参,通过引用返回*this  自身引用,也就是返回变化之后的数值  

    30. }  

    31. const Point operator--(Point& p,int x)//obj--   

    32. {  

    33.     Point temp = p;  

    34.     p.x--;  

    35.     return temp;  

    36.          // 后缀形式obj--重载的时候有一个int类型的虚参返回原状态的拷贝  

    37. }  

    class Point 

    private: 

      int x;

    public: 

      Point(int x1)

      {    x=x1;} 

      Point operator++();//成员函数定义自增

      const Point operator++(int x); //后缀可以返回一个const类型的值

      friend Point operator--(Point& p);//友元函数定义--

      friend const Point operator--(Point& p,int x);//后缀可以返回一个const类型的值

    }; 

     

    Point Point::operator++()//++obj

    {

      x++;

      return *this;

    }

    const Point Point::operator++(int x)//obj++

    {

      Point temp = *this;

      this->x++;

      return temp;

    }

    Point operator--(Point& p)//--obj

    {

      p.x--;

      return p;

             //前缀形式(--obj)重载的时候没有虚参,通过引用返回*this 或 自身引用,也就是返回变化之后的数值

    }

    const Point operator--(Point& p,int x)//obj--

    {

      Point temp = p;

      p.x--;

      return temp;

             // 后缀形式obj--重载的时候有一个int类型的虚参, 返回原状态的拷贝

    }

    函数调用:

    1.  <PRE class=cpp name="code">Point a(1);  

    2.  Point b(2);  

    3.  a++;//隐式调用成员函数operator++(0),后缀表达式  

    4.  ++a;//隐式调用成员函数operator++(),前缀表达式  

    5.  b--;//隐式调用友元函数operator--(0),后缀表达式  

    6.  --b;//隐式调用友元函数operator--(),前缀表达式  

    7.  cout<<a.operator ++(2);//显式调用成员函数operator ++(2),后缀表达式  

    8.  cout<<a.operator ++();//显式调用成员函数operator ++(),前缀表达式  

    9.  cout<<operator --(b,2);//显式调用友元函数operator --(2),后缀表达式  

    10. cout<<operator --(b);//显式调用友元函数operator --(),前缀表达式 </PRE>  

    [cpp] view plaincopyprint?

    1.Point a(1);  

    2.Point b(2);  

    3.a++;//隐式调用成员函数operator++(0),后缀表达式  

    4.++a;//隐式调用成员函数operator++(),前缀表达式  

    5.b--;//隐式调用友元函数operator--(0),后缀表达式  

    6.--b;//隐式调用友元函数operator--(),前缀表达式  

    7.cout<<a.operator ++(2);//显式调用成员函数operator ++(2),后缀表达式  

    8.cout<<a.operator ++();//显式调用成员函数operator ++(),前缀表达式  

    9.cout<<operator --(b,2);//显式调用友元函数operator --(2),后缀表达式  

  • 相关阅读:
    KVM环境搭建RHCS
    修改virt-manager默认磁盘格式
    前端基础之html
    并发编程
    网络编程
    常用模块
    模块与包
    迭代器、生成器、面向过程编程
    闭包函数和装饰器
    函数
  • 原文地址:https://www.cnblogs.com/u013533289/p/4477340.html
Copyright © 2011-2022 走看看