<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 2.1. 名字空間 > Tip > 鼓勵在 `.cc` 文件內使用匿名名字空間. 使用具名的名字空間時, 其名稱可基于項目名或相對路徑. 不要使用 _using 關鍵字_. 定義:名字空間將全局作用域細分為獨立的, 具名的作用域, 可有效防止全局作用域的命名沖突.優點: 雖然類已經提供了(可嵌套的)命名軸線 (YuleFox 注: 將命名分割在不同類的作用域內), 名字空間在這基礎上又封裝了一層. 舉例來說, 兩個不同項目的全局作用域都有一個類 `Foo`, 這樣在編譯或運行時造成沖突. 如果每個項目將代碼置于不同名字空間中, `project1::Foo` 和 `project2::Foo` 作為不同符號自然不會沖突. 缺點: 名字空間具有迷惑性, 因為它們和類一樣提供了額外的 (可嵌套的) 命名軸線. 在頭文件中使用匿名空間導致違背 C++ 的唯一定義原則 (One Definition Rule (ODR)). 結論:根據下文將要提到的策略合理使用命名空間. ## 2.1.1. 匿名名字空間 - 在 `.cc` 文件中, 允許甚至鼓勵使用匿名名字空間, 以避免運行時的命名沖突: ~~~ namespace { // .cc 文件中 // 名字空間的內容無需縮進 enum { kUNUSED, kEOF, kERROR }; // 經常使用的符號 bool AtEof() { return pos_ == kEOF; } // 使用本名字空間內的符號 EOF } // namespace ~~~ 然而, 與特定類關聯的文件作用域聲明在該類中被聲明為類型, 靜態數據成員或靜態成員函數, 而不是匿名名字空間的成員. 如上例所示, 匿名空間結束時用注釋 `// namespace` 標識. - 不要在 `.h` 文件中使用匿名名字空間. ## 2.1.2. 具名的名字空間 具名的名字空間使用方式如下: > - 用名字空間把文件包含, [gflags](http://code.google.com/p/google-gflags/) [http://code.google.com/p/google-gflags/] 的聲明/定義, 以及類的前置聲明以外的整個源文件封裝起來, 以區別于其它名字空間:> > // .h 文件 ~~~ namespace mynamespace { // 所有聲明都置于命名空間中 // 注意不要使用縮進 class MyClass { public: … void Foo(); }; } // namespace mynamespace // .cc 文件 namespace mynamespace { // 函數定義都置于命名空間中 void MyClass::Foo() { … } } // namespace mynamespace ~~~ > 通常的 `.cc` 文件包含更多, 更復雜的細節, 比如引用其他名字空間的類等. > > #include “a.h” DEFINE_bool(someflag, false, “dummy flag”); class C; // 全局名字空間中類 C 的前置聲明 namespace a { class A; } // a::A 的前置聲明 namespace b { …code for b… // b 中的代碼 } // namespace b 不要在名字空間 `std` 內聲明任何東西, 包括標準庫的類前置聲明. 在 `std` 名字空間聲明實體會導致不確定的問題, 比如不可移植. 聲明標準庫下的實體, 需要包含對應的頭文件. 最好不要使用 ``using`` 關鍵字, 以保證名字空間下的所有名稱都可以正常使用. // 禁止 —— 污染名字空間 using namespace foo; 在 `.cc` 文件, `.h` 文件的函數, 方法或類中, 可以使用 _``using`` 關鍵字_. > > > // 允許: .cc 文件中 // .h 文件的話, 必須在函數, 方法或類的內部使用 using ::foo::bar; 在 `.cc` 文件, `.h` 文件的函數, 方法或類中, 允許使用名字空間別名. > > > // 允許: .cc 文件中 // .h 文件的話, 必須在函數, 方法或類的內部使用 namespace fbz = ::foo::bar::baz; ## 2.2. 嵌套類 > Tip > 當公有嵌套類作為接口的一部分時, 雖然可以直接將他們保持在全局作用域中, 但將嵌套類的聲明置于名字空間內是更好的選擇. 定義: 在一個類內部定義另一個類; 嵌套類也被稱為 _成員類 (member class)_. class Foo { private: // Bar是嵌套在Foo中的成員類 class Bar { … }; }; 優點: 當嵌套 (或成員) 類只被外圍類使用時非常有用; 把它作為外圍類作用域內的成員, 而不是去污染外部作用域的同名類. 嵌套類可以在外圍類中做前置聲明, 然后在 `.cc` 文件中定義, 這樣避免在外圍類的聲明中定義嵌套類, 因為嵌套類的定義通常只與實現相關. 缺點: 嵌套類只能在外圍類的內部做前置聲明. 因此, 任何使用了 `Foo::Bar*` 指針的頭文件不得不包含類 `Foo` 的整個聲明. 結論: 不要將嵌套類定義成公有, 除非它們是接口的一部分, 比如, 嵌套類含有某些方法的一組選項. ## 2.3. 非成員函數、靜態成員函數和全局函數 > Tip > 使用靜態成員函數或名字空間內的非成員函數, 盡量不要用裸的全局函數. 優點: 某些情況下, 非成員函數和靜態成員函數是非常有用的, 將非成員函數放在名字空間內可避免污染全局作用域. 缺點: 將非成員函數和靜態成員函數作為新類的成員或許更有意義, 當它們需要訪問外部資源或具有重要的依賴關系時更是如此. 結論: 有時, 把函數的定義同類的實例脫鉤是有益的, 甚至是必要的. 這樣的函數可以被定義成靜態成員, 或是非成員函數. 非成員函數不應依賴于外部變量, 應盡量置于某個名字空間內. 相比單純為了封裝若干不共享任何靜態數據的靜態成員函數而創建類, 不如使用命名空間. 定義在同一編譯單元的函數, 被其他編譯單元直接調用可能會引入不必要的耦合和鏈接時依賴; 靜態成員函數對此尤其敏感. 可以考慮提取到新類中, 或者將函數置于獨立庫的名字空間內. 如果你必須定義非成員函數, 又只是在?`.cc`?文件中使用它, 可使用匿名名字空間或?`static`?鏈接關鍵字 (如?`static?int?Foo()?{...}`) 限定其作用域. ## 2.4. 局部變量 > Tip > 將函數變量盡可能置于最小作用域內, 并在變量聲明時進行初始化. C++ 允許在函數的任何位置聲明變量. 我們提倡在盡可能小的作用域中聲明變量, 離第一次使用越近越好. 這使得代碼瀏覽者更容易定位變量聲明的位置, 了解變量的類型和初始值. 特別是,應使用初始化的方式替代聲明再賦值, 比如: ~~~ int i; i = f(); // 壞——初始化和聲明分離 int j = g(); // 好——初始化時聲明 ~~~ 注意, GCC 可正確實現了?`for?(int?i?=?0;?i??10;?++i)`?(`i`?的作用域僅限?`for`?循環內), 所以其他?`for`?循環中可以重新使用?`i`. 在?`if`?和?`while`?等語句中的作用域聲明也是正確的, 如: ~~~ while (const char* p = strchr(str, ‘/’)) str = p + 1; ~~~ > Warning > 如果變量是一個對象, 每次進入作用域都要調用其構造函數, 每次退出作用域都要調用其析構函數. ~~~ // 低效的實現 for (int i = 0; i 1000000; ++i) { Foo f; // 構造函數和析構函數分別調用 1000000 次! f.DoSomething(i); } ~~~ 在循環作用域外面聲明這類變量要高效的多: ~~~ Foo f; // 構造函數和析構函數只調用 1 次 for (int i = 0; i 1000000; ++i) { f.DoSomething(i); } ~~~ ## 2.5. 靜態和全局變量 > Tip > 禁止使用 `class` 類型的靜態或全局變量: 它們會導致很難發現的 bug 和不確定的構造和析構函數調用順序. 靜態生存周期的對象, 包括全局變量, 靜態變量, 靜態類成員變量, 以及函數靜態變量, 都必須是原生數據類型 (POD : Plain Old Data): 只能是 int, char, float, 和 void, 以及 POD 類型的數組/結構體/指針. 永遠不要使用函數返回值初始化靜態變量; 不要在多線程代碼中使用非 `const` 的靜態變量. 不幸的是, 靜態變量的構造函數, 析構函數以及初始化操作的調用順序在 C++ 標準中未明確定義, 甚至每次編譯構建都有可能會發生變化, 從而導致難以發現的 bug. 比如, 結束程序時, 某個靜態變量已經被析構了, 但代碼還在跑 – 其它線程很可能 – 試圖訪問該變量, 直接導致崩潰. 所以, 我們只允許 POD 類型的靜態變量. 本條規則完全禁止 `vector` (使用 C 數組替代), `string` (使用 `const char*`), 及其它以任意方式包含或指向類實例的東東, 成為靜態變量. 出于同樣的理由, 我們不允許用函數返回值來初始化靜態變量. 如果你確實需要一個 `class` 類型的靜態或全局變量, 可以考慮在 ``main()` 函數或 `pthread_once()` 內初始化一個你永遠不會回收的指針. > Note > yospaly 譯注: > 上文提及的靜態變量泛指靜態生存周期的對象, 包括: 全局變量, 靜態變量, 靜態類成員變量, 以及函數靜態變量. ## 譯者 (YuleFox) 筆記 1. `cc` 中的匿名名字空間可避免命名沖突, 限定作用域, 避免直接使用 `using` 關鍵字污染命名空間; 1. 嵌套類符合局部使用原則, 只是不能在其他頭文件中前置聲明, 盡量不要 `public`; 1. 盡量不用全局函數和全局變量, 考慮作用域和命名空間限制, 盡量單獨形成編譯單元; 1. 多線程中的全局變量 (含靜態成員變量) 不要使用 `class` 類型 (含 STL 容器), 避免不明確行為導致的 bug. 1. 作用域的使用, 除了考慮名稱污染, 可讀性之外, 主要是為降低耦合, 提高編譯/執行效率.
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看