将结构体放在匿名命名空间中的作用是什么?

4

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

看着别人的代码,他们声明了这个:

namespace {

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

}

..在一个函数中,我看到它被用作这样:

myStruct& var = obj1;

(注意namespace是匿名的。)

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

这样声明有什么不同?

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

谢谢!


至于你问题的第二部分,引用并不是指针;更多信息请参见此处:https://dev59.com/VHVD5IYBdhLWcg3wL4mM - Ben Cottrell
1
一个匿名命名空间可以防止名称冲突,如果我没记错的话。不过我可能是错的。 - chris
1
此外,技术上 它们被称为匿名命名空间。 - Jesse Good
有关指针和引用,请参见https://dev59.com/VHVD5IYBdhLWcg3wL4mM。 - chris
4个回答

11

在匿名命名空间中声明的所有内容都会获得一个唯一且无法知晓的名称,因此无法从任何其他翻译单元中引用。匿名命名空间因此保证仅局限于当前翻译单元,并且永远不会与其他命名空间发生冲突。

例如,如果您说namespace { int i; },则可以确保只有当前翻译单元看到全局变量i。即使此声明在多个不同的翻译单元中包含的头文件中,每个翻译单元也会接收其自己的全局变量副本(每个副本具有不同的、无法知晓的全限定名称)。

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


3

C++中,对于一个命名作用域中只允许有一个定义。即使在多个编译单元中,你仍然只能有一个定义,但编译器不能保证所有的定义都是相同的。也就是说,如果你需要一个本地类型,比如structclass,你需要确保该定义不与任何其他翻译单元中的其他类型冲突。在大型项目中,要做到这一点几乎是不可能的,除非你有一种方式可以在本地保护你的类型。这就是未命名命名空间的作用:在未命名命名空间中定义的任何名称在整个可执行文件中都是唯一的。


2
它基本上与static关键字执行的操作相同,但实际上不强制内部链接。变量仍然是外部链接的,你只是没有办法在任何其他翻译单元中解析它的名称。这是必要的,因为模板参数必须具有外部链接,或者至少曾经需要这样做。 var也不是指针,它是引用。它不像其他指针一样被创建,因为它不是指针。

自C++11以来,它确实强制内部链接。 - underscore_d

0
此外,为什么要像这样创建指针而不是传统的方式。即 myStruct *ptr;
这是一个引用,而不是指针,使用 myStruct& var = obj1 创建。然而,指针也适用于同样的原理。许多 C++ 程序员更喜欢 myStruct* ptr 而不是 myStruct *ptr,myStruct& ref 而不是 myStruct &ref。编译器不关心你使用哪种方式。这种风格偏好是为了代码的读者。
将星号或和符号与类型放在一起的原因是,这个星号或和符号在逻辑上是类型的一部分。ptr 的类型是指向 myStruct 的指针。这种方案存在潜在的问题:Type* ptr1, ptr2; 由于从 C 继承的规则,ptr2 不是指针。它只是一个 int。

这个问题有一个简单的解决方案。不要那样做!通常最好每个声明声明一个变量,除了像int i,j,k;这样简单的情况。不要混用指针和非指针。


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