当前位置: 首页 > 科技观察

说说C++中的namespace

时间:2023-03-21 15:26:28 科技观察

一、背景相信大家在分析dump的时候,经常会看到WKS和SRV这样的词,如下代码所示:00007ffa`778a07b8coreclr!WKS::gc_heap::segment_standby_list=0x00000000`0000000000007ffa`778a3870coreclr!WKS::qpf=0x98968000007ffa`7789da30coreclr!SVR::heap_select::numa_node_to_heap_map=unsignedshort[1028]00007ffa`7789f2d0coreclr!SVR::gc_heap::should_expand_in_full_gc=0n0其实这就是命名空间,即coreclr编译源码时,分别为WKS和SVR编译了一份。不知道这样做的初衷是什么,这里就不关心了。接下来我们看看在coreclr中是什么样子的。namespaceWKS{#include"gcimpl.h"#include"gc.cpp"}namespaceSVR{#include"gcimpl.h"#include"gc.cpp"}其次,说说命名空间,其实和C#的命名空间。它们都起到了隔离的作用,using与C#结合使用完全一样,太有趣了。1.简单隔离C++默认只有一个命名空间,所以同一个变量会发生冲突。解决方法是使用命名空间隔离,参考如下代码:namespaceWKS{inta=10;intb=11;}命名空间SRV{inta=100;intb=101;}intmain(){printf("WKS::a=%d\n",WKS::a);printf("SRV::a=%d\n",SRV::a);}当然也可以嵌套使用,比如改成这样。命名空间WKS{命名空间V1{inta=10;整数b=11;}}intmain(){printf("WKS::a=%d\n",WKS::V1::a);}接下来看下载汇编代码:哈哈,看到上面的WKS::V1::a感觉很舒服,能看懂现在的coreclr!WKS::xxx,但是这里有个比较麻烦的地方,就是每次第一次用a的时候都要输入很长的前缀。有没有办法简化它?当然有。2.使用using导入接下来,我们在main函数中使用using直接定义字段,就不用写长前缀引用了。参考代码如下:namespaceWKS{namespaceV1{inta=10;整数b=11;}}intmain(){使用WKS::V1::a;printf("WKS::V1::a1=%d\n",a);}3.使用using来定义别名这个功能比较特殊嗯,个人感觉已经完全取代了之前的typedef功能。例如,下面的代码是完全一样的。intmain(){typedefconstchar*PCHAR;使用PCHAR2=constchar*;PCHARptr1="你好世界1";PCHAR2ptr2="helloworld2";}如果还不信,可以看看他们各自生成的汇编代码。PCHARptr1="helloworld1";00007FF79856183Blearax,[string"helloworld1"(07FF798569C10h)]00007FF798561842movqwordptr[ptr1],raxPCHAR2ptr2="helloworld2";00007FF798561807FF798569CE8h)]00007FF79856184Dmovqwordptr[ptr2],rax4。使用usingnamespace导入这是最常见的方式。我们调用系统库,都是使用usingnamespace,比如下面的代码。usingnamespacestd;intmain(){stringstr="helloworld";}接下来我们在main方法中引入V1,这样我们就可以自由使用WKS::V1中的内容了,参考如下代码:namespaceWKS{命名空间V1{inta=10;整数b=11;}}intmain(){使用命名空间WKS::V1;printf("a=%d,b=%d",a,b);}ok到此为止,这是对命名空间的一点认识,本文就到此为止,希望对你有所帮助。