国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
轉(zhuǎn):Google C++ 編程
早上起來看微博,看到大神們又在關(guān)于C++的各種討論,找相關(guān)知識來看看,搜到了這篇文章。
Google有很多自己實現(xiàn)的使C++代碼更加健壯的技巧、功能,以及有異于別處的C++的使用方式。
1. 智能指針(Smart Pointers)
如果確實需要使用智能指針的話,scoped_ptr完全可以勝任。在非常特殊的情況下,例如對STL容器中對象,你應(yīng)該只使用std::tr1::shared_ptr,任何情況下都不要使用auto_ptr。
“智能”指針看上去是指針,其實是附加了語義的對象。以scoped_ptr為例,scoped_ptr被銷毀時,刪除了它所指向的對象。shared_ptr也是如此,而且,shared_ptr實現(xiàn)了引用計數(shù)(reference-counting),從而只有當(dāng)它所指向的最后一個對象被銷毀時,指針才會被刪除。
一般來說,我們傾向于設(shè)計對象隸屬明確的代碼,最明確的對象隸屬是根本不使用指針,直接將對象作為一個域(field)或局部變量使用。另一種極端是引用計數(shù)指針不屬于任何對象,這樣設(shè)計的問題是容易導(dǎo)致循環(huán)引用或其他導(dǎo)致對象無法刪除的詭異條件,而且在每一次拷貝或賦值時連原子操作都會很慢。
雖然不推薦這么做,但有些時候,引用計數(shù)指針是最簡單有效的解決方案。
譯者注:看來,Google所謂的不同之處,在于盡量避免使用智能指針:D,使用時也盡量局部化,并且,安全第一。
其他C++特性
1. 引用參數(shù)(Reference Arguments)
所以按引用傳遞的參數(shù)必須加上const。
定義:在C語言中,如果函數(shù)需要修改變量的值,形參(parameter)必須為指針,如int foo(int *pval)。在C++中,函數(shù)還可以聲明引用形參:int foo(int &val)。
優(yōu)點:定義形參為引用避免了像(*pval)++這樣丑陋的代碼,像拷貝構(gòu)造函數(shù)這樣的應(yīng)用也是必需的,而且不像指針那樣不接受空指針NULL。
缺點:容易引起誤解,因為引用在語法上是值卻擁有指針的語義。
結(jié)論:
函數(shù)形參表中,所有引用必須是const:
void Foo(const string &in, string *out);
事實上這是一個硬性約定:輸入?yún)?shù)為值或常數(shù)引用,輸出參數(shù)為指針;輸入?yún)?shù)可以是常數(shù)指針,但不能使用非常數(shù)引用形參。
在強調(diào)參數(shù)不是拷貝而來,在對象生命期內(nèi)必須一直存在時可以使用常數(shù)指針,最好將這些在注釋中詳細(xì)說明。bind2nd和mem_fun等STL適配器不接受引用形參,這種情況下也必須以指針形參聲明函數(shù)。
2. 函數(shù)重載(Function Overloading)
僅在輸入?yún)?shù)類型不同、功能相同時使用重載函數(shù)(含構(gòu)造函數(shù)),不要使用函數(shù)重載模仿缺省函數(shù)參數(shù)。
定義:可以定義一個函數(shù)參數(shù)類型為const string&,并定義其重載函數(shù)類型為const char*。
class MyClass {
public:
void Analyze(const string &text);
void Analyze(const char *text, size_t textlen);
};
優(yōu)點:通過重載不同參數(shù)的同名函數(shù),令代碼更加直觀,模板化代碼需要重載,同時為訪問者帶來便利。
缺點:限制使用重載的一個原因是在特定調(diào)用處很難確定到底調(diào)用的是哪個函數(shù),另一個原因是當(dāng)派生類只重載函數(shù)的部分變量會令很多人對繼承語義產(chǎn)生困惑。此外在閱讀庫的客戶端代碼時,因缺省函數(shù)參數(shù)造成不必要的費解。
結(jié)論:如果你想重載一個函數(shù),考慮讓函數(shù)名包含參數(shù)信息,例如,使用AppendString()、AppendInt()而不是Append()。
3. 缺省參數(shù)(Default Arguments)
禁止使用缺省函數(shù)參數(shù)。
優(yōu)點:經(jīng)常用到一個函數(shù)帶有大量缺省值,偶爾會重寫一下這些值,缺省參數(shù)為很少涉及的例外情況提供了少定義一些函數(shù)的方便。
缺點:大家經(jīng)常會通過查看現(xiàn)有代碼確定如何使用API,缺省參數(shù)使得復(fù)制粘貼以前的代碼難以呈現(xiàn)所有參數(shù),當(dāng)缺省參數(shù)不適用于新代碼時可能導(dǎo)致重大問題。
結(jié)論:所有參數(shù)必須明確指定,強制程序員考慮API和傳入的各參數(shù)值,避免使用可能不為程序員所知的缺省參數(shù)。
4. 變長數(shù)組和alloca(Variable-Length Arrays and alloca())
禁止使用變長數(shù)組和alloca()。
優(yōu)點:變長數(shù)組具有渾然天成的語法,變長數(shù)組和alloca()也都很高效。
缺點:變長數(shù)組和alloca()不是標(biāo)準(zhǔn)C++的組成部分,更重要的是,它們在堆棧(stack)上根據(jù)數(shù)據(jù)分配大小可能導(dǎo)致難以發(fā)現(xiàn)的內(nèi)存泄漏:“在我的機器上運行的好好的,到了產(chǎn)品中卻莫名其妙的掛掉了”。
結(jié)論:
使用安全的分配器(allocator),如scoped_ptr/scoped_array。
5. 友元(Friends)
允許合理使用友元類及友元函數(shù)。
通常將友元定義在同一文件下,避免讀者跑到其他文件中查找其對某個類私有成員的使用。經(jīng)常用到友元的一個地方是將FooBuilder聲明為Foo的友元,F(xiàn)ooBuilder以便可以正確構(gòu)造Foo的內(nèi)部狀態(tài),而無需將該狀態(tài)暴露出來。某些情況下,將一個單元測試用類聲明為待測類的友元會很方便。
友元延伸了(但沒有打破)類的封裝界線,當(dāng)你希望只允許另一個類訪問某個成員時,使用友元通常比將其聲明為public要好得多。當(dāng)然,大多數(shù)類應(yīng)該只提供公共成員與其交互。
6. 異常(Exceptions)
不要使用C++異常。
優(yōu)點:
1) 異常允許上層應(yīng)用決定如何處理在底層嵌套函數(shù)中發(fā)生的“不可能發(fā)生”的失敗,不像出錯代碼的記錄那么模糊費解;
2) 應(yīng)用于其他很多現(xiàn)代語言中,引入異常使得C++與Python、Java及其他與C++相近的語言更加兼容;
3) 許多C++第三方庫使用異常,關(guān)閉異常將導(dǎo)致難以與之結(jié)合;
4) 異常是解決構(gòu)造函數(shù)失敗的唯一方案,雖然可以通過工廠函數(shù)(factory function)或Init()方法模擬異常,但他們分別需要堆分配或新的“非法”狀態(tài);
5) 在測試框架(testing framework)中,異常確實很好用。
缺點:
1) 在現(xiàn)有函數(shù)中添加throw語句時,必須檢查所有調(diào)用處,即使它們至少具有基本的異常安全保護,或者程序正常結(jié)束,永遠(yuǎn)不可能捕獲該異常。例如:if f() calls g() calls h(),h拋出被f捕獲的異常,g就要當(dāng)心了,避免沒有完全清理;
2) 通俗一點說,異常會導(dǎo)致程序控制流(control flow)通過查看代碼無法確定:函數(shù)有可能在不確定的地方返回,從而導(dǎo)致代碼管理和調(diào)試?yán)щy,當(dāng)然,你可以通過規(guī)定何時何地如何使用異常來最小化的降低開銷,卻給開發(fā)人員帶來掌握這些規(guī)定的負(fù)擔(dān);
3) 異常安全需要RAII和不同編碼實踐。輕松、正確編寫異常安全代碼需要大量支撐。允許使用異常;
4) 加入異常使二進制執(zhí)行代碼體積變大,增加了編譯時長(或許影響不大),還可能增加地址空間壓力;
5) 異常的實用性可能會刺激開發(fā)人員在不恰當(dāng)?shù)臅r候拋出異常,或者在不安全的地方從異常中恢復(fù),例如,非法用戶輸入可能導(dǎo)致拋出異常。如果允許使用異常會使得這樣一篇編程風(fēng)格指南長出很多(譯者注,這個理由有點牽強:-()!
結(jié)論:
從表面上看,使用異常利大于弊,尤其是在新項目中,然而,對于現(xiàn)有代碼,引入異常會牽連到所有依賴代碼。如果允許異常在新項目中使用,在跟以前沒有使用異常的代碼整合時也是一個麻煩。因為Google現(xiàn)有的大多數(shù)C++代碼都沒有異常處理,引入帶有異常處理的新代碼相當(dāng)困難。
鑒于Google現(xiàn)有代碼不接受異常,在現(xiàn)有代碼中使用異常比在新項目中使用的代價多少要大一點,遷移過程會比較慢,也容易出錯。我們也不相信異常的有效替代方案,如錯誤代碼、斷言等,都是嚴(yán)重負(fù)擔(dān)。
我們并不是基于哲學(xué)或道德層面反對使用異常,而是在實踐的基礎(chǔ)上。因為我們希望使用Google上的開源項目,但項目中使用異常會為此帶來不便,因為我們也建議不要在Google上的開源項目中使用異常,如果我們需要把這些項目推倒重來顯然不太現(xiàn)實。
對于Windows代碼來說,這一點有個例外(等到最后一篇吧:D)。
譯者注:對于異常處理,顯然不是短短幾句話能夠說清楚的,以構(gòu)造函數(shù)為例,很多C++書籍上都提到當(dāng)構(gòu)造失敗時只有異??梢蕴幚?,Google禁止使用異常這一點,僅僅是為了自身的方便,說大了,無非是基于軟件管理成本上,實際使用中還是自己決定。
7. 運行時類型識別(Run-Time Type Information, RTTI)
我們禁止使用RTTI。
定義:RTTI允許程序員在運行時識別C++類對象的類型。
優(yōu)點:
RTTI在某些單元測試中非常有用,如在進行工廠類測試時用于檢驗一個新建對象是否為期望的動態(tài)類型。
除測試外,極少用到。
缺點:運行時識別類型意味著設(shè)計本身有問題,如果你需要在運行期間確定一個對象的類型,這通常說明你需要重新考慮你的類的設(shè)計。
結(jié)論:
除單元測試外,不要使用RTTI,如果你發(fā)現(xiàn)需要所寫代碼因?qū)ο箢愋筒煌鴦幼鞲鳟惖脑?,考慮換一種方式識別對象類型。
虛函數(shù)可以實現(xiàn)隨子類類型不同而執(zhí)行不同代碼,工作都是交給對象本身去完成。
如果工作在對象之外的代碼中完成,考慮雙重分發(fā)方案,如Visitor模式,可以方便的在對象本身之外確定類的類型。
如果你認(rèn)為上面的方法你掌握不了,可以使用RTTI,但務(wù)必請三思,不要去手工實現(xiàn)一個貌似RTTI的方案(RTTI-like workaround),我們反對使用RTTI,同樣反對貼上類型標(biāo)簽的貌似類繼承的替代方案(譯者注,使用就使用吧,不使用也不要造輪子:D)。
8. 類型轉(zhuǎn)換(Casting)
使用static_cast<>()等C++的類型轉(zhuǎn)換,不要使用int y = (int)x或int y = int(x);。
定義:C++引入了有別于C的不同類型的類型轉(zhuǎn)換操作。
優(yōu)點:C語言的類型轉(zhuǎn)換問題在于操作比較含糊:有時是在做強制轉(zhuǎn)換(如(int)3.5),有時是在做類型轉(zhuǎn)換(如(int)"hello")。另外,C++的類型轉(zhuǎn)換查找更容易、更醒目。
缺點:語法比較惡心(nasty)。
結(jié)論:使用C++風(fēng)格而不要使用C風(fēng)格類型轉(zhuǎn)換。
1) static_cast:和C風(fēng)格轉(zhuǎn)換相似可做值的強制轉(zhuǎn)換,或指針的父類到子類的明確的向上轉(zhuǎn)換;
2) const_cast:移除const屬性;
3) reinterpret_cast:指針類型和整型或其他指針間不安全的相互轉(zhuǎn)換,僅在你對所做一切了然于心時使用;
4) dynamic_cast:除測試外不要使用,除單元測試外,如果你需要在運行時確定類型信息,說明設(shè)計有缺陷(參考RTTI)。
9. 流(Streams)
只在記錄日志時使用流。
定義:流是printf()和scanf()的替代。
優(yōu)點:有了流,在輸出時不需要關(guān)心對象的類型,不用擔(dān)心格式化字符串與參數(shù)列表不匹配(雖然在gcc中使用printf也不存在這個問題),打開、關(guān)閉對應(yīng)文件時,流可以自動構(gòu)造、析構(gòu)。
缺點:流使得pread()等功能函數(shù)很難執(zhí)行,如果不使用printf之類的函數(shù)而是使用流很難對格式進行操作(尤其是常用的格式字符串%.*s),流不支持字符串操作符重新定序(%1s),而這一點對國際化很有用。
結(jié)論:
不要使用流,除非是日志接口需要,使用printf之類的代替。
使用流還有很多利弊,代碼一致性勝過一切,不要在代碼中使用流。
拓展討論:
對這一條規(guī)則存在一些爭論,這兒給出深層次原因?;貞浳ㄒ恍栽瓌t(Only One Way):我們希望在任何時候都只使用一種確定的I/O類型,使代碼在所有I/O處保持一致。因此,我們不希望用戶來決定是使用流還是printf + read/write,我們應(yīng)該決定到底用哪一種方式。把日志作為例外是因為流非常適合這么做,也有一定的歷史原因。
流的支持者們主張流是不二之選,但觀點并不是那么清晰有力,他們所指出流的所有優(yōu)勢也正是其劣勢所在。流最大的優(yōu)勢是在輸出時不需要關(guān)心輸出對象的類型,這是一個亮點,也是一個不足:很容易用錯類型,而編譯器不會報警。使用流時容易造成的一類錯誤是:
cout << this; // Prints the addresscout << *this; // Prints the contents
編譯器不會報錯,因為<<被重載,就因為這一點我們反對使用操作符重載。
有人說printf的格式化丑陋不堪、易讀性差,但流也好不到哪兒去??纯聪旅鎯啥未a吧,哪個更加易讀?
cerr << "Error connecting to '" << foo->bar()->hostname.first << ":" << foo->bar()->hostname.second << ": " << strerror(errno);fprintf(stderr, "Error connecting to '%s:%u: %s", foo->bar()->hostname.first, foo->bar()->hostname.second, strerror(errno));
你可能會說,“把流封裝一下就會比較好了”,這兒可以,其他地方呢?而且不要忘了,我們的目標(biāo)是使語言盡可能小,而不是添加一些別人需要學(xué)習(xí)的新的內(nèi)容。
每一種方式都是各有利弊,“沒有最好,只有更好”,簡單化的教條告誡我們必須從中選擇其一,最后的多數(shù)決定是printf + read/write。
10. 前置自增和自減(Preincrement and Predecrement)
對于迭代器和其他模板對象使用前綴形式(++i)的自增、自減運算符。
定義:對于變量在自增(++i或i++)或自減(--i或i--)后表達式的值又沒有沒用到的情況下,需要確定到底是使用前置還是后置的自增自減。
優(yōu)點:不考慮返回值的話,前置自增(++i)通常要比后置自增(i++)效率更高,因為后置的自增自減需要對表達式的值i進行一次拷貝,如果i是迭代器或其他非數(shù)值類型,拷貝的代價是比較大的。既然兩種自增方式動作一樣(譯者注,不考慮表達式的值,相信你知道我在說什么),為什么不直接使用前置自增呢?
缺點:C語言中,當(dāng)表達式的值沒有使用時,傳統(tǒng)的做法是使用后置自增,特別是在for循環(huán)中,有些人覺得后置自增更加易懂,因為這很像自然語言,主語(i)在謂語動詞(++)前。
結(jié)論:對簡單數(shù)值(非對象)來說,兩種都無所謂,對迭代器和模板類型來說,要使用前置自增(自減)。
11. const的使用(Use of const)
我們強烈建議你在任何可以使用的情況下都要使用const。
定義:在聲明的變量或參數(shù)前加上關(guān)鍵字const用于指明變量值不可修改(如const int foo),為類中的函數(shù)加上const限定表明該函數(shù)不會修改類成員變量的狀態(tài)(如class Foo { int Bar(char c) const; };)。
優(yōu)點:人們更容易理解變量是如何使用的,編輯器可以更好地進行類型檢測、更好地生成代碼。人們對編寫正確的代碼更加自信,因為他們知道所調(diào)用的函數(shù)被限定了能或不能修改變量值。即使是在無鎖的多線程編程中,人們也知道什么樣的函數(shù)是安全的。
缺點:如果你向一個函數(shù)傳入const變量,函數(shù)原型中也必須是const的(否則變量需要const_cast類型轉(zhuǎn)換),在調(diào)用庫函數(shù)時這尤其是個麻煩。
結(jié)論:const變量、數(shù)據(jù)成員、函數(shù)和參數(shù)為編譯時類型檢測增加了一層保障,更好的盡早發(fā)現(xiàn)錯誤。因此,我們強烈建議在任何可以使用的情況下使用const:
1) 如果函數(shù)不會修改傳入的引用或指針類型的參數(shù),這樣的參數(shù)應(yīng)該為const;
2) 盡可能將函數(shù)聲明為const,訪問函數(shù)應(yīng)該總是const,其他函數(shù)如果不會修改任何數(shù)據(jù)成員也應(yīng)該是const,不要調(diào)用非const函數(shù),不要返回對數(shù)據(jù)成員的非const指針或引用;
3) 如果數(shù)據(jù)成員在對象構(gòu)造之后不再改變,可將其定義為const。
然而,也不要對const過度使用,像const int * const * const x;就有些過了,即便這樣寫精確描述了x,其實寫成const int** x就可以了。
關(guān)鍵字mutable可以使用,但是在多線程中是不安全的,使用時首先要考慮線程安全。
const位置:
有人喜歡int const *foo形式不喜歡const int* foo,他們認(rèn)為前者更加一致因此可讀性更好:遵循了const總位于其描述的對象(int)之后的原則。但是,一致性原則不適用于此,“不要過度使用”的權(quán)威抵消了一致性使用。將const放在前面才更易讀,因為在自然語言中形容詞(const)是在名詞(int)之前的。
這是說,我們提倡const在前,并不是要求,但要兼顧代碼的一致性!
12. 整型(Integer Types)
C++內(nèi)建整型中,唯一用到的是int,如果程序中需要不同大小的變量,可以使用<stdint.h>中的精確寬度(precise-width)的整型,如int16_t。
定義:C++沒有指定整型的大小,通常人們認(rèn)為short是16位,int是32位,long是32位,long long是64位。
優(yōu)點:保持聲明統(tǒng)一。
缺點:C++中整型大小因編譯器和體系結(jié)構(gòu)的不同而不同。
結(jié)論:
<stdint.h>定義了int16_t、uint32_t、int64_t等整型,在需要確定大小的整型時可以使用它們代替short、unsigned long long等,在C整型中,只使用int。適當(dāng)情況下,推薦使用標(biāo)準(zhǔn)類型如size_t和ptrdiff_t。
最常使用的是,對整數(shù)來說,通常不會用到太大,如循環(huán)計數(shù)等,可以使用普通的int。你可以認(rèn)為int至少為32位,但不要認(rèn)為它會多于32位,需要64位整型的話,可以使用int64_t或uint64_t。
對于大整數(shù),使用int64_t。
不要使用uint32_t等無符號整型,除非你是在表示一個位組(bit pattern)而不是一個數(shù)值。即使數(shù)值不會為負(fù)值也不要使用無符號類型,使用斷言(assertion,譯者注,這一點很有道理,計算機只會根據(jù)變量、返回值等有無符號確定數(shù)值正負(fù),仍然無法確定對錯)來保護數(shù)據(jù)。
無符號整型:
有些人,包括一些教科書作者,推薦使用無符號類型表示非負(fù)數(shù),類型表明了數(shù)值取值形式。但是,在C語言中,這一優(yōu)點被由其導(dǎo)致的bugs所淹沒??纯矗?div style="height:15px;">
for (unsigned int i = foo.Length()-1; i >= 0; --i) ...
上述代碼永遠(yuǎn)不會終止!有時gcc會發(fā)現(xiàn)該bug并報警,但通常不會。類似的bug還會出現(xiàn)在比較有符合變量和無符號變量時,主要是C的類型提升機制(type-promotion scheme,C語言中各種內(nèi)建類型之間的提升轉(zhuǎn)換關(guān)系)會致使無符號類型的行為出乎你的意料。
因此,使用斷言聲明變量為非負(fù)數(shù),不要使用無符號型。
13. 64位下的可移植性(64-bit Portability)
代碼在64位和32位的系統(tǒng)中,原則上應(yīng)該都比較友好,尤其對于輸出、比較、結(jié)構(gòu)對齊(structure alignment)來說:
1) printf()指定的一些類型在32位和64位系統(tǒng)上可移植性不是很好,C99標(biāo)準(zhǔn)定義了一些可移植的格式。不幸的是,MSVC 7.1并非全部支持,而且標(biāo)準(zhǔn)中也有所遺漏。所以有時我們就不得不自己定義丑陋的版本(使用標(biāo)準(zhǔn)風(fēng)格要包含文件inttypes.h):
// printf macros for size_t, in the style of inttypes.h#ifdef _LP64#define __PRIS_PREFIX "z"#else#define __PRIS_PREFIX#endif// Use these macros after a % in a printf format string// to get correct 32/64 bit behavior, like this:// size_t size = records.size();// printf("%"PRIuS"\n", size);#define PRIdS __PRIS_PREFIX "d"#define PRIxS __PRIS_PREFIX "x"#define PRIuS __PRIS_PREFIX "u"#define PRIXS __PRIS_PREFIX "X"#define PRIoS __PRIS_PREFIX "o"
類型不要使用使用備注
void *(或其他指針類型)%lx%p
int64_t%qd, %lld%"PRId64"
uint64_t%qu, %llu, %llx%"PRIu64", %"PRIx64"
size_t%u%"PRIuS", %"PRIxS"C99指定%zu
ptrdiff_t%d%"PRIdS"C99指定%zd
注意宏P(guān)RI*會被編譯器擴展為獨立字符串,因此如果使用非常量的格式化字符串,需要將宏的值而不是宏名插入格式中,在使用宏P(guān)RI*時同樣可以在%后指定長度等信息。例如,printf("x = %30"PRIuS"\n", x)在32位Linux上將被擴展為printf("x = %30" "u" "\n", x),編譯器會處理為printf("x = %30u\n", x)。
2) 記住sizeof(void *) != sizeof(int),如果需要一個指針大小的整數(shù)要使用intptr_t。
3) 需要對結(jié)構(gòu)對齊加以留心,尤其是對于存儲在磁盤上的結(jié)構(gòu)體。在64位系統(tǒng)中,任何擁有int64_t/uint64_t成員的類/結(jié)構(gòu)體將默認(rèn)被處理為8字節(jié)對齊。如果32位和64位代碼共用磁盤上的結(jié)構(gòu)體,需要確保兩種體系結(jié)構(gòu)下的結(jié)構(gòu)體的對齊一致。大多數(shù)編譯器提供了調(diào)整結(jié)構(gòu)體對齊的方案。gcc中可使用__attribute__((packed)),MSVC提供了#pragma pack()和__declspec(align())(譯者注,解決方案的項目屬性里也可以直接設(shè)置)。
4) 創(chuàng)建64位常量時使用LL或ULL作為后綴,如:
int64_t my_value = 0x123456789LL;uint64_t my_mask = 3ULL << 48;
5) 如果你確實需要32位和64位系統(tǒng)具有不同代碼,可以在代碼變量前使用。(盡量不要這么做,使用時盡量使修改局部化)。
14. 預(yù)處理宏(Preprocessor Macros)
使用宏時要謹(jǐn)慎,盡量以內(nèi)聯(lián)函數(shù)、枚舉和常量代替之。
宏意味著你和編譯器看到的代碼是不同的,因此可能導(dǎo)致異常行為,尤其是當(dāng)宏存在于全局作用域中。
值得慶幸的是,C++中,宏不像C中那么必要。宏內(nèi)聯(lián)效率關(guān)鍵代碼(performance-critical code)可以內(nèi)聯(lián)函數(shù)替代;宏存儲常量可以const變量替代;宏“縮寫”長變量名可以引用替代;使用宏進行條件編譯,這個……,最好不要這么做,會令測試更加痛苦(#define防止頭文件重包含當(dāng)然是個例外)。
宏可以做一些其他技術(shù)無法實現(xiàn)的事情,在一些代碼庫(尤其是底層庫中)可以看到宏的某些特性(如字符串化(stringifying,譯者注,使用#)、連接(concatenation,譯者注,使用##)等等)。但在使用前,仔細(xì)考慮一下能不能不使用宏實現(xiàn)同樣效果。
譯者注:關(guān)于宏的高級應(yīng)用,可以參考C語言宏的高級應(yīng)用。
下面給出的用法模式可以避免一些使用宏的問題,供使用宏時參考:
1) 不要在.h文件中定義宏;
2) 使用前正確#define,使用后正確#undef;
3) 不要只是對已經(jīng)存在的宏使用#undef,選擇一個不會沖突的名稱;
4) 不使用會導(dǎo)致不穩(wěn)定的C++構(gòu)造(unbalanced C++ constructs,譯者注)的宏,至少文檔說明其行為。
15. 0和NULL(0 and NULL)
整數(shù)用0,實數(shù)用0.0,指針用NULL,字符(串)用'\0'。
整數(shù)用0,實數(shù)用0.0,這一點是毫無爭議的。
對于指針(地址值),到底是用0還是NULL,Bjarne Stroustrup建議使用最原始的0,我們建議使用看上去像是指針的NULL,事實上一些C++編譯器(如gcc 4.1.0)專門提供了NULL的定義,可以給出有用的警告,尤其是sizeof(NULL)和sizeof(0)不相等的情況。
字符(串)用'\0',不僅類型正確而且可讀性好。
16. sizeof(sizeof)
盡可能用sizeof(varname)代替sizeof(type)。
使用sizeof(varname)是因為當(dāng)變量類型改變時代碼自動同步,有些情況下sizeof(type)或許有意義,還是要盡量避免,如果變量類型改變的話不能同步。
Struct data;memset(&data, 0, sizeof(data));memset(&data, 0, sizeof(Struct));
17. Boost庫(Boost)
只使用Boost中被認(rèn)可的庫。
定義:Boost庫集是一個非常受歡迎的、同級評議的(peer-reviewed)、免費的、開源的C++庫。
優(yōu)點:Boost代碼質(zhì)量普遍較高、可移植性好,填補了C++標(biāo)準(zhǔn)庫很多空白,如型別特性(type traits)、更完善的綁定(binders)、更好的智能指針,同時還提供了TR1(標(biāo)準(zhǔn)庫的擴展)的實現(xiàn)。
缺點:某些Boost庫提倡的編程實踐可讀性差,像元程序(metaprogramming)和其他高級模板技術(shù),以及過度“函數(shù)化”("functional")的編程風(fēng)格。
結(jié)論:為了向閱讀和維護代碼的人員提供更好的可讀性,我們只允許使用Boost特性的一個成熟子集,當(dāng)前,這些庫包括:
1) Compressed Pair:boost/compressed_pair.hpp;
2) Pointer Container:boost/ptr_container不包括ptr_array.hpp和序列化(serialization)。
我們會積極考慮添加可以的Boost特性,所以不必拘泥于該規(guī)則。
______________________________________
譯者:關(guān)于C++特性的注意事項,總結(jié)一下:
1. 對于智能指針,安全第一、方便第二,盡可能局部化(scoped_ptr);
2. 引用形參加上const,否則使用指針形參;
3. 函數(shù)重載的使用要清晰、易讀;
4. 鑒于容易誤用,禁止使用缺省函數(shù)參數(shù)(值得商榷);
5. 禁止使用變長數(shù)組;
6. 合理使用友元;
7. 為了方便代碼管理,禁止使用異常(值得商榷);
8. 禁止使用RTTI,否則重新設(shè)計代碼吧;
9. 使用C++風(fēng)格的類型轉(zhuǎn)換,除單元測試外不要使用dynamic_cast;
10. 使用流還printf + read/write,it is a problem;
11. 能用前置自增/減不用后置自增/減;
12. const能用則用,提倡const在前;
13. 使用確定大小的整型,除位組外不要使用無符號型;
14. 格式化輸出及結(jié)構(gòu)對齊時,注意32位和64位的系統(tǒng)差異;
15. 除字符串化、連接外盡量避免使用宏;
16. 整數(shù)用0,實數(shù)用0.0,指針用NULL,字符(串)用'\0';
17. 用sizeof(varname)代替sizeof(type);
18. 只使用Boost中被認(rèn)可的庫。
原文鏈接:http://www.cnblogs.com/vs2008_taotao/archive/2010/08/18/1801984.html
今天把Google的C++編程(50頁)規(guī)范找來看了一下,真是一寫代碼就知道你是不是專業(yè)的啊!
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
為什么很多人編程喜歡用typedef?如何避免濫用?
為什么很多人編程喜歡用typedef?
5. 其他 C++ 特性
第九章 C99可變長數(shù)組VLA詳解
C語言中實現(xiàn)模板函數(shù)小結(jié) : 不敢流淚
C\C |指針詳述及實例分析
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服