命名空间
课程内容安排 命名空间 使用命名空间 类的作用域 作用域 this指针 综合练习 思考和习题
命名空间 命名空间事实上就是一个含有许多标识符的空间,其中包含了许多标识符的定义 。 命名空间就是为解决C++中的变量、函数的命名冲突而服务的。解决的办法就是将变量定义在一个不同名字的命名空间中。就好像张家有电视机,李家也有同样型号的电视机,但人们能区分清楚,就是因为他们分属不同的家庭。同样的,变量user_name既可以在命名空间a中,也可以在命名空间b中,系统不会将其混淆,如图16-1所示。
定义命名空间 C++中,有两种形式的命名空间——有名的命名空间和无名的命名空间。标准C++中,命名空间的定义格式为: 有名的命名空间: namespace 命名空间名 { 声明序列 } 无名的命名空间: namespace
定义命名空间 命名空间的成员,是在命名空间定义中的花括号内声明了的名称。读者可以在命名空间的定义内,定义命名空间的成员(称为内部定义)。也可以只在命名空间的定义内声明成员,而在命名空间的定义之外定义命名空间的成员(称为外部定义)。其中,命名空间成员的外部定义的格式为: 命名空间名::成员名
使用命名空间 由于命名空间的定义中包含了许多变量、函数的定义,那么在实际的程序设计,如何来使用命名空间中的这些定义呢?标准C++给出了几种引用命名空间内变量和函数的方法,其分别是如下三种: 使用作用域运算符 using指令 using声明
使用using指令 前面讲解过作用域运算符::,比如多个类中定义了相同的成员函数时,需要通过作用域运算符指明是哪个类的,而使用作用域运算符引用命名空间中的成员也是如此。 读者需要注意的是,许多代码中的预编译部分为#include <iostream>,而并不是以前常用的#include <iostream.h>。在新的C++标准中,生成新头文件的方法仅仅是将现有C++头文件名中的.h去掉。以前的C++头文件名如<iostream.h>将会继续被支持,尽管它们不在官方标准中,但这些头文件的内容不在名字空间std中。
使用using指令 每次引用命名空间中的成员都必须是用作用域运算符是非常繁琐的。为了省去每次调用Inner成员和标准库的函数和对象时,都要添加Outer::Inner::和sta::的麻烦,可以使用标准C++的using编译指令来简化对命名空间中的名称的使用。格式为: using namespace 命名空间名[::命名空间名……]; 在这条语句之后,就可以直接使用该命名空间中的标识符,而不必写前面的命名空间定位部分。因为using指令,使所指定的整个命名空间中的所有成员都直接可用。
使用using声明 除了可以使用using编译指令(组合关键字using namespace)外,还可以使用using声明来简化对命名空间中的名称的使用,其使用格式为: using 命名空间名::[命名空间名::……]成员名; 读者需要注意的是,此处的格式中,关键字using后面并没有跟关键字namespace,而且最后必须为命名空间的成员名(而在using编译指令的最后,必须为命名空间名)。 与using指令不同的是,using声明只是把命名空间的特定成员的名称,添加该声明所在的区域中,使得该成员可以不需要采用命名空间的作用域解析运算符来定位,而直接被使用。但是该命名空间的其他成员,仍然需要作用域解析运算符来定位。
类的作用域 类的作用域简称类域,它是指在类的定义中由一对花括号所括起来的部分。每一个类都具有该类的类域,该类的成员局部于该类所属的类域中。
静态成员 静态成员是指类中用关键字static说明的那些成员,其主要包括静态数据成员和静态成员函数。静态成员用于解决同一个类的不同对象之间数据和函数共享的问题。 静态数据成员是指类中用关键字static说明的那些数据成员。其是类的数据成员的特例,每个类只有一个静态数据成员的拷贝,从而实现同类对象之间的数据共享。 静态成员函数是指类中用关键字static说明的那些成员函数。它属于类,由同一个类的对象共同使用和维护,为这些对象所共享。
作用域 C++程序语言的标识符作用域有三种:全局作用域,局部作用域,文件作用域。 简单的说,域就是范围;而作用应理解为起作用,也可称为有效。所以作用域就是指一个变量或函数在代码中起作用的范围,或者说,一个变量或函数的“有效范围”。 局部作用域 :一对{}括起来的代码范围,属于一个局部作用域。 全局变量:如果一个变量声明或定义不在任何局部作用域之内,该变量称为全局变量。
this指针 this指针是一个特殊的指针,当类的某个非静态的成员函数在执行时,就会存在this指针,其指向类的一个对象,且这个对象的某个成员函数正在被调用。 在实际程序中,this指针用得最多的地方是用作返回值。使用this指针可以允许成员函数返回调用对象给调用者。在前面第13章运算符重载中,this指针常作为返回值。
综合练习 在头文件16-12.h中声明一个命名空间name,其中包含变量和函数,在主函数中引用该命名空间内的成员,完成相应的功能。
头文件代码清单 1 #include <iostream> //注意没有加h 2 using namespace std; //使用命名空间 3 static int n; //定义静态全局变量 4 namespace name //定义命名空间name 5 { 6 static void fn() //定义静态成员函数 7 { 8 static int i=10; //定义静态局部变量 9 i = 505; //变量i赋值 10 n++; //变量n递加1 11 cout<<n<<endl; //输出静态全局变量的值 12 } 13 }
主函数代码清单 1 #include <iostream> 2 #include "16-12.h" //包含头文件 3 using namespace std; //使用using指令 4 using namespace name; //使用命名空间 5 void f() //定义函数 6 { 7 static int t =808; //定义静态局部变量 8 cout<<"t = "<<t<<endl; //输出值 9 } 10 void main() 11 { 12 n=20; //给静态全局变量n赋值 13 cout<<n<<endl; //输出静态全局变量n的值 14 fn(); //引用命名空间成员,输出n的值 15 cout<<"t value = "<<n<<endl; //输出值 16 }
思考和习题 在C++程序中,为什么要引入命名空间的概念? 相比以前旧的头文件,引入命名空间有什么好处? 命名空间在实际的使用中,如何引用其中的成员?有哪些方法可以实现其成员的引用?各有哪些有缺点? 类的作用域是指什么?为什么要在程序中引入静态成员? 如何在具体的程序中使用作用域来实现特定的某些功能? this指针的作用是什么?