当前位置:首页 > 芯闻号 > 充电吧
[导读]为什么需要命名空间(问题提出)命名空间是ANSIC++引入的可以由用户命名的作用域,用来处理程序中 常见的同名冲突。在 C语言中定义了3个层次的作用域,即文件(编译单元)、函数和复合语句。C++又

为什么需要命名空间(问题提出)


命名空间是ANSIC++引入的可以由用户命名的作用域,用来处理程序中 常见的同名冲突。

在 C语言中定义了3个层次的作用域,即文件(编译单元)、函数和复合语句。C++又引入了类作用域,类是出现在文件内的。  在不同的作用域中可以定义相同名字的变量,互不于扰,系统能够区别它们。

1、全局变量的作用域是整个程序,在同一作用域中不应有两个或多个同名的实体(enuty),包括变量、函数和类等。

例:如果在文件中定义了两个类,在这两个类中可以有同名的函数。在引用时,为了区别,应该加上类名作为限定:

class A//声明A类

{public:

void funl();//声明A类中的funl函数

private:

int i;};

void A::funl()//定义A类中的funl函数

{…………}

class B//声明B类

{public:

void funl();//B类中也有funl函数

void fun2();};

void B::funl()//定义B类中的funl函数

{ …………}这样不会发生混淆。

在文件中可以定义全局变量(global variable),它的作用域是整个程序。

如果在文件A中定义了一个变量aint a=3;

在文件B中可以再定义一个变量aint a=5;

在分别对文件A和文件B进行编译时不会有问题。但是,如果一个程序包括文件A和文件B,那么在进行连接时,会报告出错,因为在同一个程序中有两个同名的变量,认为是对变量的重复定义。

可以通过extern声明同一程序中的两个文件中的同名变量是同一个变量。如果在文件B中有以下声明:

extem int a;

表示文件B中的变量a是在其他文件中已定义的变量。由于有此声明,在程序编译和连接后,文件A的变量a的作用域扩展到了文件B。如果在文件B中不再对   a赋值,则在文件B中用以下语句输出的是文件A中变量a的值: cout<<a;//得到a的值为3

2、程序中就会出现名字冲突

在简单的程序设计中,只要人们小心注意,可以争取不发生错误。但是,一个大型的应用软件,往往不是由一个人独立完成的,而是由若干人合作完成的,不同的人分别完成不同的部分,最后组合成一个完整的程序。假如不同的人分别定义了类,放在不同的头文件中,在主文件(包含主函数的文件)需要用这些类时,就用#include命令行将这些头文件包含进来。由于各头文件是由不同的人设计的,有可能在不同的头文件中用了相同的名字来命名所定义的类或函数。

例4 名字冲突

程序员甲在头文件headerl.h中定义了类 Student和函数fun。

// 例4中的头文件header1(头文件1,没其文件名为cc8-4-h1.h)

#include

#include

using namespace std;

class Student//声明Student类

{public:

Student(int n,string nam,int a)

{num=n;name=nam;age=a;}

void get_data();

private:

int num;

string name;

int age; };

void Student::get_data()//成员函数定义

{ cout<<num<<" "<<name<<" "<<age<<endl; }

double fun(double a,double b)//定义全局函数(即外部函数)

{ return sqrt(a+b);}

在 main函数所在的文件中包含头文件headerl.h:

#include

using namespace std;

#include "header1.h"//注意要用双引号,因为文件一般是放在用用户目录中的

int main()

{Student stud1(101,"Wang",18);//定义类对象studl

stud1.get_data();

cout<<fun(5,3)<<endl;

return 0; }

程序 能正常运行,输出为

101 Wang 18

2.82843

如果程序员乙写了头文件header2.h,在其中除了定义其他类以外,还定义了类Student和函数fun,但其内容与头文件headerl.h中的 Student和函数fun有所不同。

// 例4中的头文件header2

#include

#include

using namespace std;

class Student//声明Student类

{ public:

Student(int n,string nam,char s)//参数与headerl中的student不同

{ num=n;name=nam;sex=s;}

void get_data();

private:

int num;

string name;

char sex; };//此项与headerl不同

void Student::get_data()//成员函数定义

{ cout<<num<<" "<<name<<" "<<sex<<endl; }

double fun(double a,double b)//定义全局函数

{ return sqrt(a-b);}//返回值与headerl中的fun函数不同

//头文件2中可能还有其他内容

假如主程序员在其程序中要用到headerl.h中的Student和函数fun,因而在程序中包含了头文件headerl.h,同时要用到头文件 header2.h中的一些内容(但对header2.h中包含与headerl.h中的Student类和fun函数同名而内容不同的类和函数并不知情,因为在一个头文件中往往包含许多不同的信息,而使用者往往只关心自己所需要的部分,而不注意其他内容),因而在程序中又包含了头文件 header2.h。如果主文件(包含主函数的文件)如下:

