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

What does putting a structure in an anonymous namespace do?

本文关键字:什么 作用 命名空间 结构      更新时间:2023-10-16

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

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

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

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

myStruct& var = obj1;

(请注意namespace是匿名的。

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

这样声明有什么不同?

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

谢谢!

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

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

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

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

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

var也不是指针,而是参考。 它不像其他指针那样创建,因为它不是一个指针。

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

它是引用,而不是指针,是用myStruct& var = obj1;创建的 但是,同样的理由也适用于指针。很多C++程序员更喜欢myStruct* ptr而不是myStruct *ptrmyStruct& ref而不是myStruct &ref。编译器不关心您使用哪个。此样式首选项适用于代码的读者。

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

这个问题有一个简单的解决方案。别这样!通常,最好为每个声明声明一个变量,但简单的事情除外int i,j,k;例如不要混合使用指针和非指针。