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

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

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

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

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

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

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

my_namespace::my_test = ;

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

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

namespace my_ns = my_namespace;

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

namespace son_ns = my_namespace::son_namespace;

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

 using my_namespace::my_test;
int
main(void)
{
my_test = ;
}

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

 using my_namespace;

 int
main(void)
{
my_test = ;
my_index = ;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

C++Primer笔记(2)的更多相关文章

  1. C++ Primer笔记

    C++ Primer笔记 ch2 变量和基本类型 声明 extern int i; extern int i = 3.14;//定义 左值引用(绑定零一变量初始值,别名) 不能定义引用的引用:引用必须 ...

  2. C++ Primer 笔记(1)基础中的战斗机 输入输出 对输入不定数据处理

    今天打算再重新好好的看一遍C++ Primer这本很经典的书籍,笔记开始: 1.每个C++程序都包含一个或者多个函数,其中必须有一个main,操作系统通过调用main入手运行程序: 2.函数包括:返回 ...

  3. C++ Primer 笔记 第一章

    C++ Primer 学习笔记 第一章 快速入门 1.1 main函数 系统通过调用main函数来执行程序,并通过main函数的返回值确定程序是否成功执行完毕.通常返回0值表明程序成功执行完毕: ma ...

  4. C++primer笔记之顺序容器

    最近又重新拾起C++primer,发现每一次看都会有不同的体验,但每一次看后因为不常用,忘记得很快,所以记笔记是很关键的一环,咋一看是浪费时间,实际上是节省了很多时间.下面就把这一节的内容做一个简单的 ...

  5. c++ primer 笔记 (一)

    昨天开始看的<C++ Primer>,确实不错.希望这周抓紧看完,每天做下笔记,以便以后复习. main函数返回一个值给操作系统   操作系统通过main函数返回的值来确定程序是否成功执行 ...

  6. C++ Primer笔记(1)——连续读取数据、类型对应的尺寸、类型转换、字符串分行写法

    这次要看看C++ Primer,这本基本上就是必读书籍了.下面的内容就是一些之前没有学过的知识的笔记. 读取数量不定的输入数据 虽然很简单,但是还是记一下: #include <iostream ...

  7. C++Primer笔记(3)

    标准库类型string表示可变长的字符序列,使用前先包含string头文件.(哈哈,终于可以逃脱C语言中的str函数系列了.)因为是标准库的一部分,所以string被定义在命名空间std中.所以你懂该 ...

  8. C++ Primer 笔记 第三章

    C++ Primer 第三章 标准库类型 3.1using声明 例: using namespace atd; using std::cin; 3.2string类型 初始化方式 string s1 ...

  9. C++ Primer 笔记 第二章

    C++ Primer 第二章 变量和基本类型 2.1基本内置类型 有算数类型和void类型:算数类型储存空间大小依及其而定. 算数类型表: 类型 含义 最小储存空间 bool 布尔型 - char 字 ...

  10. C++ Primer 笔记——数组

    1.数组的大小是固定不变的,声明时必须指定大小(或者使用列表初始化),而且大小必须大于0,C++ Primer里面也建议,如果不确定元素的个数,请使用vector. ]; , , }; //数组长度固 ...

随机推荐

  1. [每日一题] OCP1z0-047 :2013-07-25 权限――角色与对象权限

    有疑问可以去itpub讨论:http://www.itpub.net/thread-1804842-1-1.html 按题意,操作如下: 1.创建一个角色r1 sys@OCM> create r ...

  2. Mysql学习(慕课学习笔记8)插入、更新、删除记录

    插入记录 Insert[]into] tb1_name[(col_name,…..)] 自动编号的字段,可以用values default Default 可以赋予默认值 INSERT USERS V ...

  3. web标准(复习)--7 横向导航菜单

    今天我们开始学习html列表,包含以下内容和知识点: 横向列表菜单 用图片美化的横向导航 css Sprites 一.横向列表菜单前边学习过纵向导航菜单,又学习了float属性,那么要实现横向导航菜单 ...

  4. TreeMap Red-Black tree

    本文以Java TreeMap为例,从源代码层面,结合详细的图解,剥茧抽丝地讲解红黑树(Red-Black tree)的插入,删除以及由此产生的调整过程. 总体介绍 之所以把TreeSet和TreeM ...

  5. Python新手学习基础之运算符——赋值与逻辑运算

    赋值也是一种运算符 我们在之前的章节,了解过,在Python里变量是不需要声明的,只要变量的标识符合法,就可以直接定义并赋值,而且Python也允许我们同时为多个变量赋值(包括为多个变量赋不同类型的值 ...

  6. Codeforces 163A Substring and Subsequence

    http://codeforces.com/problemset/problem/163/A?mobile=true 题目大意:给出两个串,问a的连续子串和b的子串(可以不连续)相同的个数. 思路:在 ...

  7. 智能卡 APTU命令

    一条命令APDU含有一个头标和一个本体.本体可有不同长度,或者在相关数据字段为空时,整个可以不存 在. 头标由四个数据元组成,它们是类CLA(ClAss)字节,命令INS(INStructic,n)字 ...

  8. linux vmstat使用说明

    FIELD DESCRIPTION FOR VM MODE Procs r: The number of processes waiting for run time. 表示运行队列,就是说多少个进程 ...

  9. 深入理解linux网络技术内幕读书笔记(四)--通知链

    Table of Contents 1 概述 2 定义链 3 链注册 4 链上的通知事件 5 网络子系统的通知链 5.1 包裹函数 5.2 范例 6 测试实例 概述 [注意] 通知链只在内核子系统之间 ...

  10. c语言const

    const关键字 const和指针结合,共有4种形式 const int *p; p是一个指针,指针指向一个int型数据.p所指向的是个常量. int const *p; p是一个指针,指针指向一个i ...