天天看點

C++——運算符重載實踐

操作符左右同類重載

重載舉例:重載 + 實作兩個符數的相加; 重載 << 流輸出運算符 實作 cout<<c<<endl; 直接輸出c的real&imagine。

(1)重載 + 部分,分别用友元和成員重載。體會兩者不同

         友元重載時,+函數定義在類聲明之外,得傳遞兩個參數c1,c2 使其相加。 operator+(c1,c2) 

         成員重載,+定義在類内的public部分作為成員函數,傳遞一個參數。使用時為:c1.operator+(c2)

(2)重載 << 部分,<< 為 ostream 類型

         << 重載的函數體起始很簡單,也就是cout 内部實作的道理。重載<<之後的好處是不用再在類内定義dis函數來顯示。直接用cout就可以輸出私有資料。簡單直覺。

#include<iostream>
using namespace std;

class Complex
{
public:
    Complex(int real = 0,int imagine = 0)
        :_real(real),_imagine(imagine){}
    void dis()
    {
        cout<<_real<<","<<_imagine<<endl;
    }
//    friend Complex  operator + (Complex c1,Complex c2 );  + 友元重載
    //成員重載
    Complex operator + (Complex another)
    {
        this->_real += another._real;
        this->_imagine += another._imagine;
    }
    //流運算符重載
    friend ostream & operator << (ostream &os, Complex &c);
private:
    int _real;
    int _imagine;
};

/* + 友元重載
//使用時直接 c = c1 + c2;
Complex  operator + (Complex c1,Complex c2 )
{
    Complex c;
    c._real = c1._real+c2._real;
    c._imagine = c1._imagine + c2._imagine;
    return c;
}
*/

//重載流運算符
ostream & operator << (ostream &os, Complex &c)
{
    os<<c._real<<","<<c._imagine<<endl;
    return os;
}

int main ()
{
    Complex c1(1,3),c2(2,4);
    Complex c3;
//    c3 = c1 + c2;  /*友元重載 + 運算符 使其可以用于複數的加法*/
    c1.operator +(c2);//成員重載 +
    c1.dis();

    //重載流運算符 實作 cout<<c1<<endl; 即可輸出c1的real&imagine
    cout<<c1<<endl;
    return 0;
}
           

操作符左右非同類重載

重載不僅可用于 運算符兩邊同類的還可以非同類。那麼就涉及到 成員重載還是友元重載的問題。

如下示例:

Sender<<Mail1<<Mail2<<endl;

發送郵件 Sender 後跟收件位址,Mail 後為信件内容。Sender和Mail為兩個不同的類。

此時:sender 為左操作數,決定了 operator << 為 Sender 的成員函數,而 mail 決定了operator<<要作 Mail 類的友員

//流輸出運算符 重載

#include <iostream>
using namespace std;

class Mail;

class Sender
{
public:
    Sender(string Addr)
        :_Addr(Addr){}
    Sender & operator << (class Mail &mail);
private:
    string _Addr;

};

class Mail
{
public:
    Mail(string time,string topic)
        :_time(time),_topic(topic){}
    friend Sender & Sender:: operator << (class Mail &mail);

private:
    string _time;
    string _topic;

};

Sender & Sender::operator << (class Mail &mail)
{
    cout<<"Address to :"<<_Addr<<endl;
    cout<<"Mail.time  :"<<mail._time<<endl;
    cout<<"Mail.topic :"<<mail._topic<<endl;
    puts("");
    return *this;
}

//Sender & Sender::operator << (string _Addr)
//{
//    cout<<"Address to :"<<_Addr<<endl;
//    cout<<"Mail.time  :"<<Mail._time<<endl;
//    cout<<"Mail.topic :"<<Mail._topic<<endl;
//    return *this;

//}

int main()
{
    Sender s1("[email protected]");
    Mail mail1("2:00","jjjjj");
    Mail mail2("4:00","mmmm");
    s1<<mail1<<mail2;

    Sender s3("[email protected]");
    Mail mail3("4:00","chetui");
    s3<<mail3;
    return 0;
}
           

注意:

(1)Sender函數注釋部分,第一次寫的時候沒有注意到   operator <<  的左右操作數。

Sender <<  Mail   左邊為Sender 類,則運算完的傳回值類型為Sender 類型。右邊為 Mail 類,則函數操作數為 Mail。

是以:函數聲明應為 

Sender & Sender:: operator << (class Mail &mail);
           

  由此觀之:Sender 為左操作數,是以 operator << 為Sender 的成員函數。而 Mail 決定了operator << 要做Mail 的成員。

(2)this指針的使用。

在函數體中,傳回了this 指針 return *this;傳回值類型為Sender 。this指向Sender定義的位址,保證了下一次使用同一位址的時候資料還可以找到。

繼續閱讀