c++头文件知多少【2】

来源:互联网 发布:民国服饰 知乎 编辑:程序博客网 时间:2024/06/09 19:45

 

后缀为.h的头文件c++标准已经明确提出不支持了,早些的实现将标准库功能定义在全局空间里,声明在带.h后缀的头文件里,c++标准为了和C区别开,也为了正确使用命名空间,规定头文件不使用后缀.h。

因此,当使用<iostream.h>时,相当于在c中调用库函数,使用的是全局命名空间,也就是早期的c++实现;当使用<iostream>的时候,该头文件没有定义全局命名空间,必须使用namespace std;这样才能正确使用cout。

一般一个C++的老的带“.h”扩展名的库文件,比如iostream.h,在新标准后的标准库中都有一个不带“.h”扩展名的相对应,区别除了后者的好多改进之外,还有一点就是后者的东东都塞进了“std”名字空间中。  

但唯独string特别。  
问题在于C++要兼容C的标准库,而C的标准库里碰巧也已经有一个名字叫做“string.h”的头文件,包含一些常用的C字符串处理函数,比如楼主提到的strcmp。  
这个头文件跟C++的string类半点关系也没有,所以 <string >并非 <string.h >的“升级版本”,他们是毫无关系的两个头文件。  
要达到楼主的目的,比如同时:  
#include   <string.h >  
#include   <string >  
using   namespace   std;  
或者  
#include   <cstring >  
#include   <string >  

其中 <cstring >是与C标准库的 <string.h >相对应,但裹有std名字空间的版本。

using namespace std

所谓namespace,是指标识符的各种可见范围。

C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。

由于namespace的概念,使用C++标准程序库的任何标识符时,可以有三种选择:

1、直接指定标识符。例如std::ostream而不是ostream。完整语句如下:

std::cout << std::hex << 3.4 << std::endl;

2、使用using关键字。

using std::cout;
using std::endl;

以上程序可以写成

cout << std::hex << 3.4 << endl;

3、最方便的就是使用using namespace std;这样命名空间std内定义的所有标识符都有效(曝光)。就好像它们被声明为全局变量一样。那么以上语句可以如下写:

cout << hex << 3.4 << endl;

因为标准库非常的庞大,所程序员在选择的类的名称或函数名时就很有可能和标准库中的某个名字相同。所以为了避免这种情况所造成的名字冲突,就把标准库中的一切都被放在名字空间std中。但这又会带来了一个新问题。无数原有的C++代码都依赖于使用了多年的伪标准库中的功能,他们都是在全局空间下的。 

所以就有了<iostream.h>和<iostream>等等这样的头文件,一个是为了兼容以前的C++代码,一个是为了支持新的标准。

命名空间std封装的是标准程序库的名称,标准程序库为了和以前的头文件区别,一般不加".h"
 

名词空间namespace

1) namespace只能在全局范畴定义,但它们之间可以互相嵌套。

2) 在namespace定义的结尾,右大括号的后面不必要跟一个分号。

3) 一个namespace可以在多个头文件中用一个标识符来定义,就好象重复定义一个类一样。

4)一个namespace的名字可以用另一个名字来作它的别名,这样我们就不必敲打那些开发商提供的冗长的名字了。比如说namespace alex = ThisIsAelxLongNamespace;

5) 我们不能像类那样去创建一个名字空间的实例

1.每个编译单元可以有一个没有命名的名词空间。

//cu.cpp

namespace{

class object{}...

}

   2. 友元:可以在一个名字空间的类定义之内插入一个friend 声明,这个友元也属这个namespace

使用名词空间namespace

1.alex::Student::age=5;//象使用类一样使用namespace

2.使用using指令using namespace std;using namespace alex;using namespace chirs;

如果alex 和chirs都有一个love 函数的话,就会发生冲突,

3.使用using声明:

void func(){

using namespace alex;//using指令

using chris::love;//uisng声明

love();//chirs::love();

alex::love();//必须这么使用

}

 

使用名称空间标识符std。
这样在原来使用名称空间的头文件里就可以直接使用里面定义的全局变量。
此处所谓的全局就是只在本名称空间里有效。
比如你使用c++标准流库的时候,往往需要这样包含头文件:
1.#include
或者:
2.#include
方式1使用了名称空间机制,而后者没有。
所以前者定义的io对象cin&cout就不可以直接使用,而必须使用std::cin和std::cout.要是在文件开始用了using namespace std;则可以直接使用cin&cout.
方式2就不需要这些措施。这也是我们平时就采用的方法。


名字空间指标志府的可见范围。

自己定义名字空间

namespace A

{

class B{}

}

这样你的类只在这个名字空间里可见,如果别的地方想要使用你这里定义的B的话,必须加上

int main()
{
using namespace A;
B b;
}

或者加名字空间限定府 A::B b;这样就定义了一个B类型的对象。

c++标准库中所有的标志府都被定义在一个名字空间std中,iostream也是标准库中的头文件,你查看一下include目录,会发现又两个头文件iostream.h和iostream,其中iostream.h是c++以前的库,iostream是在名字空间std中的库,所以当你包含头文件并想使用头文件中的标志符的时候有两种方法。

#include <iostream.h>

或者

#include <iostream>

using namespace std;

原创粉丝点击