C++編程規範 5 範圍、模板和C++其他特性

來源:互聯網
上載者:User

5 範圍、模板和C++其他特性

  5.1  範圍

原則5.1 使用名字空間進行歸類,避免符號衝突

說明:名字空間主要解決符號衝突問題。

樣本:兩個不同項目的全域範圍都有一個類 Foo, 這樣在編譯或運行時造成衝突。如果每個項目將

代碼置於不同名字空間中

    namespace  project1
    {
       class  Foo;
       //…
    }
    namespace  project2
    {
       class  Foo;
       //…
    }
作為不同符號自然不會衝突:project1::Foo 和 project2::Foo。

建議名字空間的名稱採用全小寫,為避免衝突,可採用項目(產品組件)或目錄結構。

用名字空間把整個源檔案封裝起來, 以區別於其它名字空間,但是這些內容除外:檔案包含(include),

全域標識的聲明/定義以及類的前置聲明。

樣本:

    #include "a.h"
    DEFINE_bool(someflag, false, “dummy flag”);
   class C;                 //全域名字空間中類C的前置聲明
    namespace a{class A;}    //a::A 的前置聲明
    //以上代碼就不要放在名字空間b中。
    namespace b
    {
        //b中的代碼…
    } //namespace b

規則5.1 不要在標頭檔中或者#include之前使用using指示符

說明:使用using會影響後續代碼,易造成符號衝突,所以不要在標頭檔以及源檔案中的#include之前

使用using。

樣本:

    //標頭檔a.h
    namespace A
    {
        int f(int);
    }
    //標頭檔b.h
    namespace B
    {
        int f(int);
    }
    using namespace B;
    void g()
    {
        f(1);
    }

    //原始碼a.cpp
    #include “a.h”
    using namespace A;
    #include “b.h”
    void main()
    {
       g();//using namespace A在#include “b.h”之前,引發歧意:A::f,B::f調用不明確
    }

建議5.1 盡量少使用嵌套類

說明:一個類在另一個類中定義,這樣的類被稱為嵌套類。嵌套類是其外圍類的成員,嵌套類也被稱

為成員類。

    class Foo
    {
    private:
        //Bar是嵌套在Foo中的成員類
       class Bar
        {
           //…
        };
    };
跟其它類一樣,嵌套類可以聲明為public、priate和protected屬性,因此,從外部存取嵌套類,遵循

類成員的訪問規則。

一般來說,應該盡量少用嵌套類。嵌套類最適合用來對它們的外層類實現細節建模(如:方便實現鏈表、

容器等演算法),且在這個類需要訪問外圍類所有成員(包括私人成員)時才使用嵌套類。 不要通過嵌套
類來進行命名分組,應該使用名字空間。

建議5.2 儘可能不使用局部類

說明:定義在函數體內的類稱為局部類。局部類只在定義它的局部域內可見。

局部類的成員函數必須被定義在類定義中,且不能超過15行代碼。否則,代碼將變得很難理解。

建議5.3 使用靜態成員函數或名字空間內的非成員函數,避免使用全域函數

說明:非成員函數放在名字空間內可避免汙染全域範圍。

如果你必須定義非成員函數, 又只是在 .cpp 檔案中使用它, 也可使用static關鍵字 (如 static int

Foo() {...}) 限定其範圍。

建議5.4 避免class類型的全域變數,盡量用單件模式

說明:靜態生存周期的對象, 包括全域變數, 靜態變數, 靜態類成員變數, 以及函數靜態變數, 都必

須是原生資料類型 (POD : Plain Old Data)。

靜態變數的建構函式, 解構函式以及初始化操作的調用順序在C++標準中未明確定義,從而導致難以發

現的 bug。比如範圍結束時,某個靜態變數已經被析構了,但其他代碼還試圖訪問該變數,導致系

統崩潰。所以只允許 POD 類型的靜態變數。同樣,不允許用函數傳回值來初始化靜態變數。

  5.2  模板

