1. 程式人生 > >c++成員運算子過載和友元運算子過載的比較(以++,--運算子為例)

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指標所指的物件,應採用物件引用引數傳遞資料