Сокрытие частных констант в действующем заголовке пространства имен

У меня есть некоторые действующие функции, содержавшиеся в пространстве имен в заголовочном файле, и в настоящее время не имею возможности перемещать их в 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
задан Rob 17 January 2010 в 18:49
поделиться

3 ответа

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

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

    // ... use detail::magic
}
30
ответ дан 28 November 2019 в 03:13
поделиться

поместите их в специальное пространство имен или назвать их специально, В сочетании с проектной конгрессой о том, что такие вещи являются незаметными:

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

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

Безмятенные пространства имен решают другую проблему: получать имена, уникальные для конкретного ту. Они не помогут здесь.

3
ответ дан 28 November 2019 в 03:13
поделиться

Как насчет:

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

        friend void someFunc();
    };

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

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

18
ответ дан 28 November 2019 в 03:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: