У меня есть некоторые действующие функции, содержавшиеся в пространстве имен в заголовочном файле, и в настоящее время не имею возможности перемещать их в 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 файл?
Вы не можете, анонимные пространства имен работают для блока перевода, которые они определены в (или включены в ваш случай).
Вы могли бы рассмотреть возможность перемещения их в детали
пространства имен , чтобы сигнализировать пользователю, что они являются внутренними деталями:
namespace foo {
namespace detail {
int magic = 42;
}
// ... use detail::magic
}
поместите их в специальное пространство имен или назвать их специально, В сочетании с проектной конгрессой о том, что такие вещи являются незаметными:
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();
}
}
любой, кто использует имена, документированные как непубличные, будут обходить любую «защиту», которую вы пытаетесь; Что подчеркивает реальную обеспокоенность: документируя то, что является частью общедоступного интерфейса и может быть наложена.
Безмятенные пространства имен решают другую проблему: получать имена, уникальные для конкретного ту. Они не помогут здесь.
Как насчет:
namespace Foo {
class foo_detail {
private:
enum {
BAR = 1234,
};
friend void someFunc();
};
inline
void someFunc() {
// something with foo_detail::BAR
}
}
Это делает постоянную непрозрачную для кого-либо еще, чем функции, которые вы отмечаете как друзей. Вы можете сделать класс непонтрозненным, сделав конструктора, чтобы убедиться, что никто не пытается указать класс.