【c++】NameSpace ---命名空间详解

一.为什么要命名空间

我们知道在一个学校,一个班级难免会存在两个人的名字是相同的,那么我们区分他们的话,那就不能只仅仅根据名字了,我们可能还需要加入其他的条件,如性别,年龄…!
同样的,我们在c++编写时,可能我们正在编写一些具有名为geqian()函数的代码,并且还有另一个可用的库,它也具有相同的geqian()函数。现在编译器无法知道您在代码中引用的geqian()函数的哪个版本。那么编译器就会报错!
eg:

#include<iostream>
#include <stdlib.h>

int rand = 1;
int main()
{
	printf("%d\n", rand);
	return 0;
}

当我们运行时,会报错,说rand重定义了,以前定义是函数,这是为啥呢?在这里插入图片描述

这是因为我们在C语言中,stdlib中有一个rand()的库函数,与我们要使用的这个变量rand相冲突了,所以编译器才会报错!
那么,我们要怎么解决这个问题呢?
这就使用到了我们c++中命名空间,使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染namespace关键字的出现就是针对这种问题的!

二.命名空间的定义:

定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。
1.命名空间将全局作用域分成不同的部分;
2.不同命名空间中的标识符可以同名而不会发生冲突;
3.命名空间可以发生嵌套;
4.全局作用域也叫默认命名空间;

namespace geqian  //geqian是命名空间的名字
{
	//命名空间中可以定义变量/函数/结构体类型
	int rand = 1;

	int add(int a, int b)
	{
		return a + b;
	}

	struct Stu
	{
		char name;
		int age;
	};
}


//命名空间可以嵌套
namespace geqian
{
	int a;
	int b;
	int mul(int a, int b)
	{
		return a * b;
	}

	namespace geqian10
	{
		int c;
		int d;
		int sub(int a, int b)
		{
			return a - b;

		}
	}
}

并且在同一个工程中允许存在多个相同名称的命名空间,编译器最终会合并成同一个命名空间中。
eg:我再test.h中再定义一个geqian,那么在test.c和test.h中两个geqian就会合并成一个。
在这里插入图片描述
**注意:**一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中

三.命名空间的使用:

那么,命名空间到底如何使用呢?
命名空间的使用有三种方式:
一:加命名空间名称及作用域限定符

#include<iostream>
namespace geqian
{
	int rand = 1;

}
int main()
{
	printf("%d\n", geqian::rand);
	return 0;
}

这里的geqian就是我们所说的命名空间名称,而::就是作用域限定符

二:使用using将命名空间中某个成员引入

#include<iostream>
namespace geqian
{
	//int rand = 1;
	int rand1 = 2;


}

using geqian::rand1;

int main()
{
	//printf("%d\n", geqian::rand);
	printf("%d\n", rand1);

	return 0;
}

三:使用using namespace 命名空间名称 引入

#include<iostream>
namespace geqian
{
	int rand = 1;
	int rand1 = 2;


}

using namespace geqian;

int main()
{
	printf("%d\n", geqian::rand);
	printf("%d\n", rand1);

	return 0;
}

汇总以上eg:

#include <iostream>
namespace geqian1
{
	int a = 10;
}

namespace geqian2
{
	int a = 20;

	namespace geqian3 //嵌套命名空间
	{
		struct P      //嵌套命名空间
		{
			int x;
			int y;
		};
	}
}

int main()
{
	using namespace geqian1; //使用using namespace 整个命名空间名称引入
	using geqian2::geqian3::P;  //使用嵌套的命名空间

	printf("%d\n", a);
	printf("%d\n", geqian2::a);  //使用命名空间中的变量

	P p = { 30, 40};

	printf("%d\n", p.x);
	printf("%d\n", p.y);

	return 0;
}

运行结果:
在这里插入图片描述

四:命名空间访问顺序:

那么到目前为止,我们已经get了,局部域,全局域,命名空间域,那在我们的代码中,这几者之间的访问顺序是怎样的?
先上结论:
局部域->全局域 -> 展开了命名空间域 or 指定访问命名空间域
下面,我们用代码一一验证
首先,毫无疑问的是局部域肯定是优先我们全局域的,因为我们的局部变量的优先级高于全局变量的优先级!
那如果我们就是想访问全局变量的,我们可以在访问对象前加::,这样我们访问的就是全局变量

#include <iostream>
int rand = 1;

int main()
{
	int rand = 2;

	printf("%d\n", ::rand);
	return 0;
}

在下面这种情况,不存在全局变量,我们也可以把命名空间域当作全局变量一样看待:

#include <iostream>
namespace geqian
{
	int a = 2;
}

using namespace geqian;//展开命名空间域

int main()
{
	printf("%d\n", a);
	return 0;
}

如果,我们在命名空间域中,我们想指定一个特殊的变量或者函数,那么我们可以使用using 命名空间名::变量/函数名。

#include <iostream>

namespace geqian
{
	int a = 2;
	int add(int x, int y)
	{
		return x + y;
	}
}

using geqian::add;

int main()
{
	//printf("%d\n", a); 这个就会发生报错
	printf("%d\n", add(3,4));
	return 0;
}

运行结果:
在这里插入图片描述

本篇博客的内容【NameSpace --命名空间的使用】到此结束。
若对你有些许帮助,可以点赞、关注、评论支持下博主,你的支持将是我前进路上最大的动力。
若以上内容有任何问题,欢迎在评论区指出。若对以上内容有任何不解,都可私信评论询问。
诸君,山顶见!
在这里插入图片描述

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值