国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

More Effective C++:自增和自減

2019-11-17 05:33:19
字體:
供稿:網(wǎng)友

  很久以前(八十年代),沒有辦法區(qū)分++和--操作符的前綴與后綴調(diào)用。這個(gè)問題遭到程序員的報(bào)怨,于是C++語言得到了擴(kuò)展,答應(yīng)重載increment 和 decrement操作符的兩種形式。

  然而有一個(gè)句法上的問題,重載函數(shù)間的區(qū)別決定于它們的參數(shù)類型上的差異,但是不論是increment或decrement的前綴還是后綴都只有一個(gè)參數(shù)。為了解決這個(gè)語言問題,C++規(guī)定后綴形式有一個(gè)int類型參數(shù),當(dāng)函數(shù)被調(diào)用時(shí),編譯器傳遞一個(gè)0做為int參數(shù)的值給該函數(shù):

class UPInt { // "unlimited PRecision int"
public:
 UPInt& Operator++(); // ++ 前綴
 const UPInt operator++(int); // ++ 后綴
 UPInt& operator--(); // -- 前綴
 const UPInt operator--(int); // -- 后綴
 UPInt& operator+=(int); // += 操作符,UPInts
 // 與ints 相運(yùn)算
 ...
};

UPInt i;

++i; // 調(diào)用 i.operator++();
i++; // 調(diào)用 i.operator++(0);
--i; // 調(diào)用 i.operator--();
i--; // 調(diào)用 i.operator--(0);
  這個(gè)規(guī)范有一些古怪,不過你會(huì)習(xí)慣的。而尤其要注重的是這些操作符前綴與后綴形式返回值類型是不同的。前綴形式返回一個(gè)引用,后綴形式返回一個(gè)const類型。下面我們將討論++操作符的前綴與后綴形式,這些說明也同樣使用與--操作符。

  從你開始做C程序員那天開始,你就記住increment的前綴形式有時(shí)叫做“增加然后取回”,后綴形式叫做“取回然后增加”。這兩句話非常重要,因?yàn)樗鼈兪莍ncrement前綴與后綴的形式上的規(guī)范。

// 前綴形式:增加然后取回值

UPInt& UPInt::operator++()
{
 *this += 1; // 增加
 return *this; // 取回值
}

// postfix form: fetch and increment

const UPInt UPInt::operator++(int)
{
 UPInt oldValue = *this; // 取回值
 ++(*this); // 增加
 return oldValue; // 返回被取回的值
}
  后綴操作符函數(shù)沒有使用它的參數(shù)。它的參數(shù)只是用來區(qū)分前綴與后綴函數(shù)調(diào)用。假如你沒有在函數(shù)里使用參數(shù),許多編譯器會(huì)顯示警告信息,很令人討厭。為了避免這些警告信息,一種經(jīng)常使用的方法時(shí)省略掉你不想使用的參數(shù)名稱;如上所示。

  很明顯一個(gè)后綴increment必須返回一個(gè)對(duì)象(它返回的是增加前的值),但是為什么是const對(duì)象呢?假設(shè)不是const對(duì)象,下面的代碼就是正確的:

UPInt i;
i++++; // 兩次increment后綴
// 運(yùn)算
  這組代碼與下面的代碼相同:

i.operator++(0).operator++(0);
  很明顯,第一個(gè)調(diào)用的operator++函數(shù)返回的對(duì)象調(diào)用了第二個(gè)operator++函數(shù)。

  有兩個(gè)理由導(dǎo)致我們應(yīng)該厭惡上述這種做法,第一是與內(nèi)置類型行為不一致。當(dāng)設(shè)計(jì)一個(gè)類碰到問題時(shí),一個(gè)好的準(zhǔn)則是使該類的行為與int類型一致。而int類型不答應(yīng)連續(xù)進(jìn)行兩次后綴increment:

int i;
i++++; // 錯(cuò)誤!
  第二個(gè)原因是使用兩次后綴increment所產(chǎn)生的結(jié)果與調(diào)用者期望的不一致。如上所示,第二次調(diào)用operator++改變的值是第一次調(diào)用返回對(duì)象的值,而不是原始對(duì)象的值。因此假如:

i++++;
  是合法的,i將僅僅增加了一次。這與人的直覺相違反,使人迷惑(對(duì)于int類型和UPInt都是一樣),所以最好禁止這么做。

  C++禁止int類型這么做,同時(shí)你也必須禁止你自己寫的類有這樣的行為。最輕易的方法是讓后綴increment 返回const對(duì)象。當(dāng)編譯器碰到這樣的代碼:

i++++; // same as i.operator++(0).operator++(0);
  它發(fā)現(xiàn)從第一個(gè)operator++函數(shù)返回的const對(duì)象又調(diào)用operator++函數(shù),然而這個(gè)函數(shù)是一個(gè)non-const成員函數(shù),所以const對(duì)象不能調(diào)用這個(gè)函數(shù)。假如你原來想過讓一個(gè)函數(shù)返回const對(duì)象沒有任何意義,現(xiàn)在你就知道有時(shí)還是有用的,后綴increment和decrement就是例子。(更多的例子參見Effective C++ 條款21)

  假如你很關(guān)心效率問題,當(dāng)你第一次看到后綴increment函數(shù)時(shí), 你可能覺得有些問題。這個(gè)函數(shù)必須建立一個(gè)臨時(shí)對(duì)象以做為它的返回值,(參見條款19),上述實(shí)現(xiàn)代碼建立了一個(gè)顯示的臨時(shí)對(duì)象(oldValue),這個(gè)臨時(shí)對(duì)象必須被構(gòu)造并在最后被結(jié)構(gòu)。前綴increment函數(shù)沒有這樣的臨時(shí)對(duì)象。由此得出一個(gè)令人驚奇的結(jié)論,假如僅為了提高代碼效率,UPInt的調(diào)用者應(yīng)該盡量使用前綴increment,少用后綴increment,除非確實(shí)需要使用后綴increment。讓我們明確一下,當(dāng)處理用戶定義的類型時(shí),盡可能地使用前綴increment,因?yàn)樗男瘦^高。

  我們?cè)儆^察一下后綴與前綴increment 操作符。它們除了返回值不同外,所完成的功能是一樣的,即值加一。簡(jiǎn)而言之,它們被認(rèn)為功能一樣。那么你如何確保后綴increment和前綴increment的行為一致呢?當(dāng)不同的程序員去維護(hù)和升級(jí)代碼時(shí),有什么能保證它們不會(huì)產(chǎn)生差異?除非你遵守上述代碼里的原則,這才能得到確保。這個(gè)原則是后綴increment和decrement應(yīng)該根據(jù)它們的前綴形式來實(shí)現(xiàn)。你僅僅需要維護(hù)前綴版本,因?yàn)楹缶Y形式自動(dòng)與前綴形式的行為一致。

  正如你所看到的,把握前綴和后綴increment和decrement是輕易的。一旦了解了他們正確的返回值類型以及后綴操作符應(yīng)該以前綴操作符為基礎(chǔ)來實(shí)現(xiàn)的規(guī)則,就足夠了。


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 丹凤县| 赤水市| 湖北省| 呼和浩特市| 天峻县| 泸定县| 富宁县| 故城县| 榕江县| 金门县| 朝阳市| 长顺县| 浦县| 尤溪县| 高尔夫| 西乌珠穆沁旗| 长治县| 友谊县| 大连市| 壶关县| 南木林县| 斗六市| 韶关市| 嘉定区| 金湖县| 岳西县| 黄山市| 沛县| 长泰县| 慈溪市| 奉节县| 绥中县| 建湖县| 桦南县| 湄潭县| 佛坪县| 博兴县| 尤溪县| 从化市| 博湖县| 林甸县|