2017-05-25 22 views
5

我對使用using C++關鍵字更好地使用名稱空間的方法感到困惑。假設下面的代碼是在頭文件backtrace.h如何在C++中使用「using」關鍵字

#include <memory> 
using my_namespace1::component1; 
using my_namespace2::component2; 
namespace my_application { 
    namespace platform_logs { 
    class backtrace_log { 
      //code that creates instances of my_namespace1::component1 and my_namespace2::component2 
    }; 
    } 
} 

OR

#include <memory>  
namespace my_application { 
    namespace platform_logs { 
    using my_namespace1::component1; 
    using my_namespace2::component2; 

    class backtrace_log { 
      //code that creates instances of my_namespace1::component1 and my_namespace2::component2 
    }; 
    } 
} 

哪一個更好,爲什麼?

+0

這是一個味道和偏好問題 –

+0

@NicolBolas編輯了這個問題。 – Monku

+5

我建議不要使用深層嵌套的名稱空間(深度大於1) - 他們所做的只是讓您的代碼難以理解。使用名稱空間的主要原因是避免名稱衝突 - 如果您沒有這種衝突,則不需要複雜的名稱空間方案。 –

回答

4

在頭文件中...以下示例是邪惡。切勿在頭文件的全局範圍內使用using namespace...。它迫使批次未用於符號的用戶可能會導致很難解決問題,如果他們與其他頭衝突。

#include <memory> 
using my_namespace1::component1; 
using my_namespace2::component2; 
namespace my_application { 
    namespace platform_logs { 
    class backtrace_log { 
      //code that creates instances of my_namespace1::component1 and my_namespace2::component2 
    }; 
    } 
} 

另一方面,下一個例子很好,但要謹慎使用。它只有在你想要包含所有這些符號時纔有意義你的API內部項目名稱空間通常是這種情況,但第三方名稱空間的可能性較小。

我特別避免使用非常大的命名空間,如std::

#include <memory>  
namespace my_application { 
    namespace platform_logs { 
    using my_namespace1::component1; 
    using my_namespace2::component2; 

    class backtrace_log { 
      //code that creates instances of my_namespace1::component1 and my_namespace2::component2 
    }; 
    } 
} 
8

你應該總是拉在其它名稱空間的符號爲一個範圍越好(不污染外的命名空間),通常,只有在具體符號拉你需要,不只是整個命名空間。

(也可能會包含很多用戶),你通常應該從實踐中避免產品總數,而是更願意總是只使用在類型明確的命名空間的資格。

+0

你能否提供一些資源來提醒你?我很欣賞你對這個主題的看法,但我想要一些正式的參考來檢查。謝謝。 –

2

在你的第一個例子,只要你有

backtrace.h 

在另一個文件中的文件也將使用這些namesapces。所以,如果有人錯在你列入backtrace.h和「blax」文件寫道:「blax」也正好是在你的命名空間類或函數,例如:

my_namespace1::component1::blax 

編譯器可能會拿他的「blax 「表示」my_namespace1 :: component1 :: blax「

通過將using命名空間放置在另一個命名空間中,只需將所有這些定義包括到該命名空間中,在前面的示例中,如果使用了碰撞代碼的第二版將不會發生,因爲「my_namespace1 :: component1 :: blax」將作爲my_application :: platform_logs :: blax包含在內。

總體最編碼導遊會鼓勵你: 一)婚姻不礙着「使用命名空間」,或者至少用它只是爲了縮短(例如,使用short_namespace = first_namespace :: another_namepsace :: last_namespace)

b)如果在源文件(即.cpp或.c文件)中使用「使用名稱空間」這樣做,因爲這些文件中的定義不包括在內

c)如果在標頭中使用「名稱空間」它在另一個命名空間(如你的例子),以便它不會「泄漏」到其他文件的範圍,其中包括您的標題

+2

你能證實「它可能不依賴於使用的鏈接器」嗎? –

+2

@Jesper Juhl我的印象是,包含using語句的頭文件是未定義的行爲(例如,如果我包含ah和bh,其中b使用了一些只能在假設使用名稱空間的情況下才能工作的函數,鏈接命令的代碼可能會或可能不會編譯)...但現在我在互聯網上搜索,找不到這樣的例子,所以它有可能在閱讀時我不懂鏈接器(不是我所做的現在),我的想法扭曲了這個說法。感謝您指出,我會簡單地刪除它。 – George