猿问
下载APP

为什么使用未命名的命名空间以及它们的好处是什么?

我刚刚加入了一个新的C ++软件项目,我正在尝试理解这个设计。该项目经常使用未命名的命名空间。例如,类定义文件中可能会出现这样的情况:


// newusertype.cc

namespace {

  const int SIZE_OF_ARRAY_X;

  const int SIZE_OF_ARRAY_Y;

  bool getState(userType*,otherUserType*);

}


newusertype::newusertype(...) {...

可能导致使用未命名的命名空间的设计注意事项是什么?有哪些优点和缺点?


摇曳的蔷薇
浏览 65回答 3
3回答

忽然笑

(在下文中,这些东西不再适用于C ++ 11,但确实适用于C ++ 03.C ++ 11几乎没有任何差异(如果有的话,它们只是语言律师的差异,我不记得了。)。未命名的命名空间是使标识符转换单元本地化的实用程序。它们的行为就像为命名空间选择每个翻译单元的唯一名称一样:namespace unique { /* empty */ }using namespace unique;namespace unique { /* namespace body. stuff in here */ }使用空体的额外步骤很重要,因此您可以在命名空间体内引用像::name该命名空间中定义的标识符,因为using指令已经发生。这意味着您可以拥有help可以存在于多个翻译单元中的自由函数(例如),并且它们不会在链接时发生冲突。效果几乎与使用staticC中使用的关键字相同,您可以将其放入标识符声明中。未命名的命名空间是一种更好的替代方案,甚至可以将类型转换单元设置为本地。namespace { int a1; }static int a2;两者a都是本地翻译单位,不会在链接时发生冲突。但不同之处在于a1匿名命名空间中的名称是唯一的。

守着星空守着你

在匿名命名空间中有一些东西意味着它是本翻译单元的本地(.cpp文件及其所有包含)这意味着如果在别处定义了具有相同名称的另一个符号,则不会违反一个定义规则(ODR)。这与具有静态全局变量或静态函数的C方式相同,但它也可以用于类定义(并且应该使用而不是static在C ++中使用)。同一文件中的所有匿名命名空间都被视为相同的命名空间,不同文件中的所有匿名命名空间都是不同的。匿名命名空间相当于:namespace __unique_compiler_generated_identifer0x42 {    ...}using namespace __unique_compiler_generated_identifer0x42;

智慧大石

除了这个问题的其他答案之外,使用匿名命名空间还可以提高性能。由于命名空间中的符号不需要任何外部链接,因此编译器可以更自由地对命名空间内的代码执行积极的优化。例如,可以内联在循环中多次调用一次的函数,而不会对代码大小产生任何影响。例如,在我的系统上,如果使用匿名命名空间,则以下代码占用大约70%的运行时间(x86-64 gcc-4.6.3和-O2;请注意,add_val中的额外代码使编译器不想包含它两次)。#include <iostream>namespace {&nbsp; double a;&nbsp; void b(double x)&nbsp; {&nbsp; &nbsp; a -= x;&nbsp; }&nbsp; void add_val(double x)&nbsp; {&nbsp; &nbsp; a += x;&nbsp; &nbsp; if(x==0.01) b(0);&nbsp; &nbsp; if(x==0.02) b(0.6);&nbsp; &nbsp; if(x==0.03) b(-0.1);&nbsp; &nbsp; if(x==0.04) b(0.4);&nbsp; }}int main(){&nbsp; a = 0;&nbsp; for(int i=0; i<1000000000; ++i)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; add_val(i*1e-10);&nbsp; &nbsp; }&nbsp; std::cout << a << '\n';&nbsp; return 0;}
打开App,查看更多内容
随时随地看视频慕课网APP
我要回答