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

    0、重载一元操作符的方法

    一元运算符即只需要一个操作用的运算符,如取地址运算符(&)、复数(-)、自减(--)、自加(++)等。

    运算符重载可以分为3种方式:类的非静态成员函数、类的友元函数、普通函数。

    例如有 1 个操作数 a,一元运算符 ? (表示一个一元运算符),a? 或者?a 的操作会被解释为下面2种形式之一 

    //a? or ?a
    a.operator?();    //类的非静态成员函数
    operator?(a);    //友元函数 和 普通函数

    第一种形式是运算符被重载为类的非静态成员函数,没有参数。

    这种方式要求操作数(即a)必须是一个对象,operator?是这个对象的非静态成员函数,

    第二种形式是运算符被重载为类的友元函数 或 普通函数,有1个参数。

    重载为 类的友元函数 和 普通函数的区别是 类的友元函数可以直接访问类的私有成员,而普通函数不可以。

     

    1、重载++、--(前置 和 后置)

    自增运算符(++)和 自减运算符(--)都有 前置 和 后置 2中情况。

    C++中为了区分前置和后置规定:前置重载与普通运算符重载一致,后置重载需要在参数列表中加入一个无用的参数。

    ++/-- 的3种重载方式如下: 前置的情况可以返回类的引用,后置的情况只能返回临时对象。

    //类的非静态成员函数
    class X
    {
        X& operator++(){...}          //前置++
        X  operator++(int){...}       //后置++
       
        X& operator--(){...}         //前置--     
        X  operator--(int){...}       //后置--
    }
    /*-----------------------------------------------------*/
    //类的友元函数
    class X
    {
        friend X& operator++(X& ref){...}      //前置++
        friend X  operator++(X& ref, int){...} //后置++
    
        friend X& operator--(X& ref){...}       //前置--
        friend X  operator--(X& ref, int){...}  //后置--     
    }
    /*-----------------------------------------------------*/
    //普通函数
    class X
    {
    ...        
    }
    X& operator++(X& ref){...}         //前置++
    X  operator++(X& ref, int){...}    //后置++
    
    X& operator--(X& ref){...}         //前置--
    X  operator--(X& ref, int){...}    //后置--

    下例中有3个Counter类 CounterA、CounterB 和CounterC,3个类都重载了前置++、-- 和后置++、--。

    其中CounterA使用类的非静态成员函数方式重载,CounterB使用类的友元函数方式重载,CounterC使用普通函数方式重载

    #include <iostream>
    using namespace std;
    
    class CounterA
    {
    public:
        //默认构造函数(Default constructor)
        CounterA(){cout<<"Default Constructor"<<endl;}
        //带参数的构造函数(The constructor with parameters)
        CounterA(int m):n(m){cout<<"Parameter Constructor"<<endl;}
        //拷贝构造函数(Copy constructor)
        CounterA(const CounterA& ref){n = ref.n; cout<<"Copy Constructor"<<endl;}
        //析构函数(destructor)
        ~CounterA(){cout<<"Destructor"<<endl;}
    
    
        //重载运算符 ++(前置)
        const CounterA& operator++(){++n; return *this;}
        //重载运算符 ++(后置)
        const CounterA operator++(int dump){CounterA Tmp(*this);++n; return Tmp;}
        //重载运算符 --(前置)
        const CounterA& operator--(){--n; return *this;}
        //重载运算符 --(后置)
        const CounterA operator--(int dump){CounterA Tmp(*this);--n; return Tmp;}
    
        //输出用函数
        void display(void){cout<<"n = " << n << endl;}
        //GetData
        int GetVal(void){return n;}
    
    private:
        int n;
    };
    
    class CounterB
    {
    public:
        //默认构造函数(Default constructor)
        CounterB(){cout<<"Default Constructor"<<endl;}
        //带参数的构造函数(The constructor with parameters)
        CounterB(int m):n(m){cout<<"Parameter Constructor"<<endl;}
        //拷贝构造函数(Copy constructor)
        CounterB(const CounterB& ref){n = ref.n; cout<<"Copy Constructor"<<endl;}
        //析构函数(destructor)
        ~CounterB(){cout<<"Destructor"<<endl;}
    
        //重载运算符 ++(前置)
        friend const CounterB& operator++(CounterB& ref){ref.n += 1;return ref;}
        //重载运算符 ++(后置)
        friend const CounterB operator++(CounterB& ref, int dump){CounterB Tmp(ref);ref.n += 1; return Tmp;}
        //重载运算符 --(前置)
        friend const CounterB& operator--(CounterB& ref){ref.n -= 1;return ref;}
        //重载运算符 --(后置)
        friend const CounterB operator--(CounterB& ref, int dump){CounterB Tmp(ref);ref.n -= 1; return Tmp;}
    
        //输出用函数
        void display(void){cout<<"n = " << n << endl;}
        //GetData
        int GetVal(void){return n;}
        //SetData
        void SetVal(int val){n = val;}
    
    private:
        int n;
    };
    
    class CounterC
    {
    public:
        //默认构造函数(Default constructor)
        CounterC(){cout<<"Default Constructor"<<endl;}
        //带参数的构造函数(The constructor with parameters)
        CounterC(int m):n(m){cout<<"Parameter Constructor"<<endl;}
        //拷贝构造函数(Copy constructor)
        CounterC(const CounterC& ref){n = ref.n; cout<<"Copy Constructor"<<endl;}
        //析构函数(destructor)
        ~CounterC(){cout<<"Destructor"<<endl;}
    
    
        //输出用函数
        void display(void){cout<<"n = " << n << endl;}
        //GetData
        int GetVal(void){return n;}
        //SetData
        void SetVal(int val){n = val;}
    
    private:
        int n;
    };
    //重载运算符 ++(前置)
    const CounterC& operator++(CounterC& ref){ref.SetVal(ref.GetVal()+1);return ref;}
    //重载运算符 ++(后置)
    const CounterC operator++(CounterC& ref, int dump){CounterC Tmp(ref);ref.SetVal(ref.GetVal()+1); return Tmp;}
    //重载运算符 --(前置)
    const CounterC& operator--(CounterC& ref){ref.SetVal(ref.GetVal()-1);return ref;}
    //重载运算符 --(后置)
    const CounterC operator--(CounterC& ref, int dump){CounterC Tmp(ref);ref.SetVal(ref.GetVal()-1); return Tmp;}
    
    
    int main(void)
    {
        CounterA cp1(5);cp1.display();
        ++cp1;cp1.display();
        --cp1;cp1.display();
        CounterA cp2(cp1++);cp2.display();
        CounterA cp3(cp1--);cp3.display();
    
        CounterB cp4(5);cp4.display();
        ++cp4;cp4.display();
        --cp4;cp4.display();
        CounterB cp5(cp4++);cp5.display();
        CounterB cp6(cp4--);cp6.display();
    
        CounterC cp7(5);cp7.display();
        ++cp7;cp7.display();
        --cp7;cp7.display();
        CounterC cp8(cp7++);cp8.display();
        CounterC cp9(cp7--);cp9.display();
    
        return 0;
    }

    2、重载负号(-)

    下例中有3个Complex类 ComplexA、ComplexB 和ComplexC,3个类都重载了负号。

    其中ComplexA使用类的非静态成员函数方式重载,ComplexB使用类的友元函数方式重载,ComplexC使用普通函数方式重载。

    #include <iostream>
    using namespace std;
    
    class ComplexA
    {
    public:
        //constructor
        ComplexA(double re, double im):real(re),image(im){}
        //Operator Overload : -
        ComplexA operator-(){return ComplexA(-real, -image);}
        //display
        void display(void){if (image>0)cout<<real<<"+"<<image<<endl;else cout<<real<<image<<endl;}
    
    private:
        double real;
        double image;
    };
    
    class ComplexB
    {
    public:
        //constructor
        ComplexB(double re, double im):real(re),image(im){}
        //Operator Overload : -
        friend ComplexB operator-(ComplexB& ref){return ComplexB(-ref.real, -ref.image);}
        //display
        void display(void){if (image>0)cout<<real<<"+"<<image<<endl;else cout<<real<<image<<endl;}
    private:
        double real;
        double image;
    };
    
    class ComplexC
    {
    public:
        //constructor
        ComplexC(double re, double im):real(re),image(im){}
        //GetData
        double GetReal(void){return real;}
        double GetImage(void){return image;}
        //display
        void display(void){if (image>0)cout<<real<<"+"<<image<<endl;else cout<<real<<image<<endl;}
    
    
    private:
        double real;
        double image;
    };
    
    //Operator Overload : -
    ComplexC operator-(ComplexC& ref){return ComplexC(-ref.GetReal(), -ref.GetImage());}
    
    int main(void)
    {
        ComplexA a1(1,2);a1.display();
        ComplexA a2(-a1);a2.display();
    
        ComplexB b1(1,2);b1.display();
        ComplexB b2(-b1);b2.display();
    
        ComplexC c1(1,2);c1.display();
        ComplexC c2(-c1);c2.display();
    
        return 0;
    }
  • 相关阅读:
    <a href=”#”>与 <a href=”javascript:void(0)” 的区别
    win7与ubuntu11.04双系统
    winform中为控件设置鼠标样式
    如何得到格林威治标准时间(C#,SQL SERVER)
    winform中将光标定位到多行文本框的最下处
    VS2010 MV3开发时让jQuery支持智能感知
    转载:SQL Server 2005无日志文件附加数据库
    PowerPoint无法显示文件中某些幻灯片中的文字、图像或对象
    转载:版本简介
    使用 ADO.NET连接SQL Azure
  • 原文地址:https://www.cnblogs.com/LubinLew/p/CppOperatorOverload-UnaryOperator.html
Copyright © 2011-2022 走看看