我在头文件中的命名空间中包含一些内联函数,目前无法将它们移动到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文件的情况下执行此操作?
答案 0 :(得分:30)
您不能,匿名命名空间适用于他们定义的翻译单元(或包含在您的案例中)。
您可以考虑将它们移动到detail
命名空间,以向用户发出它们是内部详细信息的信号:
namespace foo {
namespace detail {
int magic = 42;
}
// ... use detail::magic
}
答案 1 :(得分:18)
怎么样:
namespace Foo {
class foo_detail {
private:
enum {
BAR = 1234,
};
friend void someFunc();
};
inline
void someFunc() {
// something with foo_detail::BAR
}
}
这使得除了您标记为朋友的功能之外,其他任何人都无法访问该常量。您可以通过将构造函数设置为私有来使类不可构造,以确保没有人尝试实例化该类。
答案 2 :(得分: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();
}
}
任何使用记录为非公开的姓名的人都将规避您尝试的任何“保护”;这突出了真正的关注点:记录公共界面的哪些部分,可以依赖它。
未命名的命名空间解决了另一个问题:获取特定TU的唯一名称。他们在这里没有帮助。