• C++运算符重载


    所谓重载,就是重新赋予新的含义,函数重载就是对一个已有的函数赋予新的含义,使之实现新功能。
    运算符的重载主要存在两种形式,一种是作为类的成员函数进行使用,另一种则是作为类的友元函数进行使用。运算符的重载的形式为:
       返回类型 operator 运算符符号(参数说明)
        {    
               //函数体的内部实现
        }

    例如,能否用“+”号进行两个复数的相加,在C++中不能在程序中直接用运算符“+”对复数进行相加运算,用户必须自己设法实现复数相加。例如用户可以通过定义一个专门的函数来实现复数相加。

     1 /*
     2 实现复数类中的运算符重载
     3 定义一个复数类重载运算符+、-、*、/,使之能用于复数的加减乘除。
     4 方案一:使用类的成员函数完成运算符的重载;
     5 */
     6 #include<iostream>
     7 using namespace std;
     8 
     9 class Complex
    10 {
    11 private:
    12     double real;
    13     double imag;
    14 public:
    15     Complex()
    16     {
    17         real = 0 ; imag = 0 ;
    18     }
    19     Complex(double r,double i)
    20     {
    21         real = r ; imag = i ;
    22     }
    23     Complex operator+(Complex &c2);
    24     Complex operator-(Complex &c2);
    25     Complex operator*(Complex &c2);
    26     Complex operator/(Complex &c2);
    27     void display();
    28 };
    29 
    30 //下面定义成员函数
    31 Complex Complex::operator+(Complex &c2) //定义重载运算符”+“的函数
    32 {
    33     return Complex(this->real+c2.real , this->imag+c2.imag);   //此处this->real就是c1.real
    34 }
    35 Complex Complex::operator-(Complex &c2)//定义重载运算符”-“的函数
    36 {
    37     return Complex(this->real-c2.real , this->imag-c2.imag);   //此处this->real就是c1.real
    38 }
    39 
    40 Complex Complex::operator*(Complex &c2)  
    41 {
    42     return Complex(this->real*c2.real , this->imag*c2.imag);   //此处this->real就是c1.real  
    43 }
    44 
    45 Complex Complex::operator/(Complex &c2)  
    46 {
    47     Complex c;      
    48     c.real = (real*c2.real + imag*c2.imag)/(c2.real*c2.real+c2.imag*c2.imag);      
    49     c.imag = (-real*c2.imag + imag*c2.real)/(c2.real*c2.real+c2.imag*c2.imag);     
    50     return c;      
    51 }   
    52 
    53 void Complex::display()
    54 {
    55     cout<<"("<<real<<","<<imag<<"i)"<<endl;
    56 }
    57 
    58 int main(void)
    59 {
    60     Complex c1(3,4),c2(5,-10),c3;
    61     cout<<"c1=";
    62     c1.display();
    63     cout<<"c2=";
    64     c2.display();
    65     c3=c1+c2;   // 此处相当于非重载运算符函数中的“c3=c1.Complex_add(c2)
    66     //将运算符+重载为类的成员函数后,编译系统会将程序中的表达式c1+c2解释为:c1.operator+(c2)即以c2为实参调用c1的运算符重载函数operator+(Complex&c2),operator+是类的一个函数名
    67     cout<<"c1+c2=";
    68     c3.display();
    69     c3=c1-c2;
    70     cout<<"c1-c2=";
    71     c3.display();
    72     c3=c1*c2;
    73     cout<<"c1*c2=";
    74     c3.display();
    75     c3=c1/c2;
    76     cout<<"c1/c2=";
    77     c3.display();
    78     return 0;
    79 }
    View Code

    运算符重载运算符的运算规则
          ①运算符重载函数也是函数,重载的运算符不会改变运算符的优先级、结合型和参数的个数。
          ②重载运算符不能违反语言的语法规则。
          ③赋值运算符除外,重载运算符可由派生类继承下去。
          ④重载运算符不能使用默认参数。
          ⑤运算符=、()、[]和->等操作符必须定义为类的成员函数,将这些操作符定义为友元函数将在编译时标记为错误。
         
     ⑥C++中不能重载的运算符只有5个:
           .  (成员访问运算符)
           .* (成员指针访问运算符)
           ∷ (域运算符)
           sizeof(长度运算符)
           ?: (条件运算符)

          因为前两个运算符不能重载是为了保证访问成员的功能不能被改变,域运算符和sizeof运算符的运算对象是类型而不是变量或一般表达式,不具重载的特征。总结:带点'.'的都不能重载,new和delete神马的也可以重载!
          ⑦友元运算符的参数规则与类成员运算符的参数规则不同,一员运算符必须显示地声明一个参数,二员运算符必须显示地声明两个参数。类成员运算符重载时,参数中隐含了一个this指针。(另外,C++规定,有的运算符(如赋值运算符、下标运算符、函数调用运算符)必须定义为类的成员函数有的运算符则不能定义为类的成员函数(如流输入“>>”和流输出“<<”运算符、类型转换运算符))。
    重载为类的成员函数时,参数个数=原操作数个数-1(后置++、--除外),它可以通过this指针自由地访问本类的数据成员,可以少写一个函数的参数,但必须要求运算表达式的第一个参数(即运算符左侧的操作数)是一个类对象。
    重载为类的友元函数时,参数个数=原操作数个数,且至少应该有一个自定义类型的形参。

    如何重载增量运算符 ++ 和 --
        运算符++和—有前置和后置两种形式,如果不区分前置和后置,则使用operator++( )或operator--( )即可;否则,要使用operator++( )或operator--( )来重载前置运算符,使用operator++(int)或operator--(int)来重载后置运算符,调用时,参数int被传递给值0。如下列程序段:

     1 //重载增量运算符 ++ 和 --
     2 #include<iostream>
     3 using namespace std;
     4 
     5 class Complex
     6 {
     7 private:
     8     int x;
     9     int y;
    10 public:
    11     Complex()    //定义构造函数
    12     {
    13         x = 0 ; y = 0 ;
    14     }
    15     Complex(int a,int b)    //构造函数重载
    16     {
    17         x = a ; y = b ;
    18     }
    19     void display();
    20     Complex operator ++();      //前置自增方式
    21     Complex operator ++(int);   //后置自增方式(增加一个int类型的形参)
    22 };
    23 
    24 Complex Complex::operator ++()
    25 {
    26     x = x + 1;
    27     y = y + 1;
    28     return *this;
    29 }
    30 Complex Complex::operator ++(int)
    31 {
    32     Complex temp(*this);
    33     x = x + 1;
    34     y = y + 1;
    35     return temp;
    36 }
    37 void Complex::display()  
    38 {  
    39     cout<<"("<<x<<","<<y<<")"<<endl;  
    40 }
    41 int main(void)
    42 {
    43     Complex c1(3,4),c2(5,-10),c3;
    44     c3 = c1++;
    45     cout<<"c1++=";
    46     c3.display();
    47     c3 = ++c2;
    48     cout<<"++c2=";
    49     c3.display();
    50     return 0;
    51 }
    View Code

    重载流输入运算符和流输出运算符

    istream  类的对象cin;
    ostream类的对象cout;
    如果想直接用“<<”和“>>”输出和输入自己声明的类型的数据,必须对它们重载,对“<<”和“>>”重载的函数形式如下:
    istream & operator >> (istream &,自定义类 &);
    ostream & operator << (ostream &,自定义类 &);

    重载运算符“>>”的函数的第一个参数和函数的类型都必须是istream&类型,第二个参数是要进行输入操作的类。
    重载“<<”的函数的第一个参数和函数的类型都必须是ostream&类型,第二个参数是要进行输出操作的类。
    只能将重载“>>”和“<<”的函数作为友元函数或普通的函数,而不能将它们定义为成员函数。

    实现代码如下:

     1 //增加重载流提取运算符“>>”,用“cin>>”输入复数,用“cout<<”输出复数。
     2 #include<iostream>
     3 using namespace std;
     4 
     5 class Complex
     6 {
     7 private:
     8     double real;
     9     double imag;
    10 public:
    11     Complex()    //定义构造函数
    12     {
    13         real = 0 ; imag = 0 ;
    14     }
    15     Complex(double r,double i)    //构造函数重载
    16     {
    17         real = r ; imag = i ;
    18     }
    19     friend istream& operator>>(istream & , Complex & );
    20     friend ostream& operator<<(ostream & , Complex & );
    21 };
    22 
    23 //下面定义友员函数 
    24 istream& operator>>(istream & in, Complex &c)
    25 {
    26     cout<<"input real part and imaginary part of complex number:";
    27     in>>c.real>>c.imag;
    28     return in;
    29 }
    30 ostream& operator<<(ostream & out, Complex &c)
    31 {
    32     out<<'('<<c.real<<"+"<<c.imag<<"i)";
    33     return out;
    34 }
    35 
    36 int main(void)
    37 {
    38     Complex c1 , c2;
    39     cin>>c1>>c2;
    40     cout<<"c1="<<c1<<endl;
    41     cout<<"c2="<<c2<<endl;
    42     return 0;
    43 }
    View Code

    转载自http://blog.csdn.net/hackbuteer1/article/details/7554070

  • 相关阅读:
    大爽Python入门教程 3-1 布尔值: True, False
    以太坊中的账户、交易、Gas和区块Gas Limit
    全链路压力测试经验
    全链路压力测试
    腾讯大牛教你ClickHouse实时同步MySQL数据
    数据湖和数据仓库的区别?
    第六次作业
    linux CPU实时频率命令
    没有Flash如何做直播
    如何扩展srs并发能力
  • 原文地址:https://www.cnblogs.com/CnZyy/p/3317086.html
Copyright © 2020-2023  润新知