资讯专栏INFORMATION COLUMN

关于c++的namespace,你真的了解吗?真的会用吗?

Lionad-Morotar / 913人阅读

摘要:据我了解,很多学校在学习的时候,老师会让学生死记一条语句,那就是那么你真的了解它吗命名空间是一个命名空间。如果我们真的想使用的话,的命名空间遍给了我们解决方法使用命名空间。

据我了解,很多学校在学习c++的时候,老师会让学生死记一条语句,那就是

using namespace std;

那么你真的了解它吗?

(1)命名空间

namespace是一个命名空间。在讲述命名空间之前先了解为什么c++之父要创造这个功能。

在一个巨大的项目面前,很难保证每一个的协调一致,如果张三用了某一个变量,李四又不知道张三用了这个变量,那么这会导致命名重复。为了解决这个问题,就有了命名空间这个概念。

再讲一句,我们有一些函数,比如printf函数,这些函数是编写出来的,只是编写者取了这个printf当做函数的名字而已,所以我们定义变量的时候才不能使用printf等会产生争议的名字。

如果我们真的想使用的话,c++的命名空间遍给了我们解决方法----使用命名空间。

#include#includeint main(){    int printf=1;    printf("%d",printf);//这里我们暂时使用printf进行演示,所以引上头文件stdio.h}

首先毫无疑问,这个是不可能的

如果有的老铁就是想用printf的话,我们此时就可以使用命名空间了。

首先:命名空间是全局的,必须写在main函数外面

#include#includenamespace lxy{   int printf=1;}int main(){   printf("%d",lxy::printf);   return 0;}

这样的话是可以把1打印出来的,接下来详细讲一下:

这个lxy的位置是我自己命名的,代表这个是我自己的命名空间,当然这里你可以任意的命名。

这个namespace是一个域,跟结构体不一样,结构体那个是声明,这个域就像是隐身衣一样,让系统编译的时候不会去这个区里面读取,所以这个时候系统不会认为出现了两个printf,从而不会引发问题,但是当我们使用的时候我们可以写上lxy::也就是命名空间的名字加个域作用限定符让系统到命名空间查找这个变量。

这里要注意的是:命名空间是全局的,必须写在main外面,且这个东西仅仅就是加了一个外壳,这个外壳的作用是让编译器编译的时候不在这个空间里面作文章。所以里面该怎么写就怎么写,比如可以写结构体,可以写函数等等。相当于是你在main外面写了一些东西,但是加上namespace加个隐身而已。

但是外面要牢记,这个东西是一个隐身衣,就可以应对各种情况,在lxy::之前这个隐身衣一直在隐身。

下面列举一些例子:

#include#includenamespace lxy {	int printf;}int main(){	printf = 1;//错,系统会认为你对这个函数赋值了,没有任何意义,直接报错	lxy::printf = 1;//对,你专门用了printf这个(全局)变量,我们说过了int printf写在main外面,是全局的	//只是加上了隐身buff而已。	printf("%d", lxy::printf);	return 0;}

函数也一样的:

#include#includenamespace lxy {	int printf;	int Add(int a, int b)	{		return a + b;	}}int main(){	printf("%d", lxy::Add(5,6));	return 0;}

但是如果我把函数实现写在外面,里面写函数声明呢?因为隐身衣的缘故,相当于你没有写函数声明,如果你的函数定义写在main上面的话,这样也可以。(同一个cpp文件)

#include#includenamespace lxy {	int printf;	int Add(int a, int b);}int Add(int a, int b){	return a + b;}int main(){	printf("%d", /*lxy::*/Add(5,6));	return 0;}

请注意,这个时候你不可以写lxy::了,因为如果你这么写的话系统会优先的马上去lxy的命名空间查找,发现只有函数定义哦,所以肯定是打印不出来的。

把本代码函数定义移到其他cpp文件或者main下面的话,也是无法打印的。

我们等会讲完之后会专门把结构体提出来讲。

注意:1.namespace可以嵌套

2.可以在不同的地方使用多次,比如不同的cpp文件中。其中命名空间名字一样的空间会被编译器整合在一起,所以你可以在一个源文件里面写函数声明,另一个里面写函数定义。这是没问题的。

 (2)命名空间的使用

1.嵌套命名空间的使用(我这里可以使用rand这个函数名作为变量因为我隐身了)

#include#includenamespace lxy {	namespace yzza {		int rand;	}}using namespace std;int main(){	lxy::yzza::rand = 5;	cout << lxy::yzza::rand << endl;	return 0;}

2.如果你不想写lxy::这样复杂的东西可以解除隐身,但是这个时候你已经解除了哦,相当于没有隐身了。

