日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

重載操作符解析

 pgj555 2014-01-16
重載操作符是個(gè)好青年,但是要吐槽的是 ,我們時(shí)常為了重載操作符編寫許多重復(fù)的代碼。這是枯燥的,但是也是必須的。你重載的越多,你的類的彈性就越大。但是,你也不能為所欲為。玩游戲總是遵守相應(yīng)的規(guī)則,寫重載操作符亦是如此 !

    以下是要遵守的游戲規(guī)則 :

 一元操作符可以是不帶參數(shù)的成員函數(shù)或帶一個(gè)參數(shù)的非成員函數(shù)。

 二元操作符可以是帶一個(gè)參數(shù)的成員函數(shù)或帶兩個(gè)參數(shù)的非成員函數(shù)。

 operator=、operator[]、operator()、operator->只能定義為成員函數(shù)。

 operator->的返回值必須是一個(gè)指針或能使用->的對(duì)象。

 重載 operator++ 和 operator--時(shí)帶一個(gè) int 參數(shù)表示后綴,不帶參數(shù)表示前綴。

 除 operator new 和 operator delete 外,重載的操作符參數(shù)中至少要有一個(gè)非內(nèi)建數(shù)據(jù)類型。

 重載的的操作符應(yīng)盡量模擬操作符對(duì)內(nèi)建類型的行為。

    在看完游戲規(guī)則之后,我們就各個(gè)部分的實(shí)現(xiàn)和注意點(diǎn)進(jìn)行肢解 。

⒈ 輸入和輸出操作符的重載

    對(duì)于>>和<<的重載要注意以下幾個(gè)要點(diǎn) :

    ① IO操作符必須為 非成員函數(shù),如果將其定義為成員函數(shù),那么IO操作符的操作習(xí)慣將和正常的習(xí)慣相反。多怪??!此時(shí),你或許會(huì)問,那我怎么調(diào)用對(duì)象中的私有成員呢?別急,我們不是有友員和友類嗎?將IO操作符重載函數(shù)定義成類的友員函數(shù),這個(gè)問題就迎刃而解了 。

    ② 在輸入期間,我們可能會(huì)碰到錯(cuò)誤。此時(shí),要恢復(fù)對(duì)象為初始狀態(tài)。也就是,在輸入之前什么樣子,我們就恢復(fù)成那個(gè)樣子。

    ③ 這個(gè)要點(diǎn)是摘至《C++ primer》,我覺得挺好的。我們可以重載操作符,意味著我們自由的空間就大了。但是,我們不要忘了IO操作符的本質(zhì),不要過度的格式化,應(yīng)將格式化降到最低。

    在注意了幾個(gè)要點(diǎn)之后,我們看一個(gè)完整的IO操作符的實(shí)現(xiàn)例子:

#include <iostream>

#include <string>

using namespace std;

 

class MyClass {

private:

    string name;

    int id;

    int prefix;

    int value;

public:

    MyClass() { };

    MyClass(string n, int a, int p, int nm):name(n), id(a), prefix(p), value(nm){}    // 利用初始化列表來初始化成員對(duì)象

 

    friend ostream &operator<<(ostream &stream, MyClass o);        // 操作符被定義為非成員函數(shù)時(shí),要將其定義為所操作類的友員

    friend istream &operator>>(istream &stream, MyClass &o);   

};

 

ostream &operator<<(ostream &stream, MyClass o)

{

    stream << o.name << " ";

    stream << "(" << o.id << ") ";

    stream << o.prefix << "-" << o.value << "\n";

 

    return stream;

}

 

istream &operator>>(istream &stream, MyClass &o)

{

    cout << "Enter name: ";

    stream >> o.name;

    cout << "Enter id: ";

    stream >> o.id;

    cout << "Enter prefix: ";

    stream >> o.prefix;

    cout << "Enter value: ";

    stream >> o.value;

    cout << endl;

 

    return stream;

}

 

int main()

{

    MyClass a;

    operator>>(cin, a);        // 相當(dāng)于operator>>(cin, a)

    cout << a;                // 相當(dāng)于operator<<(cout, a)

    return 0;

}

    我覺得,許多的事情都是盡在不言中??戳舜a,你就知道,這個(gè)家伙是這么用的,這樣用才是規(guī)范的。好了接下來介紹算術(shù)操作符和關(guān)系操作符。

⒉ 算術(shù)操作符和關(guān)系操作符的重載

    一般而言,將算術(shù)操作符和關(guān)系操作符定義為非成員函數(shù)。

① 算術(shù)操作符

    那就看代碼怎么實(shí)現(xiàn)吧:

#include <iostream>

#include <string>

 

using namespace std;

 

class Point

{

public:

    Point(){};

    Point(int x_, int y_):x(x_),y(y_){};

    Point(const Point &p){

        this->x = p.x;

        this->y = p.y;

    };

 

    ~Point(){};

 

    friend Point operator+(Point &p1, Point &p2);    // 兩個(gè)對(duì)象相加

    friend Point operator+(int value, Point &p1);    // 對(duì)象和值的相加

 

    friend ostream &operator<<(ostream &os, Point &p1);

private:

    int x;

    int y;

};

 

Point operator+(Point &p1, Point &p2)

{

    Point temp;

 

    temp.x = p1.x + p2.x;

    temp.y = p1.y + p2.y;

 

    return temp;

}

 

Point operator+(int value, Point &p1)

{

    Point temp;

 

    temp.x = p1.x + value;

    temp.y = p1.y + value;

 

    return temp;

}

 

ostream &operator<<(ostream &os, Point &p1)

{

    os << p1.x << " " << p1.y << endl;

    return os;

}

 

int main()

{

    Point p1(1,2);

    Point p2(3,4);

 

    cout << p1 + p2;

    cout << 5 + p1;

 

    return 0;

}

② 相等操作符www.

    首先,“==”相等操作符的兩個(gè)對(duì)象包含相同的數(shù)據(jù),這樣才有比較性。其次,定義了operator==,同時(shí)也要定義operator!=。

friend bool operator==(Point &p1, Point &p2);

friend bool operator!=(Point &p1, Point &p2);

 

.......

 

bool operator==(Point &p1, Point &p2)

{

    return (p1.x == p2.x)&&(p1.y == p2.y);

}

 

bool operator!=(Point &p1, Point &p2)

{

    return !(p1 == p2);

}

⒊ 賦值操作符

    賦值操作符有個(gè)強(qiáng)調(diào)點(diǎn),那是賦值必須返回對(duì) *this的引用。要定義為成員函數(shù)。

Point &operator=(const Point &p1);

Point &operator+=(const Point &p1);

 

.....

 

Point &Point::operator=(const Point &p1)

{

    this->x = p1.x;

    this->y = p1.y;

 

    return *this;

}

 

Point &Point::operator+=(const Point &p1)

{

    this->x += p1.x;

    this->y += p1.y;

 

    return *this;

}

⒋ 下標(biāo)操作符

    可以從容器中檢索單個(gè)元素的容器類一般會(huì)定義下標(biāo)操作符operator[]。首先,要注意到, 下標(biāo)操作符必須定義為成員函數(shù)。其次,要定義兩個(gè)版本,一個(gè)是非const成員并返回引用。一個(gè)是為const成員并返回引用。

#include <iostream>

using namespace std;

 

class Point {

    int a[3];

public:

    Point(int i, int j, int k) {

        a[0] = i;

        a[1] = j;

        a[2] = k;

    }

    int &operator[](int &i) { return *(a + i); }

    const int &operator[](const int &i) { return *(a + i); }

 

};

 

int main()

{

    Point ob(1, 2, 3);

    cout << ob[1];

    return 0;

}

    在sgi stl中,可以看到重載的情形:(夠簡(jiǎn)潔的 )

reference operator[](size_type __n) { return *(begin() + __n); }

const_reference operator[](size_type __n) const { return *(begin() + __n); }

⒌ 成員訪問操作符

    C++中支持重載解引用操作符(*)和箭頭操作符(->),其中, 箭頭操作符必須定義為類成員函數(shù),解引用則兩者皆可。看看以下的用法:

_Reference operator*() const {

  _BidirectionalIterator __tmp = current;

  return *--__tmp;    // 返回值

}

 

pointer operator->() const { return &(operator*()); }   // 返回指針

⒍ 自增和自減操作

    a++,++a,--b,b--。是不是有點(diǎn)煩人?但是看了重載的意義之后,你就知道,這個(gè)東西是不煩人的。也知道了在for循環(huán)中為什么要強(qiáng)調(diào)用++a了。

    在C++中,并沒有特別要求說一定要為成員函數(shù),但是為成員函數(shù)是一個(gè)不錯(cuò)的選擇 。

    還有要注意的是 :

    ① 為了與內(nèi)置類型一致,前綴式操作符應(yīng)返回被增量或減量對(duì)象的引用;

    ② 后綴式返回舊值,應(yīng)作為值返回,不是返回引用,所以返回不用引用。

    現(xiàn)在看看如何使用:

Point &operator++();    // 為了與內(nèi)置類型一致,前綴式操作符應(yīng)返回被增量或減量對(duì)象的引用

Point operator++(int);    // 返回舊值,應(yīng)作為值返回,不是返回引用

 

Point &operator--();

Point operator--(int);

....

// 前增

Point &Point::operator++()

{

    ++this->x;

    ++this->y;

    return *this;

}

 

// 后增

Point Point::operator++(int)

{

    Point temp = *this;

    ++this->x;

    ++this->y;

    return temp;

}

 

// 前減

Point &Point::operator--()

{

    --this->x;

    --this->y;

    return *this;

}

 

// 后減

Point Point::operator--(int)

{

    Point temp = *this;

    --this->x;

    --this->y;

    return temp;

}

    知道為什么說要強(qiáng)調(diào)說前綴式了嗎 ?看看前綴和后綴的區(qū)別,你就知道那個(gè)效率會(huì)高。。。

    總結(jié),這些東西寫的有點(diǎn)辛苦,寫寫停停的。請(qǐng)大牛指正其中不妥之處,小菜謝謝了。。。



摘自  云端小飛象cg

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多