#include

using namespace std;

#include "header1.h"//包含头文件l

#include "header2.h"//包含头文件2

int main()

{ Student stud1(101,"Wang",18);

stud1.get_data();

cout<<fun(5,3)<<endl;

return 0; }

这时程序编译就会出错。因为在预编译后,头文件中的内容取代了对应的#include命令行,这样就在同一个程序文件中出现了两个Student类和两个 fun 函数,显然是重复定义,这就是名字冲突,即在同一个作用域中有两个或多个同名的实体。

3、全局命名空间污染(global namespace pollution)。

在程序中还往往需要引用一些库(包括C++编译系统提供的库、由软件开发商提供的库或者用户自己开发的库),为此需要包含有关的头文件。如果在这些库中包含有与程序的全局实体同名的实体,或者不同的库中有相同的实体名,则在编译时就会出现名字冲突。

为了避免这类问题的出现,人们提出了许多方法,例如:将实体的名字写得长—些(包含十几个或几十个字母和字符);把名字起得特殊一些,包括一些特殊的字符;由编译系统提供的内部全局标识符都用下划线作为前缀,如_complex(),以避免与用户命名的实体同名;由软件开发商提供的实体的名字用特定的字符作为前缀。但是这样的效果并不理想,而且增加了阅读程序的难度,可读性降低了。

C语言和早期的C++语言没有提供有效的机制来解决这个问题,没有使库的提供者能够建立自己的命名空间的工具。人们希望ANSI C++标准能够解决这个问题,提供—种机制、一种工具,使由库的设计者命名的全局标识符能够和程序的全局实体名以及其他库的全局标识符区别开来。


什么是命名空间(解决方案)


命名空间:实际上就是一个由程序设计者命名的内存区域,程序设计者可以根据需要指定一些有名字的空间域,把一些全局实体分别放在各个命名空间中,从而与其他全局实体分隔开来。

如:namespace ns1//指定命名中间nsl

{ int a;

double b; }

<p style="margin:0in; padding-top:0px; padding-bottom:0px; font-family:simsun; border:0px; outline:0px; font-size:14px; vertical-align:baseline; color:rgb(68,68,68); line-height:21px; list-style:none; word-wrap:normal; word-

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

其实在 c++语言里面const修饰的才算是一个真正的常量,在 c 语言中 const 可以说是个“冒牌货”。为什么会这样?其实是 c++ 编译器对 const 进行了加强,当 c++ 编译器遇到常量声明时,不会像 c...

关键字: c++ C语言 const

返回函数的引用去初始化一个新的引用这个和前面一样,都是不会产生副本,但是现在是用返回值去初始化一个引用声明c,也就是说这时候变成了变量temp的别名,在c的生命周期内temp是一直有效的,这样做完全可以。

关键字: c++ 返回值 引用声明

C++是一种面向对象的高级程序设计语言,是C语言的超集。

关键字: c++ C语言

在Linux虚拟化技术中,网络级别上最重要的三项技术是网络名称空间、线对和Veth桥接器或虚拟交换机技术。 今天,我们将指导您学习Linux网络虚拟化技术。

关键字: Linux namespace network 虚拟网络

分析:这是Adobe 公司2007 年校园招聘的最新笔试题。这道题除了考察应聘者的C++ 基本功底外,还能考察反应能力,是一道很好的题目。 在Java 中定义了关键字final ,被final 修饰的

关键字: c++ class

泛型算法中的定制操作很多算法都会比较输入序列中的元素,通过定制比较动作,可以控制算法按照编程者的意图工作。本文以string排序为例进行说明,首先是缺省的排序动作: vector v{"This","

关键字: c++

为什么是lambda?讲了这么多天的lambda表达式,有一个很基本的问题没有回答:为什么叫lambda表达式呢?首先这个lambda就是罗马字母λ,lambda表达式即λ表达式。数学上有一个概念叫λ

关键字: c++

        假设我们有个函数用来揭示处理程序的优先权,另一个函数用来在某动态分配所得的Widget 上进行某些带有优先权的处理:int priority () ; void processWi

关键字: c++ effective

判断链表中是否有环最经典的方法就是快慢指针,同时也是面试官大多想要得到的答案。       快指针pf(f就是fast的缩写)每次移动2个节点,慢指针ps(s为slow的缩写)每次移动1个节点,如果快

关键字: c++ 链表 快慢指针

转载请注明出处:http://blog.csdn.net/callon_h/article/details/52073268 引子 上一篇博客从内核驱动到android app讲述了android通过

关键字: c++ java
关闭
关闭