2010-01-17 2 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 доступна для любого файла CPP, который включает в себя Foo.h? Есть ли способ сделать это без создания файла cpp реализации?

ответ

28

Вы не можете использовать анонимные пространства имен для единицы перевода, в которой они определены (или включены в ваш случай).
Вы могли бы рассмотреть вопрос о переносе их в detail пространство имен, чтобы сигнализировать пользователю, что они являются внутренние детали:

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

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

Это также использование форсирования конвенции. Он работает хорошо, пока вы говорите всем простым: «Никогда не вводите пространство имен деталей», что в большинстве случаев не сделало бы этого. – GManNickG

3

Поместите их в специальном пространстве имен или имя их специально, в сочетании с конвенцией проекта, что такие вещи, которые не -публичный:

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(); 
    } 
} 

любое использование имен документированные в непубличных обойдет любую «защиту» вы пытаетесь; что подчеркивает реальную проблему: документирование того, что является частью публичного интерфейса и на которое можно положиться.

Пространства имен по-разному решают другую проблему: получение уникальных имен для конкретного ТУ. Они здесь не помогут.

16

Как насчет:

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

     friend void someFunc(); 
    }; 

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

Это делает константу nonaccessible для кого, чем функции вы маркируют как друзья. Вы можете сделать класс неконструктивным, сделав конструктор закрытым, чтобы убедиться, что никто не пытается инициализировать класс.

Смежные вопросы