可能重复:
Why are unnamed namespaces used and what are their benefits?
查看某些代码,这就是他们声明的内容:
namespace {
struct myStruct {
int x;
int y;
} obj1;
}
..在一个函数中,我看到它像这样使用:
myStruct& var = obj1;
(注意namespace
是匿名的。)
从我看到它的使用方式来看,我无法弄清楚为什么会这样宣告和使用它。
宣布这样做的做法有何不同?
另外,为什么指针是这样创建的而不是传统的样式shown here。即myStruct * ptr;
谢谢!
答案 0 :(得分:9)
在匿名命名空间内声明的所有内容都会获得一个唯一的,不可知的名称,因此无法从任何其他翻译单元引用。因此,匿名命名空间仅保证是当前翻译单元的本地名称空间,并且永远不会与其他翻译单元冲突。
例如,如果您说namespace { int i; }
,则可以保证只有当前翻译单元才会看到全局i
。即使此声明位于包含在多个不同TU中的标头中,每个TU也会接收其全局变量的自己的副本(每个都具有不同的,不可知的完全限定名称)。
该效果类似于在C ++ 03中声明全局对象static
(它提供全局对象内部链接),其中匿名命名空间中的对象可能仍然具有外部链接。在C ++ 11中,未命名的命名空间中的名称按照3.5 / 4具有内部链接,因此对于变量和函数的效果与声明它们static
完全相同 - 但内部链接不仅适用于变量和函数(例如枚举,类,模板),所以从C ++ 11开始,你应该总是喜欢未命名的命名空间!
答案 1 :(得分:3)
在C ++中,您只能在给定的命名范围内拥有一个定义。如果有多个翻译单元,您仍然只允许有一个定义,但编译器不保证所有定义确实相同。也就是说,如果您需要本地类型,例如struct
或class
,您需要确保定义不与其他类型的冲突在任何其他翻译单元中。除非你有办法以某种方式在本地保护你的类型,否则在大型项目中这样做几乎是不可能的。这是未命名的命名空间提供的内容:未命名的命名空间中定义的任何名称在整个可执行文件中都是唯一的。
答案 2 :(得分:2)
它与static
关键字基本相同,但实际上并不强制内部链接。该变量仍然是外部链接的,您无法在任何其他翻译单元中解析其名称。这是必要的,因为模板参数必须具有外部链接,或者至少用于要求这样的。
var
也不是指针,它是一个引用。它不是像其他指针那样创建的,因为它不是一个。
答案 3 :(得分: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;
之类的简单事例除外。不要混用指针和非指针。