4

可能重复:
为什么要使用未命名的命名空间,它们有什么好处?

查看某人的代码,这就是他们声明的内容:

namespace {

  struct myStruct {
     int x;
     int y;
  } obj1;

}

..在一个函数中,我看到它是这样使用的:

myStruct& var = obj1;

(通知namespace是匿名的。)

从我对它的使用方式来看,我无法弄清楚为什么它会这样声明和使用。

像这样声明它有什么不同?

另外,为什么指针是这样创建的,而不是这里显示的传统样式。即 myStruct *ptr;

谢谢你!

4

4 回答 4

11

在匿名命名空间中声明的所有内容都有一个唯一的、不可知的名称,因此不能从任何其他翻译单元中引用。因此,匿名命名空间被保证仅对当前翻译单元是本地的,并且永远不会与其他翻译单元发生冲突。

例如,如果您说namespace { int i; },则保证只有当前翻译单元才能看到全局i。即使此声明位于包含在多个不同 TU 中的标头中,每个 TU 也会收到其自己的全局变量副本(每个都具有不同的、不可知的完全限定名称)。

效果类似于static在 C++03 中声明一个全局对象(提供全局对象内部链接),其中匿名命名空间中的对象可能仍具有外部链接。在 C++11 中,未命名命名空间中的名称根据 3.5/4 具有内部链接,因此变量和函数的效果与声明它们的效果完全相同static——但内部链接不仅仅适用于变量和函数(例如枚举、类、模板),因此从 C++11 开始,您应该始终更喜欢未命名的命名空间!

于 2012-09-21T23:02:56.920 回答
3

在 C++ 中,您只能在给定的命名范围内拥有一个定义。如果有多个翻译单元,您仍然只能有一个定义,但编译器不能保证所有定义确实是相同的。也就是说,如果您需要本地类型,例如 astruct或 a class,您需要确保定义不会任何其他翻译单元中的任何其他类型冲突。在大型项目中这样做几乎是不可能的,除非您有办法以某种方式在本地保护您的类型。这就是未命名命名空间所提供的:在未命名命名空间中定义的任何名称在整个可执行文件中都是唯一的。

于 2012-09-21T23:04:08.110 回答
2

它与关键字的作用基本相同,static但实际上并不强制内部链接。该变量仍然是外部链接的,您无法在任何其他翻译单元中解析其名称。这是必要的,因为模板参数必须具有外部链接,或者至少曾经需要这样。

var也不是指针,它是一个引用。它不像其他指针那样被创建,因为它不是一个。

于 2012-09-21T23:05:11.567 回答
0

另外,为什么指针是这样创建的,而不是这里显示的传统样式。即 myStruct *ptr;

它是一个引用,而不是一个指针,它是用同样的原理创建myStruct& var = obj1;的,但是同样的原理也适用于指针。许多 C++程序员更myStruct* ptr喜欢myStruct *ptr. 编译器不在乎你使用哪个。这种风格偏好适用于代码的读者。myStruct& refmyStruct &ref

将星号或 & 号与类型而不是变量放在一起的原因是因为星号或 & 号在逻辑上是类型的一部分。的类型ptr是指向 的指针myStruct。该方案存在一个潜在问题:Type* ptr1, ptr2;由于从 C 继承的规则,ptr2它不是指针。这只是一个int.

这个问题有一个简单的解决方案。不要那样做!一般来说,最好在每次声明时声明一个变量,但像int i,j,k;不要混合指针和非指针这样简单的事情除外。

于 2012-09-22T01:47:31.113 回答