精华内容
下载资源
问答
  • C++匿名命名空间
    2021-03-15 09:53:31

    当定义一个命名空间时,可以忽略这个命名空间的名称:    

    namespce {
        char c;
        int i;
        double d;
    }

    编译器在内部会为这个命名空间生成一个唯一的名字,而且还会为这个匿名的命名空间生成一条using指令。所以上面的代码在效果上等同于:    

    namespace __UNIQUE_NAME_ {
        char c;
        int i;
        double d;
    }
    using namespace __UNIQUE_NAME_;

    在匿名命名空间中声明的名称也将被编译器转换,与编译器为这个匿名命名空间生成的唯一内部名称(即这里的__UNIQUE_NAME_)绑定在一起。还有一点很重要,就是这些名称具有internal链接属性,这和声明为static的全局名称的链接属性是相同的,即名称的作用域被限制在当前文件中,无法通过在另外的文件中使用extern声明来进行链接。如果不提倡使用全局static声明一个名称拥有internal链接属性,则匿名命名空间可以作为一种更好的达到相同效果的方法。

    注意:命名空间都是具有external 连接属性的,只是匿名的命名空间产生的__UNIQUE_NAME__在别的文件中无法得到,这个唯一的名字是不可见的.

    C++ 新的标准中提倡使用匿名命名空间,而不推荐使用static,因为static用在不同的地方,涵义不同,容易造成混淆.另外,static不能修饰class。

    另一篇;

    今天得到来自google的老大的指点,学习了一个新的用法:匿名命名空间。
    C++另外有一种匿名的命名空间,来保证生成的符号是局部的,这样对于匿名空间中的变量等,外部都是不可见的.
    
    
    
    //test3.cpp
    
    static void bar(){}
    
    namespace //匿名的命名空间
    {
        float bar2;
        int foo;
    }
    
    //test4.cpp
    extern int foo;
    extern void bar();
    extern float bar2; 
    int main()
    {
    bar();                    //外部的bar()被声明为static,这里链接不到符号.不能访问
    bar2 = 0.1f;          //外部的匿名空间哩,这里也不能访问.
    foo = 0xFF;
    return 0;
    };//如果将test4的目标和test3的目标进行链接,实际上是找不到这些符号的.链接会失败.
    匿名的命名空间是C++的特性,相对于C的static声明来说,可以在匿名的空间里面声明很多变量和函数,这样可以省去了对每个变量和函数添加static声明.
    实质上匿名空间的功能跟static声明是一样的.

    对于一个大型的C语言软件项目,给函数和全局变量起名不是一个容易的事情,因为必须考虑有没有可能与其它程序员写的代码冲突,多数的做法是对每个模块的一组函数名加个特定前缀,如HTRequest_setInternal、HTRequest_internal等。这使得程序员每次调用这些函数时都必须多输出一些字符,虽然使用现在比较优秀的IDE(Integrated Development Environment),不会给程序员的输入带来多少负责,但这些字符看起来还是有些多余。所以C++引入了namespace的概念,把一些标识符以命名空间树结构的方式组织起来,使代码看起来更优雅。而且事实证明,该特性是先进的,对于大型项目的作用是明显的,并且在后来的编程语言如Java、C#、Python都支持此类特性,只是有些叫法不同而已。

    命名空间不仅可以用于组织类型(class、struct、Enum)等,还可以用于组织全局变量、全局函数等。如例程[2-1]所示,将不同模块的标识符分别组织到不同的命名空间中,从而避免标识符的冲突。

    // 例程[2-1]
    #include <iostream>
    namespace sock{
    typedef unsigned short socket_port_t;
    const char* LOOPBACK_ADDR = “127.0.0.1”;
    const socket_port_t DEFUALT_HTTP_PORT = 80;
    }
    
    int main( void )
    {
    std::cout<<”Local HTTP addr = “<<sock::LOOPBACK_ADDR
    <<’:’<<sock::DEFUALT_HTTP_PORT<<std::endl;
    return 0;
    }

    在大型的C++项目中使用命名空间比较好的项目如Google浏览器Chorme、开源C++库boost等,而没有使用命名空间的一个例子就是开源C++库ACE(The ADAPTIVE Communication Environment ),它选择了在每个类型的前面加上前缀“ACE_”,使得标识符都比较长,而且看起来有点儿冗余。为使用起来方便,而且不修改ACE的源码,可以使用typedef标识符对这些标识符进行重命名,如例程[2-2]所示。请注意,不能在这里使用#define,因为宏不受命名空间的限制。

    // 例程[2-2]
    #include <ace/Mutex.h>
    namespace ace{
    typedef ACE_Mutex Mutex;
    typedef ACE_Lock Lock;
    }

    1.1.2. 如何引用命令空间内的标识符

    当引用的标识符不在当前命名空间或全局命名空间内时,有三种方式可以引用该标识符,如引用前一节新定义的ace命令空间中的Mutex类型:

    // 方式一
    ace::Mutex mutex;
    // 方式二
    using ace::Mutex;
    Mutex mutex;
    // 方式三
    using namespace ace;
    Mutex mutex;

    方式一只在必要的时候通过域运算符“::”引用指定命令空间内的标识符,适用于当前编译单元引用ace内的标识符不多,而且编译单元内使用这些标识符的次数也不多的情况。

    方式二只引入ace::Mutex一个标识符,如果在当前编译单元内使用ace::Mutex次数较多,而且不会与当前命名空间内的标识符冲突,建议使用这种方式。

    方式三是把ace命名空间中的全部标识符都引入到当前命名空间中,此后ace所有的标识符对于当前命名空间都是可见的,这会提高标识符冲突的危险。如果当前编译单元用到ace命令空间内的标识符较多,而且不会出现标识符冲突的问题,可以使用这种方式,以减少字符的输入。

    对于以上三种方式,建议优先选择第一种,这种方式最不容易产生标识符冲突,方式二次之,尽可能不用第三种试,即使是对于C++标准库也不要使用第三种方式,因为至少在Solaris系统中就有一个struct类型叫map ??,如果你引用了包含该类型的头文件就会导致命名冲突。

    另外,建议不要在头文件中使用using语句引入标识符,否则这些标识符将被暴露到引用这个头文件的所有编译单元内,这样很容易使命名空间失去其作用而产生命名冲突。

    对于用到的系统API,建议函数名前使用域运算符加以区别,使程序可读性更好,如:::GetLastError( ), ::getcwd( )。

    注意,切忌在自定义的命名空间中引用系统头文件,如例程[2-3]所示,避免造成标识符的混乱。

    // 例程[2-3]
    namespace my_space{
    #include <net/if.h>
    }

    1.1.3. 命令空间的别名

    当要引用的命名空间比较长,而且想用第一种方式引用命名空间内的实体,则可以通过命名空间别名,为原来的命名空间起个简短的名字,如例程[2-4]。

    // 例程[2-4]
    namespace long_namespace{
    void func( void ) { /* function body */ }
    }
    namespace ns = long_namespace;
    int main( void )
    {
    ns::func();
    return 0;
    }

    1.1.4. 匿名命令空间

    当声明命名空间时的名称为空时,则该命名空间为匿名命名空间(unnamed namespace)。匿名的空间是C++用于替代使用static定义作用域为本编译单元的全局函数或全局变量的一种新的替代方式,匿名空间与命名的命名空间一样可以嵌套。由于匿名命名空间没有命名空间的名字,所以也无法在其它的编译单元内通过extern声明该变量,于是该变量自然也只在本编译单元内可见,如例程[2-5]。

    // 例程[2-5]
    #include <iostream>
    using namespace std;
    namespace{ int i = 256; }
    namespace ns{
        namespace { int i = 128; }
        void func(void)
        {
            cout<<"ns::func :" <<endl;
            cout<<"\t::i="<<::i<<endl;
            cout<<"\tns::i="<<i<<endl;
        }
    }
    int main(void )
    {
        cout<<::i<<endl;
        cout<<"i="<<i<<endl;
        cout<<"ns::i="<<ns::i<<endl;
        ns::func();
        return 0;
    }

    使用匿名空间比使用static至少有两个好处:

    1) 对于一组多个标识符函数只需要使用一个匿名空间来声明,不需要多次输入static。

    2) 可以嵌套。这样可以在不同命名空间中使用多个同名的标识符。

    在C++的标准中也建议使用匿名命名空间间定义编译单元内部的全局变量,替代static,static关键词在此处被认为是过期的(deprecated)特性。

    更多相关内容
  • 4.C++匿名命名空间 1.3.4.1、std和cout的引入 (1)std是C++标准库定义好的一个namespace (2)cout是std这个namespace下的一个标准输出工具,类似于C中的printf (3)用法示例 1.3.4.2、匿名命名空间的定义和使用 (1)定义...

    1.默认命名空间

    1.1 默认命名空间的定义

    默认命名空间也叫全局命名空间,所有没有置于某一具体命名空间下的代码即在默认命名空间下,例如func(),main()函数。

    #include<iostream>
    
    void func(void);
    
    int main(int argc,char**argv)
    {
    	std::cout<<"this is main"<<std::endl;
    	return 0;
    }
    
    void func(void)
    {
    	std::cout<<"this is func"<<std::endl;
    }
    

    需要注意的是:

    • 1.默认命名空间也是命名空间。
    • 2.默认命名空间是全局的。
    • 3.main()函数必须置于默认命名空间下。

    1.2 默认命名空间引用其他命名空间

    默认命名空间引用其他命名空间的方法与上一篇中的使用命名空间的方法是一样的,这里不再多说了。

    1.3 默认命名空间引用自己

    这个就是类似于C语言里简单的没有命名空间的函数调用,如下面的代码中main()调用func1()

    #include<iostream>
    
    void func1(void);
    
    int main(int argc,char**argv)
    {
    	func1();
    	return 0;
    }
    
    void func1(void)
    {
    	std::cout<<"this is func1"<<std::endl;
    }
    

    1.4 其他命名空间引用默认命名空间

    其他命名空间引用默认命名空间同样使用::,但是前面命名空间的名字是空白的,例如下面的代码中命名空间ns引用默认命名空间下的func()

    #include<iostream>
    
    void func1(void);
    
    namespace ns
    {
    	void func2(void)
    	{
    		::func1();
    	}
    }
    
    int main(int argc,char**argv)
    {
    	ns::func2();
    	return 0;
    }
    
    void func1(void)
    {
    	std::cout<<"this is ::func1"<<std::endl;
    }
    

    2.匿名命名空间

    2.1 匿名命名空间的定义

    匿名命名空间和全局命名空间有些类似,他们都没有名字,但是全局命名空间不需要自己定义,而匿名命名空间需要自己去定义,方法就是namespace后面没有空间名,直接就是 {}

    namespace
    {
    	void func(void)
    	{
    		std::cout<<"来自匿名命名空间的func()."<<std::endl;
    	}
    }
    

    2.2 匿名命名空间中引用其他命名空间

    匿名命名空间引用其他命名空间的方法与上一篇中的使用命名空间的方法是一样的,这里不再多说了。

    2.3 匿名命名空间中引用自己

    直接用,无需添加命名空间名前缀,只要确保先声明后使用的顺序就没有问题。

    2.4 其他命名空间中引用匿名命名空间

    一般匿名命名空间定义于文件前面,类似于全局函数位置,之后的命名空间可以正常访问匿名命名空间中的内容,但是匿名命名空间的作用不在于此,而是在于跨文件访问的时候。因此其实对于单个文件内部,使用匿名命名空间与全局函数并无多大差别。

    2.5 匿名命名空间的意义

    • 1.匿名命名空间中的符号限于文件内部使用,不需要被外部引用。
    • 2.匿名命名空间效果类似于全局变量和函数加static,但是比C中的static使用范围广,static只能用于修饰函数名变量名,而不能用于修饰一个类型,如struct,class,而匿名命名空间则不局限于这些。
    • 3.匿名命名空间虽然是一种特殊情况,但是用法逻辑上符合整个命名空间的一般原则。
    展开全文
  • c++系列:匿名命名空间

    2021-01-02 08:14:00
    3.实验3.1在匿名空间中引用其它命名空间3.2匿名命名空间中引用自己命名空间中的方法3.3其他命名空间中引用匿名命名空间中的方法3.4不同文件调用匿名命名空间4.最后 1.什么是匿名命名空间匿名命名空间就是一个没有...

    1.什么是匿名命名空间?

    匿名命名空间就是一个没有名字的命名空间。

    namespace 
    {
    	func()
    	{
    		...
    	}
    }
    

    2.匿名命名空间有什么用处?

    • 匿名命名空间里的内容只能被本文件调用,不能被外部引用;
    • 匿名命名空间中的变量特点跟全局变量一样,而函数特点像是添加了static的功能一样。两者仅此在本文件使用

    3.实验

    3.1在匿名空间中引用其它命名空间

    #include <iostream>
    
    using namespace std;
    
    
    namespace np
    {
    	void func1()
    	{
    		cout << "this is func1" << endl;
     	}
    }
    
    namespace
    {
    	void func2()
    	{
    		np::func1();
    	}
    }
    
    
    int main()
    {
    	func2();
    	return 0;
    }
    

    实验结果
    在这里插入图片描述

    3.2匿名命名空间中引用自己命名空间中的方法

    #include <iostream>
    
    using namespace std;
    
    namespace
    {
    	int cnt = 0;
    	void func2()
    	{
    		cout << "this is func2" << endl;
    	}
    }
    
    int main()
    {
    	cnt += 1;	//像全局变量一样读取
    	cout << cnt << endl;	
    	func2();	//像全局变量一样读取
    	return 0;
    }
    

    实验结果
    在这里插入图片描述

    3.3其他命名空间中引用匿名命名空间中的方法

    #include <iostream>
    
    using namespace std;
    
    namespace
    {
    	void func2()
    	{
    		cout << "this is func2" << endl;
    	}
    }
    
    namespace np
    {
    	void func1()
    	{
    		func2();
     	}
    }
    
    int main()
    {
    	np::func1();
    	return 0;
    }
    

    实验结果
    在这里插入图片描述

    3.4不同文件调用匿名命名空间

    //test2.cpp
    //namespace xxx {extern func1()};  //连名字符号都没有,无法声明....
    void func1()
    {
    	func2();
    }
    
    test1.cpp
    #include <iostream>
    
    void func1();
    
    using namespace std;
    
    namespace
    {
    	void func2()
    	{
    		cout << "this is func2" << endl;
    	}
    }
    
    int main()
    {
    	func1();
    	return 0;
    }
    

    实验结果
    在这里插入图片描述
    首先,匿名命名空间没有名字,或者说把名字给隐藏了,无法像xxx::func2()这样子调用,并且在test2.cpp中也无法声明匿名命名空间空间(不符合语法)。

    4.最后

    匿名命名空间的本质是什么?
    就是将命名空间的名字符号给去掉,让其他文件找不到。
    C++ 新的标准中提倡使用匿名命名空间,而不推荐使用static,因为static用在不同的地方,涵义不同,容易造成混淆.另外,static不能修饰class。

    在这里插入图片描述

    展开全文
  • 匿名命名空间的学习

    2021-10-19 00:08:22
    C++的匿名命名空间 首先这篇文章很有用 当声明命名空间时的名称为空时,则该命名空间为匿名命名空间(unnamed namespace)。匿名的空间是C++用于替代使用static定义作用域为本编译单元的全局函数或全局变量的一种新的...

    C++的匿名命名空间
    首先这篇文章很有用
    当声明命名空间时的名称为空时,则该命名空间为匿名命名空间(unnamed namespace)。匿名的空间是C++用于替代使用static定义作用域为本编译单元的全局函数或全局变量的一种新的替代方式

    #include <iostream>
    
    using namespace std;
    
    namespace{ int i = 256; }
    
    namespace ns
    {
    	namespace { int i = 128; }
    	void func(void)
    	{
    		cout<<"ns::func :" <<endl;
    		cout<<"\t::i="<<::i<<endl;
    		cout<<"\tns::i="<<i<<endl;
    	}
    }
    
    int main(void )
    {
    	cout<<::i<<endl;
    	cout<<"i="<<i<<endl;
    	cout<<"ns::i="<<ns::i<<endl;
    	ns::func();
    	return 0;
    }
    

    运算结果

    在这里插入图片描述

    我觉得这个例子挺有趣的,也有点疑惑。
    main函数里面的第一个cout,按照我的理解应该是默认命名空间的i了,但是这里默认明明空间里面没有i,但是默认命名空间里面有个匿名命名空间,所以编译器就直接到匿名命名空间里面去找i去了,所以i=256
    main函数里面的第二个cout,我觉得这样跟第一个一样,没区别
    main函数里面的第三个cout,很明显是nsnamespace里面的i,但是在ns里面没有i,只能继续往里面找,所以里面的匿名命名空间里面的i=128
    main函数里面最后一个,func里面的第二句cout,他要的是默认命名空间的i,然后外面的默认命名空间里面的匿名命名空间有i=256,所以i=256,然后最后找的就是ns里面的匿名命名空间的i,所以i=128

    其实就是匿名命名空间可以有很多个,这里的很多个是指的是在一个命名空间里面可以有一个,你想有多几个就多声明几个命名空间。

    而匿名命名空间的用法跟static有点像的,但是它的功能比static更强,具体还是看一下刚开始的那一篇文章,里面的例子都撸一遍,脑子过一遍,对这些概念就会清楚一点了。

    展开全文
  • 匿名命名空间的作用

    2021-07-30 18:20:52
    匿名命名空间的作用是该命名空间只能在本文件使用,相当于C语言的static.
  • C++学习笔记:默认命名空间与匿名命名空间 - it610.com
  • static关键字声 明的符号有内部链接属性,而匿名命名空间中声明的符号有外部链接属性。 二、static C和C++中每一个源文件(.c, .cpp)都可以单独编译成一个目标文件(.o),之后通过链接器把这些目标文件链接起来,...
  • c++匿名命名空间

    2019-08-09 11:36:51
    匿名命名空间是c++的特性,相对于c的static声明来说,可以在匿名的空间里面声明很多变量和函数,这样可以省去对每个变量和函数添加static声明。实质上匿名空间的功能跟static声明是一样。 当定义一个匿名命名空间时...
  • C++学习(十)匿名命名空间

    千次阅读 2019-06-05 06:44:26
    由于匿名命名空间没有命名空间的名字,所以也无法在其它的编译单元内通过extern声明该变量,于是该变量自然也只在本编译单元内可见。 当定义一个命名空间时,可以忽略这个命名空间的名称: namespce { char c; ...
  • c++ 匿名命名空间与static全局变量

    千次阅读 2019-11-15 10:56:57
    https://www.cnblogs.com/youxin/p/4308364.htmlhttps://blog.csdn.net/Solstice/article/details/6186978
  • 命名空间及匿名命名空间

    千次阅读 2013-10-10 10:44:11
    命名空间单独提出来描述是因为:命名空间的功能几乎和前缀是一致的。 1. 使用命名空间的必要性  在一个大的项目中,当多时合作时,多个人编写的库头文件中,不可以避免的存在变量名相同的冲突,特别都是作为...
  • 匿名命名空间 与 static 区别与联系

    千次阅读 2018-01-22 20:24:08
    区别 1 static 无法修饰 ADT类型(自定义...匿名命名空间  1.匿名命名空间内的变量与函数,只在当前源文件内有效。同一源文件内的匿名空间中的符合最终会合并。  2.不同源文件的匿名命名空间,可以存在同名符
  • 匿名命名空间,就是没有名字的namespace,如下所示: #include <iostream> namespace // unnamed namespace { void doSomething() // can only be accessed in this file { std::cout << "v1\n"; ...
  • C++匿名命名空间 匿名命名空间的价值 匿名命名空间中的符号纯文件内部使用,不需要被外部文件引用类似于全局变量和函数加static,一般在跨文件中使用到其特性 嵌套命名空间 #include void fun5(void); namespace NS ...
  • Qt命名空间 Qt namespace

    2021-01-18 20:21:43
    讲述Qt命名空间怎么用,文章地址:https://lizhifun.blog.csdn.net/article/details/112584777
  • C++:匿名命名空间

    2020-03-17 19:06:19
    匿名命名空间 概念 当定义一个命名空间时,可以忽略这个命名空间的名称: namespce { char c; int i; double d; } 编译器内部处理 编译器在内部会为这个命名空间生成一个唯一的名字,而且还会为这个匿名的命名空间...
  • 命名空间: namespace叫命名空间,用于解决函数/变量重名的问题,如果一个函数/变量被声明在命名空间中,那么使用他们的时候需要加上作用域 namespace foo{ int x = 10; } cout<<foo::x<<endl; ...
  • 解决C++重定义问题--匿名命名空间

    千次阅读 2019-10-30 17:47:56
    今天遇到一个命名空间重定义的问题,程序框架大体如下: interface中定义的是一个namespace, 形式如下: namespade np { int a = 1; int b = 2; }; 并且三个module(1,2,3),以及core模块全都需要引用这个命名...
  • C++嵌套和匿名命名空间namspace

    千次阅读 2018-06-13 20:34:35
    嵌套的命名空间其作用是改进库中代码的组织架构,防止库中命名冲突::name 表示访问最外层的命名结构(包含自己所在最外层结构)省略::表示访问自身命名结构中的内容如下例所示:#include &lt;stdlib.h&gt; #...
  • 1. 嵌套的命名空间 命名空间可以嵌套,嵌套的命名空间可以进一步改进库中代码的组织。 namespace cplusplus_primer { namespace QueryLib { class Query { /* … */ }; // … } namespace Bookstore { ...
  • 匿名命名空间中声明的名称也将被编译器转换,与编译器为这个匿名命名空间生成的唯一内部名称(即这里的__UNIQUE_NAME_)绑定在一起。还有一点很重要,就是这些名称具有internal链接属性,这和声明为static的全局名称...
  • c++ 匿名命名空间

    千次阅读 2013-07-08 17:50:22
    当定义一个命名空间时,可以忽略这个命名空间的名称: ... 编译器在内部会为这个命名空间生成一个唯一的名字,而且还会为这个匿名命名空间生成一条using指令。所以上面的代码在效果上等同于:  na

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 65,812
精华内容 26,324
关键字:

匿名命名空间