c++成员运算符重载和友元运算符重载的比较(以++,--运算符为例)

1、对双目运算符而言,成员运算符重载函数参数列表中含有一个参数,而友元运算符重载函数参数列表含有两个参数;对单目运算符而言,成员运算符重载函数参数列表中没有参数,而友元运算符重载函数参数列表含有一个参数。
2、双目运算符一班可以被重载为友元运算符和成员函数运算符,但是当一个整数与一个复数相加时,必须使用友元函数。
例:友元运算符重载函数实现一个复数与一个整数相加

#include<iostream>
using namespace std;
class complex
{
    public:
        complex(int r=0,int i=0);
        friend complex operator+(complex com,int a)//定义友元运算符重载函数,+左侧是类对象,右侧是函数 
        {
            return complex(com.real+a,com.imag);
        }
        friend complex operator+(int a,complex com)//定义友元运算符重载函数,+左侧是函数,右侧是类对象
        {
            return complex(a+com.real,com.imag);
        }
        void show();
        private:
            int real,imag;
};

void complex::show()
{
    cout<<"real="<<real<<" imag="<<imag<<endl;
}

complex::complex(int r,int i)
{
    real=r;
    imag=i;
}
int main()
{
    complex com1(12,34),com2,com3;
    com2=com1+27;
    com2.show();
    com3=12+com1;
    com3.show();
    return 0;
}

结果:
real=39 imag=34
real=24 imag=34
如果有成员函数运算符,整数不是类的对象
com2=com1+27,则编译为com2=com1.operator(100)
com2=12+com1,则编译为com2=100.operator(com1),错误,100无法调用成员运算符重载函数。
所以,当一个整数与一个复数相加时,只能使用友元运算符重载函数

运算符函数调用形式
习惯调用形式 友元 成员函数
a+b operator+(a,b) a.operator+(b)
-a operator-(a) a.operator-()
a++ operator++(a,0) a.operator++(0)
–a operator–(a) a.operator–();

使用成员函数以前缀和后缀方式重载运算符–

#include<iostream>
using namespace std;
class three
{
    public:
        three(int a=0,int b=0,int c=0);
        void print();
        three operator--();//声明自减运算符--重载成员函数(前缀方式) 
        three operator--(int);//声明自减运算符--重载成员函数(后缀方式)
        private:
        int x,y,z; 
};

three::three(int a,int b,int c)
{
    x=a;
    y=b;
    z=c;
}

void three::print()
{
    cout<<"x="<<x<<" y="<<y<<" z="<<z<<endl;
}

three three::operator--()
{
    --x;
    --y;
    --z;
    return *this;//返回自减后的当前对象 
 } 
three three::operator--(int)
{
    three temp(*this); 
    x--;
    y--;
    z--;
    return temp;
}

int main()
{
    three obj1(4,5,6),obj2,obj3(7,8,9),obj4;
    obj1.print();
    --obj1;
    obj1.print();
    obj2=obj1--;//obj2保存的是执行obj1--前的obj1值 
    obj2.print();
    obj1.print();
    cout<<endl;
    obj3.print();
    obj3.operator--();
    obj3.print();
    obj4=obj3.operator--(0);
    obj4.print();
    obj3.print();
    return 0;
}

结果:
x=4 y=5 z=6
x=3 y=4 z=5
x=3 y=4 z=5
x=2 y=3 z=4

x=7 y=8 z=9
x=6 y=7 z=8
x=6 y=7 z=8
x=5 y=6 z=7

重载后缀自增运算符时,多了一个int型参数,这个参数只是为了与前缀++运算符重载函数有所区别,定义时可以只写int

使用友元函数以前缀方式和后缀方式重载运算符++

#include<iostream>
using namespace std;
class three
{
    public:
        three(int a=0,int b=0,int c=0);
        void print();
        friend three operator++(three &op);//声明自加运算符++重载友元函数(前缀方式) 
        friend three operator++(three &op,int);//声明自加运算符++重载友元函数(后缀方式) 
        private:
            int x,y,z;
 };

 three::three(int a,int b,int c)
 {
    x=a;
    y=b;
    z=c;
 }

 void three::print()
 {
    cout<<"x="<<x<<" y="<<y<<" z="<<z<<endl;
 }

three operator++(three &op)
{
    ++op.x;
    ++op.y;
    ++op.z;
    return op;
}

three operator++(three &op,int)
{
    op.x++;
    op.y++;
    op.z++;
    return op;
}
int main()
{
    three obj1(4,5,6),obj2(7,8,9);
    obj1.print();
    ++obj1;
    obj1.print();
    obj1++;
    obj1.print();
    cout<<endl;
    obj2.print();
    operator++(obj2);//显示调用 
    obj2.print();
    operator++(obj2,0);
    obj2.print();
    return 0;

}

结果:
x=4 y=5 z=6
x=5 y=6 z=7
x=6 y=7 z=8

x=7 y=8 z=9
x=8 y=9 z=10
x=9 y=10 z=11

友元运算符重载函数没有this指针,所以不能用this指针所指的对象,应采用对象引用参数传递数据

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页