C++中的命名空间私有成员

4
我正在阅读Scott Meyers的C++书籍,现在我正在学习关于封装的部分。他说,除非将数据成员声明为private,否则无法将其封装起来。这是清楚的。
但是,由于我之前主要使用Java,而Java有其“包私有(package-private)”方法和成员,因此我想知道C++是否允许我们使用一些技巧,在命名空间中声明一些不可从命名空间外访问的内容。类似于命名空间私有(namespace-private)之类的东西。我认为下面使用匿名命名空间的代码会很好:
namespace A {
    namespace { //anonymous namespace within the namespace
        int a;
    }
    void foo(){ std::cout << a << std::endl; }
}

int main()
{
    A::a = 2;
    A::foo();
}

但它运行良好:http://coliru.stacked-crooked.com/a/b4690b9bb28dad29


1
一个常见的约定是使用名为 internal 的嵌套命名空间。它仍然可以访问 - 任何人都可以编写 A::internal::a - 但它清楚地向外部任何人发出信号,表明他们即将依赖于内部实现细节,这可能会带来风险。未命名的命名空间则完全不同 - 它包含的定义仅限于此翻译单元(也称源文件)。 - Igor Tandetnik
@IgorTandetnik 确实,听起来非常合理。非常感谢您的建议。 - stella
2个回答

5
我对于C++是否允许我们在命名空间中声明某些内容以使其在命名空间外不可访问很感兴趣。然而,C++本身并没有提供类似于私有成员的保护机制来限制命名空间的访问权限。
如果想要实现这样的功能,需要在特定代码库中采用一致的命名规则来实现。
这在某种程度上类似于Python方法名前缀加下划线“_”的约定,表示该方法(或数据成员)被视为“私有”,不应从外部访问。

2

命名空间 { //在命名空间内的匿名命名空间

这是未命名的命名空间声明,也就是说,它可以使用内部链接(internal linkage)进行声明,这意味着在未命名的命名空间中声明的任何名称都具有内部链接。

因此,允许执行 A::a = 2

如果将该命名空间命名为

namespace B

那么你需要做的是:
A::B::a = 2;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接