#include#includenamespace lxy {	namespace yzza {		int rand1;	}	int a=10;}using namespace std;using namespace lxy::yzza;//这样代表解除的是yzza,此时相当于变量a没有解除的,要解除a你还要写//using namespace lxy;int main(){	rand1 = 5;	cout << rand1 <

这样解放的是整个命名空间,你也可以只解放一个变量

#include#includenamespace lxy {	namespace yzza {		int rand1;	}	int a=10;}using namespace std;using lxy::yzza::rand1;//解放rand1using lxy::a;//解放aint main(){	rand1 = 5;	cout << rand1 <

那么回到标题的问题,你们知道为什么要加上这句话了吗?

因为c++的函数名全部定义在std这个命名空间里面。如果不加这句话你加上std::也是一样可以使用库函数的。不过你就不能定义跟函数重名的变量了。

关于结构体提一句。

#include#includenamespace lxy {	struct yzza {		int a;	}N1;}//using lxy::N1;int main(){	lxy::N1.a = 5;	printf("%d", lxy::N1.a);	return 0;}

这里是结构体变量名直接定义了的,直接按照上面的写。

#include#includenamespace lxy {	struct yzza {		int a;	}N1;}using lxy::yzza;int main(){	N1.a = 5;	printf("%d", N1.a);	return 0;}

此时写lxy::yzza是直接错误的,编译器直接报错

#include#includenamespace lxy {	struct yzza {		int a;	};}using lxy::yzza;int main(){	struct yzza N1;	N1.a = 5;	printf("%d", N1.a);	return 0;}

直接写lxy::yzza。

#include#includenamespace lxy {	struct yzza {		int a;	};}//using lxy::yzza;int main(){	struct lxy::yzza N1;//注意::的位置,我们找的是yzza,不能写	//struct yzza lxy::N1	N1.a = 5;//此时这里什么都不用写了,因为我的结构体变量已经定义完成了	printf("%d",  N1.a);	return 0;}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/125078.html

相关文章

  • 多线程通信三大法器,会用

    摘要:是多线程之间通信最重要的个方法,今天,栈长给大家普及一下它们的知识要点及应用实战。实战微信公众号技术栈技术栈上面的例子结合来演示了它们的相互作用。更多多线程技术文章请在技术栈微信公众号后台回复关键字多线程。 wait, notify, notifyAll 是多线程之间通信最重要的 3 个方法,今天,栈长给大家普及一下它们的知识要点及应用实战。 定义 wait:让持有该对象锁的线程等待;...

    liuyix 评论0 收藏0
  • 知道Python字符串怎么用

    摘要:方法可接收两个参数,第一个参数是分隔符,即用来分隔字符串的字符,默认是所有的空字符,包括空格换行制表符等。拆分过程会消耗分隔符,所以拆分结果中不包含分隔符。 正如《你真的知道Python的字符串是什么吗?》所写,Python 中字符串是由 Uniocde 编码的字符组成的不可变序列,它具备与其它序列共有的一些操作,例如判断元素是否存在、拼接序列、切片操作、求长度、求最值、求元素的索引位...

    Thanatos 评论0 收藏0
  • 知道Python字符串怎么用

    摘要:方法可接收两个参数,第一个参数是分隔符,即用来分隔字符串的字符,默认是所有的空字符,包括空格换行制表符等。拆分过程会消耗分隔符,所以拆分结果中不包含分隔符。 正如《你真的知道Python的字符串是什么吗?》所写,Python 中字符串是由 Uniocde 编码的字符组成的不可变序列,它具备与其它序列共有的一些操作,例如判断元素是否存在、拼接序列、切片操作、求长度、求最值、求元素的索引位...

    scwang90 评论0 收藏0
  • 知道Python字符串怎么用

    摘要:方法可接收两个参数,第一个参数是分隔符,即用来分隔字符串的字符,默认是所有的空字符,包括空格换行制表符等。拆分过程会消耗分隔符,所以拆分结果中不包含分隔符。 正如《你真的知道Python的字符串是什么吗?》所写,Python 中字符串是由 Uniocde 编码的字符组成的不可变序列,它具备与其它序列共有的一些操作,例如判断元素是否存在、拼接序列、切片操作、求长度、求最值、求元素的索引位...

    Jinkey 评论0 收藏0
  • 知道Python字符串怎么用

    摘要:方法可接收两个参数,第一个参数是分隔符,即用来分隔字符串的字符,默认是所有的空字符,包括空格换行制表符等。拆分过程会消耗分隔符,所以拆分结果中不包含分隔符。 正如《你真的知道Python的字符串是什么吗?》所写,Python 中字符串是由 Uniocde 编码的字符组成的不可变序列,它具备与其它序列共有的一些操作,例如判断元素是否存在、拼接序列、切片操作、求长度、求最值、求元素的索引位...

    jifei 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<