• C++运算符重载——重载二元运算符


    1、重载二元操作符的方法

    二元运算符又称为双目运算符,即需要2个操作数的运算符,例如 + - * / 等。

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

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

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

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

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

    并且只能有一个参数。

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

    这种方式需要2个参数,

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

    2、应用举例(对象 ? 对象)

    下例中有3个complex类 ComplexA、ComplexB 和 ComplexC,3个类都重载了加减乘除 运算符。

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

    需要注意的是复数的加减乘除运算的算法是有问题的,只是一个说明重载方法的例子,

    另外重载函数的参数最好使用const关键字限定,至于返回值是否用const限定,需要取决于你的设计,比如允许C3 = ++(C1+C2)这种情况,就不能用cosnt限定。

    至于不同类型的对象间的操作,通常是没有意义的。

    #include <iostream>
    using namespace std;
    
    class ComplexA
    {
    public:
        //默认构造函数(Default constructor)
        ComplexA(){cout<<"Default Constructor"<<endl;}
        //带参数的构造函数(The constructor with parameters)
        ComplexA(double re, double im):real(re),image(im){cout<<"Parameter Constructor"<<endl;}
        //拷贝构造函数(Copy constructor)
        ComplexA(const ComplexA& ref){real = ref.real; image = ref.image; cout<<"Copy Constructor"<<endl;}
        //析构函数(destructor)
        ~ComplexA(){cout<<"Destructor"<<endl;}
    
        //Operator Overload : +
        ComplexA operator+(ComplexA& ref)
        {
            return ComplexA(real + ref.real, image + ref.image);
        }
    
        //Operator Overload : -
        ComplexA operator-(ComplexA& ref)
        {
            return ComplexA(real - ref.real, image - ref.image);
        }
    
        //Operator Overload : *
        ComplexA operator*(ComplexA& ref)
        {
            return ComplexA(real * ref.real, image * ref.image);
        }
    
        //Operator Overload : /
        ComplexA operator/(ComplexA& ref)
        {
            return ComplexA(real / ref.real, image / ref.image);
        }
    
        //display
        void display(void){cout<<real<<"+"<<image<<"i"<<endl;}
    private:
        double real;    //复数的实部
        double image;   //复数的虚部
    };
    
    class ComplexB
    {
    public:
        //默认构造函数(Default constructor)
        ComplexB(){cout<<"Default Constructor"<<endl;}
        //带参数的构造函数(The constructor with parameters)
        ComplexB(double re, double im):real(re),image(im){cout<<"Parameter Constructor"<<endl;}
        //拷贝构造函数(Copy constructor)
        ComplexB(const ComplexB& ref){real = ref.real; image = ref.image; cout<<"Copy Constructor"<<endl;}
        //析构函数(destructor)
        ~ComplexB(){cout<<"Destructor"<<endl;}
    
        //Operator Overload : +
        friend ComplexB operator+(ComplexB& ref1, ComplexB& ref2)
        {
            return ComplexB(ref1.real + ref2.real, ref1.image + ref2.image);
        }
    
        //Operator Overload : -
        friend ComplexB operator-(ComplexB& ref1, ComplexB& ref2)
        {
            return ComplexB(ref1.real - ref2.real, ref1.image - ref2.image);
        }
    
        //Operator Overload : *
        friend ComplexB operator*(ComplexB& ref1, ComplexB& ref2)
        {
            return ComplexB(ref1.real * ref2.real, ref1.image * ref2.image);
        }
    
        //Operator Overload : /
        friend ComplexB operator/(ComplexB& ref1, ComplexB& ref2)
        {
            return ComplexB(ref1.real / ref2.real, ref1.image / ref2.image);
        }
    
        //display
        void display(void){cout<<real<<"+"<<image<<"i"<<endl;}
    private:
        double real;    //复数的实部
        double image;   //复数的虚部
    };
    
    
    class ComplexC
    {
    public:
        //默认构造函数(Default constructor)
        ComplexC(){cout<<"Default Constructor"<<endl;}
        //带参数的构造函数(The constructor with parameters)
        ComplexC(double re, double im):real(re),image(im){cout<<"Parameter Constructor"<<endl;}
        //拷贝构造函数(Copy constructor)
        ComplexC(const ComplexC& ref){real = ref.real; image = ref.image; cout<<"Copy Constructor"<<endl;}
        //析构函数(destructor)
        ~ComplexC(){cout<<"Destructor"<<endl;}
    
        //Get Data
        double GetReal(void){return real;}
        double GetImage(void){return image;}

      //display
    void display(void){cout<<real<<"+"<<image<<"i"<<endl;} private: double real; //复数的实部 double image; //复数的虚部 }; //Operator Overload : + ComplexC operator+(ComplexC& ref1, ComplexC& ref2) { return ComplexC(ref1.GetReal() + ref2.GetReal(), ref1.GetImage() + ref2.GetImage()); } //Operator Overload : - ComplexC operator-(ComplexC& ref1, ComplexC& ref2) { return ComplexC(ref1.GetReal() - ref2.GetReal(), ref1.GetImage() - ref2.GetImage()); } //Operator Overload : * ComplexC operator*(ComplexC& ref1, ComplexC& ref2) { return ComplexC(ref1.GetReal() * ref2.GetReal(), ref1.GetImage() * ref2.GetImage()); } //Operator Overload : / ComplexC operator/(ComplexC& ref1, ComplexC& ref2) { return ComplexC(ref1.GetReal() / ref2.GetReal(), ref1.GetImage() / ref2.GetImage()); } int main(void) { ComplexA C1(2,4), C2(1, 2), C3; C3 = C1 + C2; C3.display(); C3 = C1 - C2; C3.display(); C3 = C1 * C2; C3.display(); C3 = C1 / C2; C3.display(); cout <<"--------------------------------------"<<endl; ComplexB C4(2,4), C5(1, 2), C6; C6 = C4 + C5; C6.display(); C6 = C4 - C5; C6.display(); C6 = C4 * C5; C6.display(); C6 = C4 / C5; C6.display(); cout <<"--------------------------------------"<<endl; ComplexC C7(2,4), C8(1, 2), C9; C9 = C7 + C8; C9.display(); C9 = C7 - C8; C9.display(); C9 = C7 * C8; C9.display(); C9 = C7 / C8; C9.display(); return 0; }

     3、应用举例(对象 ? 基本数据类型 or 基本数据类型 ? 对象)

    上面的例子中是对象 和 对象之间的运算符重载,如果需要一个是对象 + char/int/float/double,或者反过来 char/int/float/double + 对象,这时上面的程序的重载方式就不适用了。

    需要定义新的重载,如下列程序所示。

    #include <iostream>
    using namespace std;
    
    class ComplexD
    {
    public:
        ComplexD(double re = 0, double im = 0):real(re),image(im){}
    
        ComplexD operator+(ComplexD& ref){return ComplexD(real+ref.real, image+ref.image);};
        ComplexD operator+(int a){cout<<"IN	 int 		";return ComplexD(real+a, image);};
        ComplexD operator+(double d){cout<<"IN	 double 	";return ComplexD(real+d, image);};
        ComplexD operator+(float f){cout<<"IN	 float 		";return ComplexD(real+f, image);};
    
        void display(void){cout<<real<<"+"<<image<<"i"<<endl;}
        double GetReal(void){return real;}
        double GetImage(void){return image;}
    private:
        double real;
        double image;
    };
    
    ComplexD operator+(int a, ComplexD& ref){cout<<"OUT	 int 		";return ComplexD(ref.GetReal()+a, ref.GetImage());};
    ComplexD operator+(double d, ComplexD& ref){cout<<"OUT	 double 	";return ComplexD(ref.GetReal()+d, ref.GetImage());};
    ComplexD operator+(float f, ComplexD& ref){cout<<"OUT	 float 		";return ComplexD(ref.GetReal()+f, ref.GetImage());};
    
    int main(void)
    {
        ComplexD D1(2,4), D2;
        D2 = D1 + 2; D2.display();
        D2 = D1 + 2.1f; D2.display();
        D2 = D1 + 2.1; D2.display();
    
        D2 = 2 +D1; D2.display();
        D2 = 2.1f + D1; D2.display();
        D2 = 2.1 +D1; D2.display();
    
        return 0;
    }
  • 相关阅读:
    hdu 3722 Card Game 二分图的最大权匹配
    如何将中国知网CNKI中的文献导入EndNote X6
    高性能以太网芯片W5500 数据手册 V1.0(二)
    (贪心5.1.2)POJ 2287 Tian Ji -- The Horse Racing
    [置顶] 斗地主算法的设计与实现--项目介绍&如何定义和构造一张牌
    Robotium学习笔记一
    Robotium学习笔记二
    Robotium学习笔记三
    做一个测试经理我还差多少?
    [每日一题] 11gOCP 1z0-053 :2013-10-9 backup with the KEEP option....................................33
  • 原文地址:https://www.cnblogs.com/LubinLew/p/CppOperatorOverload-BinaryOperator.html
Copyright © 2020-2023  润新知