C++命名空间深度解析

article/2025/8/2 16:09:34

1.命名空间的价值

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

举个例子:

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

这是一个正确的C语言代码(但并不推荐这种写法),局部变量rand覆盖了全局变量的数值,能够正确运行。但是只要加入一个头文件,就会使程序运行错误,看:
在这里插入图片描述
报错信息显示,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<stdio.h>
//#include<stdlib.h>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++ 中,:: 是作用域解析运算符,用于访问全局作用域或特定命名空间中的标识符。
在这里插入图片描述
注意:这里将#include<stdlib.h>给注释了,不然第二次打印会报错,跟rand函数冲突,但第一次打印可以正常运行,大家可以去试一试。

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

#include <iostream>
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 << "Inside function: " << lifeLocal << endl;  // 输出局部变量值// lifeLocal在此处销毁
}int main() {// 访问全局变量(直接使用变量名)cout << "Global: " << lifeGlobal << endl;// 访问命名空间变量(通过命名空间限定符)cout << "Namespace: " << MyNS::lifeNS << endl;// 访问类静态成员(通过类名限定符)cout << "Class static: " << MyClass::lifeStatic << endl;// 调用函数,创建并销毁局部变量testScopes();// 函数调用结束后:cout << "After function call:" << endl;// 全局变量、命名空间变量和类静态成员仍然有效cout << "Global: " << lifeGlobal << endl;cout << "Namespace: " << MyNS::lifeNS << endl;cout << "Class static: " << MyClass::lifeStatic << endl;return 0;
}

在这里插入图片描述

• namespace只能定义在全局,当然他还可以嵌套定义。

#include<iostream>
using namespace std;namespace hhy
{int num1 = 10;namespace ty{int num2 = 20;}
}int main()
{cout << hhy::tsy::num2 << endl;
}

上图我在hhy命名空间里嵌套定义了ty命名空间,程序可以正确打印20。

• 项⽬工程中多文件中定义的同名namespace会认为是⼀个namespace,不会冲突。

在这里插入图片描述

在上面图片,我定义了math.h,math.cpp,test.cpp三个文件,在文件中分别定义了Calc命名空间,程序是可以正确运行的,定义重名命名空间并不会使程序发生错误。

• C++标准库都放在⼀个叫std(standard)的命名空间中。

std 是 C++ 标准库的官方命名空间,它将标准库的所有内容(如 cout、endl、vector 等)封装起来,防止污染全局作用域。
如果不使用 using namespace stdstd:: 限定符,编译器会认为 cout 等标识符未定义,导致编译错误。

3. 命名空间使用

编译查找⼀个变量的声明/定义时,默认只会在局部或者全局查找,不会到命名空间里面去查找。所以下面程序会编译报错。

#include<stdio.h>
namespace N
{int a = 0;int b = 1;
}
int main()
{// 编译报错:error C2065: “a”: 未声明的标识符printf("%d\n", a);return 0;
}

所以我们要使用命名空间中定义的变量/函数,有三种方式:
• 指定命名空间访问,项目中推荐这种方式。
• using将命名空间中某个成员展开,项目中经常访问的不存在冲突的成员推荐这种方式。
• 展开命名空间中全部成员,项目不推荐,冲突风险很大,日常小练习推荐使用。

#include<stdio.h>
namespace N
{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;
}

http://www.hkcw.cn/article/KyoxFCjUqE.shtml

相关文章

上海工作机会:Technical Writer Senior Technical Writer - 中微半导体设备

大名鼎鼎的中微半导体招聘文档工程师了,就是那家由中国半导体产业的领军人物尹志尧领导的、全员持股的公司。如果你还不了解他,赶快Deepseek一下“尹志尧”了解。 招聘职位:Technical Writer & Senior Technical Writer 公司名称:中微半导体设备(上海)股份有限公司…

