C++·初步认识(命名空间)

本文介绍了C++中命名空间的出现原因,如何定义(包含变量、函数和类型)、以及三种使用方式:通过作用域限定符访问、using引入部分成员和usingnamespace展开整个命名空间。通过实例展示了命名空间如何避免全局作用域下的命名冲突。
摘要由CSDN通过智能技术生成

1.为什么会出现

在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。

#include <stdio.h>
#include <stdlib.h>
int rand = 10;
int main()
{
	printf("%d\n", rand);
	return 0;
}
//编译后报错
//错误	C2365	“rand”: 重定义;以前的定义是“函数”
//重定义;以前的定义是“函数”(rand 随机数函数)

C语言没办法解决类似这样的命名冲突问题,所以C++提出了namespace来解决

#include<iostraem>
#include<stdlib.h>
namespace Room
{
	int rand = 0;
}
int main()
{
	printf("%d", Room::rand);
	return 0;
}
//程序正常运行

2.命名空间如何定义

定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。

命名空间可定义变量、函数、类型
命名空间可以嵌套

namespace Room
{
	//变量
	int rand = 0;
	//函数
	int Add(int a, int b)
	{
		return a + b;
	}
	//类型
	struct Node {
		int val;
		struct Node* Next;
	};
	//嵌套
	namespace room
	{
		int b = 0;
		int Sub(int a, int b)
		{
			return a - b;
		}
		struct NNode {
			int val;
			struct NNode* Next;
		};
	}
}

3.命名空间如何使用

① 加命名空间名称及作用域限定符(命名空间不展开)

作用域限定符 “::”
使用方式:命名空间名字 :: 命名空间内部变量、函数、或类型
其作用是通知编译器应从作用域限定符左侧的名字所示的作用域****中寻找右侧那个名字,即指定访问哪个名字空间的哪个成员。

#include<stdio.h>
namespace Room
{
	//变量
	int rand = 0;
	//函数
	int Add(int a, int b)
	{
		return a + b;
	}
	//类型
	struct Node {
		int val;
		struct Node* Next;
	};
	//嵌套
	namespace room
	{
		int b = 0;
		int Sub(int a, int b)
		{
			return a - b;
		}
		struct NNode {
			int val;
			struct NNode* Next;
		};
	}
}
int main()
{
	//访问变量
	printf("%d\n", Room::rand);
	//访问函数
	printf("%d\n", Room::Add(1, 2));
	//定义类型,域作用符在struct后
	struct Room::Node NewNode;
	NewNode.val = 0;
	NewNode.Next = nullptr;//c++新增关键字 空指针NULL的升级版
	printf("%d\n", NewNode.val);
	//访问嵌套命名空间的变量
	printf("%d\n", Room::room::b);
	//访问嵌套命名空间的函数
	printf("%d\n", Room::room::Sub(2, 1));
	//访问嵌套命名空间的类型
	struct Room::room::NNode NNewNode;
	NNewNode.val = 0;
	NNewNode.Next = nullptr;
	printf("%d\n", NNewNode.val);
	return 0;
}

②使用using将命名空间中某个成员引入(命名空间部分展开)

using 命名空间名字 :: 命名空间内部变量、函数、或类型
将其展开,使其成为一个全局变量

#include<stdio.h>
//展开命名空间内部的变量
using Room::a;
//展开命名空间内部的函数
using Room::Add;
//展开命名空间内部的类型
using Room::Node1;
namespace Room
{
	int a = 0;
	int b = 1;
	int Add(int a, int b)
	{
		return a + b;
	}
	int Sub(int a, int b)
	{
		return a - b;
	}
	struct Node1 {
		int val;
		struct Node1* Next;
	};
	struct Node2 {
		int val;
		struct Node1* Next;
	};
}
int main()
{
	//变量a被展开,不需要域作用符
	//变量b未被展开,需要域作用符
	printf("%d\n", a);
	printf("%d\n", Room::b);
	//函数Add被展开,不需要域作用符
	//函数Sub未被展开,需要域作用符
	printf("%d\n", Add(1, 2));
	printf("%d\n", Room::Sub(2, 1));
	//类型Node1被展开,不需要域作用符
	//类型Node2未被展开,需要域作用符	
	struct Node1 NewNode1;
	NewNode1.val = 0;
	struct Room::Node2 NewNode2;
	NewNode2.val = 0;
	return 0;
}

③使用using namespace 命名空间名称引入(命名空间全部展开)

using namespace 命名空间名字

#include<stdio.h>
using namespace Room;
namespace Room
{
	//变量
	int rand = 0;
	//函数
	int Add(int a, int b)
	{
		return a + b;
	}
	//类型
	struct Node {
		int val;
		struct Node* Next;
	};
	//嵌套
	namespace room
	{
		int b = 0;
		int Sub(int a, int b)
		{
			return a - b;
		}
		struct NNode {
			int val;
			struct NNode* Next;
		};
	}
}

int main()
{
	//访问变量
	printf("%d\n", rand);
	//访问函数
	printf("%d\n", Add(1, 2));
	//定义类型,域作用符在struct后
	struct Node NewNode;
	NewNode.val = 0;
	NewNode.Next = nullptr;
	printf("%d\n", NewNode.val);
	//展开的是命名空间Room,不需要struct Room::room::NNode NNewNode;
	//但是struct NNode在room之中仍需要room::NNode
	struct room::NNode NNewNode;
	NNewNode.val = 0;
	NNewNode.Next = nullptr;
	printf("%d\n", NNewNode.val);
	return 0;
}

同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。
一个工程中的test.h和上面test.cpp中两个Room会被合并成一个

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值