码迷,mamicode.com
首页 > 编程语言 > 详细

C++Primer笔记(2)::命名空间

时间:2015-11-25 23:29:54      阅读:217      评论:0      收藏:0      [点我收藏+]

标签:

大型程序一般都是分为多个模块,由多人协作来进行开发的,其中还不可避免的会用到库。而各个模块代码以及库中会定义大量变量,而大量变量的命名,不可避免的会遇见“重名”的问题。“重名”的情况我们称之为命名空间污染。就像你的同学重名了(这也是没有办法的事),比如同班有两个李明(此名重名率极高),这个时候当你们提到其中某一个时,聆听者就搞不懂到底说的是哪个李明了,这个时候就出现了命名空间污染。而这个时候,命名空间就派上用场了,而所谓的命名空间事实上就相当于给作用域起了一个名字,然后你可以在这个作用域中进行各种声明和定义。命名空间的定义如下:

1 namespace my_namespace {    //关键字namespace   命名空间名字
2     int my_test;            //      各种声明和定义    
3     namespace son_namespace { /*....*/ } //嵌套命名空间
4 };

只要是能在全局作用域中的声明就能放在命名空间中,包括:类,变量(及其初始化),函数(及其定义)、模板和其他命名空间。

命名空间可以是不连续的。我们可以打开一个已经定义过的命名空间,并在其中添加新的声明与定义。

namespace my_namespace {
    int my_index;              //打开一个已经定义过的命名空间
}//注意此处没有分号!!!

值得注意的是,通常情况下不要将#include <***>放在命名空间中,这样的话等于我们试图将头文件中的命名空间嵌套在我们定义的命名空间中,程序普遍会出错,所以建议避免此种情况的发生。

命名空间的成员在命名空间中可以正常使用,而在命名空间外则需要加上前缀。就比如两个李明一个家是山西太原的,另一个家是陕西西安的,这个时候你就可以说:陕西西安的那个李明如何如何,这样别人就不会出现搞不清楚对象的情况。

my_namespace::my_test = 5;

但是大型项目中变量何其多,这样每个都加前缀会给巨大的不必要的麻烦。所以C++提供了命名空间别名using声明以及using指示来解决此问题。

命名空间别名其实与类型别名是一样的,它可以让我们为我们定义的命名空间设定一个短的多的同义词,这样可以减轻一点工作量。就比如说你觉着每次都加说陕西西安觉着累,然后你可以告诉聆听者一声,说:说这个太累,后面我就直接说陕西的李明,这样好点。

namespace my_ns = my_namespace;

命名空间别名也可以指向一个嵌套的空间。

namespace son_ns = my_namespace::son_namespace;

using声明的作用与其他声明一致,一条using声明语句一次只引入命名空间的一个成员,它的有效范围从声明开始到声明所在的作用域结束为止。再回到刚才那个例子,这次在谈话之前就告诉聆听者:我先声明我说的是咱班陕西西安的那个李明,然后在这次谈话中你说李明他自然知道你说的是哪个了。

1 using my_namespace::my_test;
2 int
3 main(void)
4 {
5     my_test = 10;
6 }

using指示则是将命名空间的所有成员都呈现到当前作用域。就比如告诉聆听者:我接下来说的人都是陕西西安的。

1 using my_namespace;
2 
3 int
4 main(void)
5 {
6     my_test = 10;
7     my_index = 100;
8 }

我个人建议谨慎使用using指示,因为和using声明不同,我们无法控制成员的可见与否,因为所有的都是可见的,如果两个using指示的命名空间中有同样名称的成员,则又会出现命名空间污染的情况。

 模板特例化必须定义在原始模板所属的命名空间。

全局命名空间以隐式的方式声明,全局作用域中的定义也就定义在全局命名空间。

::someone; //表示全局命名空间中的一个成员

内联命名空间(C++11新标准) ,它的特殊之处在于,内联命名空间中的名字可以被外层命名空间直接使用,无需添加前缀。

inline namespace test {
    /*此命名空间即为内联命名空间*/
};

这个特性对于代码版本升级且需保留旧版本代码的情况来说实在是太有用了。

namespace work {
    namespace edition1 {
        /*初始版本代码*/
    };
    inline namespace edition2 {
        /*新版本代码*/
    };
};

当我们更新代码以及新代码出现故障紧急回撤版本时,只需要增删inline即可,只要保证接口不变,则可以实现无缝更换。

未命名的命名空间,是指namespace后没有自己定义的名字的命名空间。

namespace {
    /*这是一个未命名的命名空间*/
};

未命名的命名空间中定义的变量拥有静态的生命周期,它们在第一次使用前创建,知道程序结束时才销毁。

它的作用与C语言中的static一致。

C++Primer笔记(2)::命名空间

标签:

原文地址:http://www.cnblogs.com/noobknight/p/4995878.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!