Google C++ style guide——C++類

1.構造函數的職責
構造函數中僅僅進行那些沒有實際意義的初始化。因爲成員變量的「有意義」的值大多不在構造函數中肯定。
可以的話,使用Init()方法集中初始化爲有意義的數據。


長處:排版方便,無需操心類是否初始化。
缺點:
1)在構造函數中不易報告錯誤,不能使用異常;
2)操做失敗會形成對象初始化失敗,引發不肯定狀態。
3)構造函數內調用虛函數。調用不會派發到子類實現中,即便當前沒有子類化實現,未來還是隱患;
4)若是有人建立該類型的全局變量,構造函數將在main()以前被調用,有可能破壞構造函數中暗含的若是條件。函數


假設,對象需要有意義的初始化。考慮使用另外的Init()方法並(或)添加一個成員標記來指示對象是否已經初始化。


2.默認構造函數
當一個類有成員變量又沒有構造函數的時候。需要定義一個默認的構造函數,不然編譯器將會本身主動生成默認構造函數。性能


默認構造函數更適合於初始化對象,使對象內部狀態一致、有效。對象


編譯器生成的構造函數並不會對對象進行初始化。
假設你定義的類繼承現有類,而你又沒有添加信的成員變量。則不需要爲新類定義默認構造函數。


3.明白的構造函數
對單參數構造函數使用C++keywordexplicit。
一般,僅僅有一個參數的構造函數可被用於轉換。
好比:定義了Foo::Foo(string name)跟void FooTest(Foo foo)
這個時候FooTest需要的是一個Foo對象做爲參數。假設你傳入的是string類型的參數的話。構造函數Foo::Foo(string name)將被調用。
並且將該字符串轉換爲一個Foo暫時對象傳給FooTest。
爲避免構造函數被調用形成隱士轉換。可以將其聲明爲explicit。繼承


所有單參數構造函數必須是明白的。接口

在類定義中,將keywordexplicit夾到單參數構造函數前。
例外:在少數狀況下,拷貝構造函數可以不聲明爲explicit;特地做爲其它類的透明包裝器的類。相似狀況應在凝視中明白說明。


4.拷貝構造函數
僅在代碼中需要拷貝一個類對象的時候使用拷貝構造函數;不需要拷貝時應使用DISALLOW_COPY_AND_ASSIGN。ci


大量的類並不需要可拷貝。也不需要一個拷貝構造函數或賦值操做。
但假設你不主動聲明它們。編譯器會爲你本身主動生成。而且是public的。
可以考慮在類的private中加入空的拷貝構造函數和賦值操做,僅僅有聲明,未定義。
爲了方便,可以使用宏DISALLOW_COPY_AND_ASSIGN。字符串


//禁止使用拷貝構造函數和賦值操做的宏
//應在類的private:中使用
#define DISALLOW_COPY_AND_ASSIGN(TypeName)               \
        TypeName(const TypeName&);//拷貝構造函數         \         
        void operator=(const TypeName&)//賦值操做函數


class Foo {
 public:
  Foo(int f);
  ~Foo();
 private:
  DISALLOW_COPY_AND_ASSIGN(Foo);
};


絕大多數狀況下都應該使用DISALLOW_COPY_AND_ASSIGN,假設類確實需要可拷貝,應該在類的頭文件裏說明原有,並適當定義拷貝構造函數和賦值操做。


5.結構體和類
僅當僅僅有數據時使用struct,其它一律使用class。
假設與STL結合,對於仿函數和特性可以不用class而是使用struct。
注意:類和結構體的成員變量使用不一樣的命名規則。
類的成員變量下面劃線(_)結尾,結構體與普通變量同樣。都是小寫。編譯器




6.繼承
使用組合一般比使用繼承更適宜,假設使用繼承的話,僅僅使用公共繼承。string


C++實踐中,繼承主要用於兩種場合:實現繼承。子類繼承父類的實現代碼;接口繼承。子類僅繼承父類的方法名稱。it


假設該類具備虛函數。其析構函數應該爲虛函數。


限定僅在子類訪問的成員函數爲protected,需要注意的是數據成員應始終爲私有。


7.多重繼承
真正需要用到多重實現繼承的時候不多。僅僅有當最多一個基類中含有實現,其它基類都是以Interface爲後綴的純藉口類時纔會使用多重繼承。


僅僅有當所有超類除第一個外都是純接口時才幹使用多重繼承。爲確保它們是純接口。這些類必須以Interface爲後綴。


8.接口
當一個類知足下面要求時,稱之爲純接口:
1)僅僅有純虛函數和靜態函數(析構函數除外);
2)沒有非靜態數據成員;
3)未定義不論什麼構造函數,假設有,也不含參數,並且爲protected。
4)假設是子類,也僅僅能繼承知足上述條件以Interface爲後綴的類。


9.操做符重載
除少數特定環境外,不要重載操做符。
通常不要重載操做符,尤爲是賦值操做(opeartor =)比較陰險,應避免重載。


假設需要的話,可以定義相似Equals(),CopyFrom()等函數。




10.存取控制
將數據成員私有化。並提供相關存取函數。
如定義變量foo_以及取值函數foo()、賦值函數set_foo()。


11.聲明次序
在類中使用特定的聲明次序:public在private以前,成員函數在數據成員前。

定義次序例如如下:public、protected、private。 每一塊中,聲明次序通常例如如下: 1)typedefs和enums; 2)常量; 3)構造函數。 4)析構函數。 5)成員函數。含靜態成員函數; 6)數據成員,含靜態數據成員。 宏DISALLOW_COPY_AND_ASSIGN至於private塊以後。做爲類的最後部分。 12.編寫短小函數 傾向於選擇短小、凝練的函數。 長函數有時是恰當的,所以對於函數長度並無嚴格限制。 假設函數超過40行。可以考慮在不影響程序結構的狀況下將其切割一下。

相關文章
相關標籤/搜索