模板可以衍生出一系列的類和函數,這是一種形式的代碼複用。但要注意,這種形式的複用是原始碼級

而不是目標代碼級的。也就是說,對模板的每一次執行個體化都會產生一份新的原始碼。與此相反,繼承允

許複用基類的大部分目標代碼。

濫用模板會造成三個後果:第一,代碼規模的過度膨脹;第二,當修改模板時,很難預料是否會對原先

正常工作的代碼造成不良影響;第三,很難確保模板所有可能的合法執行個體化都能正常工作。所以模板的

使用要仔細且有節制。

建議5.5 謹慎使用模板,只使用模板的基礎特性

說明:模板對編譯器的要求很高,當前對模板100%支援的編譯器幾乎沒有,因此,使用前應作測試,

特別是涉及偏特化,模板參數等進階特性時。

模板的錯誤提示比較難懂,產生的錯誤要映射回模板後才能顯示給編程者看,但映射畢竟不是錯代碼

本身,所以有時很難看懂,有時甚至失真,對於人員素質要求也高,增加了維護難度。

建議5.6 注意使用模板的代碼膨脹

說明:模板會為每個類型產生一個執行個體,如果使用不當,會產生過多執行個體,特別是根據常量執行個體化時。

建議5.7 模板類型應該使用引用或指標

說明:執行個體化和參數傳遞複雜類型(結構體,對象),傳值的代價很高;引用和指標可以提高效率。

建議5.8 模板如果有約束條件,請在模板定義處顯式說明

說明:編譯對模板的檢查較弱,很難保證檢察所有錯誤,因此進行顯式說明可以減少模板使用錯誤。
建議5.9 兩個模組之間介面中盡量不要暴露模板

說明:因為在編譯器最佳化選項開啟的情況下,其編譯的符號為不確定,導致依賴。

  5.3  其他

規則5.2 不要在extern "C"內部使用#include包含其他標頭檔

說明:在C++代碼中調用C的庫檔案,需要用extern "C"來告訴編譯器:這是一個用C寫成的庫檔案,請

用C的方式來連結它們。

嚴格的講,只應該把函數、變數以及函數類型這三種對象放置於extern "C"的內部。

如果把#include指令放在extern "C"裡面,可能會導致extern "C"嵌套而帶來如下幾個風險:

extern "C"嵌套過深,導致編譯錯誤

extern "C"嵌套後,改變其他某些檔案的編譯連結方式

建議5.10 避免使用友元

說明:友元擴大了 (但沒有打破) 類的封裝邊界。友元會導致類間強耦合,打破封裝,暴露出具體實

現,從而使友元和類的實現緊耦合;友元不可繼承,降低可繼承性。

例外:某些情況下, 相對於將類成員聲明為public, 使用友元是更好的選擇, 尤其是你只允許另一個

類訪問該類的私人成員時。

建議5.11 避免使用RTTI

說明:RTTI允許在運行時識別對象的類型。使用RTTI很容易違反“開放封閉原則”。如果要根據派生

類的類型來確定執行不同邏輯代碼, 虛函數無疑更合適,在對象內部就可以處理類型識別問題;如果

要在對象外部的代碼中判斷類型, 考慮使用雙重指派方案, 如訪問者模式,在對象本身之外確定類的

類型。所以,不建議使用RTTI,除非在一些特定場合如某些單元測試中會用到。

建議5.12 使用sizeof(變數)而不是sizeof(類型)

說明:使用 sizeof(varname),當代碼中變數類型改變時會自動更新。

    struct DATA data;
    memset(&data, 0, sizeof(data));
    memset(&data, 0, sizeof(DATA));  //當data改為其他類型時,出錯。
另外,對數組來說,sizeof(陣列變數) 並不一定是元素的個數,元素個數是sizeof(數組變

量)/sizeof(陣列變數[0])。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.