2024年12月 C/C++(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

C/C++编程(1~8级)全部真题・点这里 第1题:最近的斐波那契数 斐波那契数列 Fn 的定义为:对 n ≥ 0 有 Fn+2 = Fn+1 + Fn,初始值为 F0 = 0 和 F1 = 1。所谓与给定的整数 N 最近的斐波那契数是指与 N 的差之绝对值最小的斐波那契数。 本题就请你为任意给定的整数 N 找出与之最…

大数据集群架构hadoop集群、Hbase集群、zookeeper、kafka、spark、flink、doris、dataease(三)

hbase集群部署 wget -c https://dlcdn.apache.org/hbase/2.5.10/hbase-2.5.10-bin.tar.gz 下载地址 在master-1操作 tar xf hbase-2.5.10-bin.tar.gz -C /data/ && mv /data/hbase-2.5.10 /data/hbase vim /etc/profile export HBASE_HOME/data/hbase export PAT…

2022—2025年:申博之路及硕士阶段总结

文章目录 1 前景概要2 打造神兵利器2.1 夺天地之精2.2 锻兵魂之形2.3 契人兵之命 3 潜心闭关修炼3.1 第一阶段&#xff1a;苦心智3.2 第二阶段&#xff1a;劳筋骨3.3 第三阶段&#xff1a;摧意志 4 突破晋级4.1 突破失败4.2 聚气凝神4.3 心魔再现4.4 新起点 5 回顾及深思 1 前景…

NetSuite Bundle - Dashboard Refresh

儿童节快乐&#xff01; 今朝发一个Bundle&#xff0c;解决一个NetSuite Dashboard的老问题。出于性能上的考虑&#xff0c;NetSuite的Dashboard中的Portlet&#xff0c;只能逐一手工刷新。有人基于浏览器做了插件&#xff0c;可以进行自动刷新。但是在我们做项目部署时&#…

简析PointNet++

简析PointNet 更好的阅读体验&#xff0c;欢迎访问 简析PointNet 获得 论文: https://arxiv.org/abs/1706.02413 TensorFlow 版本代码: https://github.com/charlesq34/pointnet2 Pytorch 版本代码: https://github.com/yanx27/Pointnet_Pointnet2_pytorch 背景 在PointNet中…

2024 CKA模拟系统制作 | Step-By-Step | 8、题目搭建-创建 Ingress

目录 ​​​​​​免费获取题库配套 CKA_v1.31_模拟系统 一、题目 二、核心考点 Ingress 资源定义 Ingress Controller 依赖 服务暴露验证 网络层次关系 三、搭建模拟环境 1.创建命名空间 2.安装ingress ingress-nginx-controller 3.创建hello.yaml并部署 四、总结 …

Android Java 版本与 Gradle 版本兼容问题:use incompatible Java 21.0.3 and Gradle 4.8.1.

问题与处理策略 问题描述 打开一个 Android 项目&#xff0c;报如下错误 Your build is currently configured to use incompatible Java 21.0.3 and Gradle 4.8.1. Cannot sync the project.We recommend upgrading to Gradle version 8.9.The minimum compatible Gradle v…

深度理解Restful开发规范【总结】

目录 &#x1f499;一、为啥要遵循 Restful 开发规范 ❤️二、Restful 初印象 &#x1f49a;&#xff08;一&#xff09;啥是 Restful &#x1f49c;&#xff08;二&#xff09;核心原则 &#x1f499;三、Restful 在 Java 中的实战 &#x1f49b;&#xff08;一&#xf…

【SF顺丰】顺丰开放平台API对接(Java对接篇)

对接前置篇&#xff1a; 【SF顺丰】顺丰开放平台API对接&#xff08;注册、API测试篇&#xff09;_顺丰api接口对接指南-CSDN博客 1.实现效果展示 2.SF顺丰开放平台&#xff0c;JDK资源下载。 下载地址&#xff1a;顺丰开放平台 3.将下载的JDK放入项目中。 4.将JDK资源引入p…

Java 大视界 —— Java 大数据在智能建筑室内环境舒适度预测与调控中的应用(269)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

树莓派3B小练习

PWM驱动LED灯 3B引脚图 PWM通道 GPIO号 物理引脚 复用功能 PWM0 GPIO12 32 Alt Fun 0 PWM1 GPIO13 33 Alt Fun 0 PWM0 GPIO18 12 Alt Fun 5 PWM1 GPIO19 35 Alt Fun 5 第一步 启用pwm&#xff08;默认情况下未启用&#xff09; 简而言之&#xff0c;你无法通过Linux内核API…

中国信通院:《“机器人+人工智能”工业应用研究报告》| 人工智能赋能机器人,如何重塑工业版图?

在数字经济蓬勃兴起的浪潮中&#xff0c;《中国信通院&苏州机器人产业协会-“机器人人工智能”工业应用研究报告》为我们揭示了智能制造的未来图景。 这份报告不仅是技术发展的记录&#xff0c;更是产业升级的指南。它以深刻的洞察力&#xff0c;剖析了“机器人人工智能”…

LangChain-结合GLM+SQL+函数调用实现数据库查询(三)

针对 LangChain-结合GLM+SQL+函数调用实现数据库查询(二)-CSDN博客 进一步简化 通过 LangChain 和大语言模型(GLM-4)实现了一个 AI 代理,能够根据自然语言提问自动生成 SQL 查询语句,并连接 MySQL 数据库执行查询,最终返回结果。 整个流程如下: 用户提问 → AI 生成 SQ…

8天Python从入门到精通【itheima】-62~63

目录 第六章开始-62节-数据容器入门 1.学习目标 2.为什么要学习数据容器&#xff1f; 3.什么是Python中的数据容器 4.小节总结 63节-列表的定义语法 1.学习目标 2.为什么需要列表&#xff1f; 3.列表定义的基本语法 4.列表定义的基本语法-案例演示 5.列表定义的基本语…

重学计算机网络之以太网

一&#xff1a;历史发展进程 DIX EtherNet V2 战胜IEEE802.3成为主流版本。总线型交换机拓扑机构代替集线器星型拓扑机构 1990年IEEE制定出星形以太网10BASE-T的标准**802.3i**。“10”代表10 Mbit/s 的数据率&#xff0c;BASE表示连接线上的信号是基带信号&#xff0c;T代表…

4、数据标注的武林秘籍:Label-Studio vs CVAT vs Roboflow

开篇痛点&#xff1a;90%的模型效果取决于数据质量 "标注3小时&#xff0c;训练5分钟"——这是很多AI工程师的真实写照。上周有位读者训练YOLOv12时发现&#xff0c;同样的代码&#xff0c;换批数据mAP直接跌了15%&#xff0c;根本原因是标注不规范&#xff01;本文…

一天搞懂深度学习--李宏毅教程笔记

目录 1. Introduction of Deep Learning1.1. Neural Network - A Set of Function1.2. Learning Target - Define the goodness of a function 2. Tips for Training Deep Neural Network3. Variant of Neural Network4. Next Wave 对一天搞懂深度学习–李宏毅教程分享内容做读…

【Canvas与色彩】八彩大风车

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>八彩风车 Draft1</title><style type"text/css"&…

Linux权限

文章目录 一、Linux用户权限1.1权限的概念1.2 用户分类##1.3切换用户1.4sudo提权 二、Linux文件权限2.1文件属性2.2文件的类型2.3 基本权限##2.4权限划分 三、Linux文件权限的修改方法3.1 chmod3.1.1操作符3.1.2数字模式 3.2chown3.3chgrp3.4目录文件权限的具体剖析3.4.1目录的…