C++命名空间深度解析

06-02 1171阅读

1.命名空间的价值

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

举个例子:

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

这是一个正确的C语言代码(但并不推荐这种写法),局部变量rand覆盖了全局变量的数值,能够正确运行。但是只要加入一个头文件,就会使程序运行错误,看:

C++命名空间深度解析

报错信息显示,rand被重定义了,因为标准库中已经有一个名为rand()的函数(用于生成随机数)。为了避免这种情况,C++语言引进了namespace关键字。

2. namespace定义

• 定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接⼀对{}即可,{}中即为命名空间的成员。命名空间中可以定义变量/函数/类型等。

namespace hhy
{
	int rand = 1;
	int Add(int x, int y)
	{
		return x + y;
	}
	struct Stu
	{
		int age;
		char name[10];
	};
}

这是一个简单的命名空间,定义了一个变量,函数和结构体。

• namespace本质是定义出⼀个域,这个域跟全局域各自独立,不同的域可以定义同名变量,所以下面的rand不在冲突了。

#include
//#include
int rand = 10;
namespace hhy
{
	int rand = 1;
	int Add(int x, int y)
	{
		return x + y;
	}
	struct Stu
	{
		int age;
		char name[10];
	};
}
int main()
{
	printf("%d\n", hhy::rand);//在hhy命名空间寻找rand变量
	printf("%d\n", ::rand);//在全局变量中寻找rand变量
	return 0;
}

在 C 和 C++ 中,:: 是作用域解析运算符,用于访问全局作用域或特定命名空间中的标识符。

C++命名空间深度解析

注意:这里将#include给注释了,不然第二次打印会报错,跟rand函数冲突,但第一次打印可以正常运行,大家可以去试一试。

• C++中域有函数局部域,全局域,命名空间域,类域;域影响的是编译时语法查找⼀个变量/函数/类型出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就解决了。局部域和全局域除了会影响编译查找逻辑,还会影响变量的生命周期,命名空间域和类域不影响变量生命周期。

#include 
using namespace std;
// 全局作用域:变量lifeGlobal的生命周期从程序启动到结束
int lifeGlobal = 1;
// 命名空间作用域:变量lifeNS的生命周期同样贯穿程序全程
namespace MyNS {
    int lifeNS = 2;
}
// 类作用域:静态成员变量lifeStatic属于类本身,而非类的实例
class MyClass {
public:
    static int lifeStatic;  // 声明静态成员变量
};
// 定义并初始化静态成员变量(在全局/静态存储区分配内存)
int MyClass::lifeStatic = 3;
// 测试函数:展示局部变量的生命周期
void testScopes() {
    // 局部作用域:变量lifeLocal的生命周期从函数调用开始,到函数返回时结束
    int lifeLocal = 4;
    cout 
    // 访问全局变量(直接使用变量名)
    cout 
	int num1 = 10;
	namespace ty
	{
		int num2 = 20;
	}
}
int main()
{
	cout 
	int a = 0;
	int b = 1;
}
int main()
{
	// 编译报错:error C2065: “a”: 未声明的标识符
	printf("%d\n", a);
	return 0;
}

	int a = 1;
	int b = 2;
}
//指定命名空间访问
int main()
{
	printf("%d\n", N::a);
	return 0;
}
// using将命名空间中某个成员展开
using N::b;
int main()
{
	printf("%d\n", N::a);
	printf("%d\n", b);
	return 0;
}
// 展开命名空间中全部成员
using namespace N;
int main()
{
	printf("%d\n", a);
	printf("%d\n", b);
	return 0;
}
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码