2010-01-17 49 views
26

我有一些內聯函數包含在頭文件中的命名空間內,目前還沒有將它們移動到cpp文件中的位置。其中一些內聯函數使用魔術常數,例如:隱藏內聯命名空間標題中的私有常量

// Foo.h 
namespace Foo 
{ 
    const int BAR = 1234; 

    inline void someFunc() 
    { 
     // Do something with BAR 
    } 
} 

但是,我想讓這些魔術常量爲私人 - 任何想法如何?我首先想到的是使用這樣的匿名命名空間:

// Foo.h 
namespace Foo 
{ 
    namespace 
    { 
     // 'private' constants here 
     const int BAR = 1234; 
    } 

    inline void someFunc() 
    { 
     // Do something with BAR 
    } 
} 

然而,這並不工作,Foo::BAR可用於包括Foo.h任何CPP文件?有沒有辦法做到這一點,而不創建一個實施cpp文件?

回答

28

你不能,匿名命名空間適用於它們在(或包含在你的案例中)定義的翻譯單元。
你可以考慮將它們轉移到一個detail命名空間來通知他們內部細節的用戶:

namespace foo { 
    namespace detail { 
     int magic = 42; 
    } 

    // ... use detail::magic 
} 
+4

這也是會議助推使用。只要你告訴每個人簡單的說,「永遠不要輸入詳細的命名空間」,這很好。 – GManNickG 2010-01-17 19:09:12

3

把它們放在一個特殊的命名空間或專門爲它們命名,一個項目慣例相結合,這樣的事情是不-public:

namespace foo { 
    namespace detail { // as in "implementation details" 
    inline int answer() { return 42; } 
    const int perfect = 28; 
    } 
    std::string _question(); // not part of foo's "public interface" by convention 

    int this_is_public() { 
    using namespace detail; // now don't have to prefix detail:: 
    return answer() + perfect + _question().length(); 
    } 
} 

任何使用記錄爲非公名字會規避任何「保護」你嘗試;這突出了真正的關注點:記錄什麼是公共接口的一部分,並且可能是依賴的。

未命名的命名空間解決了一個不同的問題:獲取特定TU的唯一名稱。他們在這裏沒有幫助。

16

如何:

namespace Foo { 
    class foo_detail { 
    private: 
     enum { 
      BAR = 1234, 
     }; 

     friend void someFunc(); 
    }; 

    inline 
    void someFunc() { 
     // something with foo_detail::BAR 
    } 
} 

這使得恆nonaccessible的人比你標記爲朋友的其他功能。您可以通過將構造函數設爲私有來確保沒有人嘗試實例化類,從而使該類不可構造。