cpp运算符重载简单教程

⌚Time: 2022-01-22 19:13:29

👨‍💻Author: Jack Ge

定义一个复数类,实现两个复数相加功能


#include<iostream>

using namespace std;

class complex{

    private:

        int real;

        int image;

    public:

        complex(){}

        complex(int real,int image){

            this->real=real;

            this->image=image;

        }

        void setReal(int value){

            real=value;

        }

        void setImage(int value){

            image=value;

        }

        int getReal(){

            return real;

        }

        int getImage(){

            return image;

        }

        void display(){

            cout<<real<<'+'<<image<<'i'<<endl;

        }

        complex add(const complex &a)const{

            complex b;

            b.setReal(real+a.getReal());

            b.setImage(image+a.getImage());

            return b;

        }

};

int main(){

    complex a(1,2);

    complex b(3,4);

    complex c;

    c=a.add(b);

    c.display();

    return 0;

}



}

结果:

复数类通过成员函数add()实现了两个复数类的相加功能。

是否有办法使用易于理解的a+b表达式的形式实现两个复数类相加呢?当然有。c++提供运算符重载功能。可以实现对自定义类实现+-*%等各种运算符的运算。只需要在成员函数中定义operator()函数就可以实现对运算符的重载

例子:


#include<iostream>

using namespace std;

class complex{

    private:

        int real;

        int image;

    public:

        complex(){}

        complex(int real,int image){

            this->real=real;

            this->image=image;

        }

        void setReal(int value){

            real=value;

        }

        void setImage(int value){

            image=value;

        }

        int getReal()const{

            return real;

        }

        int getImage()const{

            return image;

        }

        void display(){

            cout<<real<<'+'<<image<<'i'<<endl;

        }

        //运算符重载函数operator+

        complex operator+(const complex &a)const{

            complex b;

            b.setReal(real+a.getReal());

            b.setImage(image+a.getImage());

            return b;

        }

};

int main(){

    complex a(1,2);

    complex b(3,4);

    complex c;

    c=a+b;

    c.display();

    return 0;

}


结果:

通过定义operator+()函数实现了两个类c=a+b表达式形式的加法运算。此时的c=a+b相当于c=a.operator+(b)。同样的,也可以使用以上方法重载-*/等运算符。即在类中定义operator-()operator*()operator/()等成员函数。

运算符重载,至少有一个操作数是用户自定义的类型,这将防止用户为标准类型重载运算符,比如,你不能为两个标准类型的double值去重载运算符+


当两个操作数有一个是自定义类,而另一个是标准类型时,如要实现complex类与int值相加,实现复数实部的增加,可以在complex类中继续定义一个成员函数


        complex operator+(const int &a)const{

            complex b;

            b.setReal(real+a);

            b.setImage(image);

            return b;

        }

可以使用


complex c=a+2;

来实现,相当于调用a.operator+(2);而如果是


complex c=2+a;

呢?显然不行的,因为int型没有operator+()这个成员函数

解决办法可以是让所有人使用a+2这个形式,而不是2+a,这显然是我们不希望使用的方法

还有一种办法就是使用非成员函数形式实现运算符重载,由于运算符重载函数需要访问类的内部空间,需要将此函数定义为该类的友元函数。友元函数不是类的成员函数,但是与类成员函数具有相同的访问权限。

实现:


#include<iostream>

using namespace std;

class complex{

    private:

        int real;

        int image;

    public:

        complex(){}

        complex(int real,int image){

            this->real=real;

            this->image=image;

        }

        void setReal(int value){

            real=value;

        }

        void setImage(int value){

            image=value;

        }

        int getReal()const{

            return real;

        }

        int getImage()const{

            return image;

        }

        void display(){

            cout<<real<<'+'<<image<<'i'<<endl;

        }

        

        complex operator+(const complex &a)const{

            complex b;

            b.setReal(real+a.getReal());

            b.setImage(image+a.getImage());

            return b;

        }

        complex operator+(const int &a)const{

            complex b;

            b.setReal(real+a);

            b.setImage(image);

            return b;

        }

        //定义非成员函数operator+

        friend complex operator+(int a,const complex &b);

};

complex operator+(int a,const complex &b){

    complex c;

    c.setReal(a+b.getReal());

    c.setImage(b.getImage());

    return c;

}



int main(){

    complex a(1,2);

    complex c;

    complex d;

    c=a+2;

    c.display();

    d=4+a;

    d.display();

    return 0;

}


结果:

可以看到,将operator+(int a,const complex &b)定义为非成员函数,这样对于类似c=4+a这样的表达式,会转换为c=operator+(4,a),从而调用刚才定义的非成员友元函数。


虽然通过非成员友元函数的方法也可以进行运算符重载,但是下列运算符只能通过定义为成员函数的方法进行重载

|运算符|说明 |

|--|--|

| = |赋值运算符 |

|() |函数调用运算符 |

| []| 下标运算符|

| ->| 通过指针访问类成员的运算符|

也有一些运算符,不能进行重载

|运算符|说明 |

|--|--|

|sizeof| sizeof运算符|

| .| 成员运算符|

| .*| 成员指针运算符|

| ::| 作用域解析运算符|

| ?:| 条件运算符|

| typeid| 一个RTTI运算符|

| const_cast| 强制类型转换运算符|

| dynamic_cast| 强制类型转换运算符 |

| reinterpret_cast| 强制类型转换运算符 |

|static_cast|强制类型转换运算符|


Tips:

对于单目运算符++的重载,如何区分重载的左侧++i还是右侧i++

实际上默认重载运算符在左侧的情况,如果对运算符在右边的情况重载,需要在重载函数参数列表中加入一个int

例子:


#include<iostream>

using namespace std;

class complex{

    private:

        int real;

        int image;

    public:

        complex(){}

        complex(int real,int image){

            this->real=real;

            this->image=image;

        }

        void setReal(int value){

            real=value;

        }

        void setImage(int value){

            image=value;

        }

        int getReal()const{

            return real;

        }

        int getImage()const{

            return image;

        }

        void display(){

            cout<<real<<'+'<<image<<'i'<<endl;

        }

        //重载++i

        complex operator++(){

            real+=1;

            image+=1;

        }

        //重载i++

        complex operator++(int){

            real+=1;

            image+=1;

        }

};

int main(){

    complex a(1,2);

    complex b(5,7);

    ++a;

    b++;

    a.display();//2+3i

    b.display();//6+8i

    return 0;

}