C++ namespace(域)

news2025/1/12 6:07:51

个人主页:Jason_from_China-CSDN博客

所属栏目:C++系统性学习_Jason_from_China的博客-CSDN博客

namespace的价值

  1. 避免命名冲突:在大型项目或使用多个库的情况下,不同部分可能会定义相同名称的实体(如变量、函数、类等)。使用命名空间可以有效地避免这些命名冲突。【这一点的尤其关键的,在C语言里面,是没有域这样的区分之说的,所以会导致命名的冲突,尤其的当命名应该新变量的时候,如果引入新的库,会导致命名错误,就需要大量的修改命名,这会很麻烦。但是在C++里面,我们只需要在外层封装一层就可以了】

//这个C语言的代码就是有问题的,因为引入了新的库,从而导致需要更改命名,
//这里还是比较少的代码,如果代码数量比较多,那么就会存在大量重复的代码的工作
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
int rand = 10;
int main()
{
// 编译报错:error C2365: “rand”: 重定义;以前的定义是“函数”
printf("%d\n", rand);
return 0;
}
  1. 组织代码逻辑:命名空间可以将逻辑相关的代码组织在一起,使得代码结构更加清晰,便于理解和维护。

  2. 提供上下文:命名空间提供了一种上下文,使得程序员可以快速了解某个实体属于哪个模块或库。

  3. 支持大型项目开发:在大型项目中,可能需要包含多个库和子系统,命名空间的使用可以确保这些不同的部分在全局作用域中不会相互干扰。

  4. 促进代码重用:命名空间允许程序员在不同的上下文中重用相同的名称,而不必担心名称冲突,从而提高了代码的重用性。

  5. 简化代码编写:使用命名空间后,程序员可以在不同的命名空间中定义具有相同名称的变量或函数,简化了代码编写。

  6. 支持模块化开发:命名空间支持模块化开发,每个模块可以有自己的命名空间,从而实现代码的解耦。

  7. 提高编译效率:编译器在查找未限定名称时,会先在局部作用域查找,然后是类作用域,接着是命名空间作用域,最后是全局作用域。这种分层次的查找顺序可以提高编译效率。

  8. 便于代码维护:当需要修改或更新某个模块时,只需要关注该模块的命名空间,减少了对其他模块的影响。

  9. 支持语言的扩展性:随着 C++ 语言的发展,新的库和特性不断加入,命名空间的使用确保了新旧代码可以和谐共存,不会因新特性的加入而导致现有代码出现问题。

namespace定义

  • 定义命名空间,需要使用到namespace关键字,后⾯跟命名空间的名字,然后接⼀对{}即可,{}中即为命名空间的成员。命名空间中可以定义变量/函数/类型等。
  • namespace本质是定义出⼀个域,这个域跟全局域各自独立,不同的域可以定义同名变量,所以下面的rand不在冲突了。
  • C++中域有函数局部域,全局域,命名空间域,类域;域影响的是编译时语法查找⼀个变量/函数/类型出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就解决了。局部域和全局域除了会影响编译查找逻辑,还会影响变量的生命周期,命名空间域和类域不影响变量生命周期。
  •  namespace只能定义在全局,当然他还可以嵌套定义。
  • 项目工程中多文件中定义的同名namespace会认为是⼀个namespace,不会冲突。
  • C++标准库都放在⼀个叫std(standard)的命名空间中
  • namespace是C++基础关键字,不需要什么头文件

namespace单层的书写和调用

这里Js是命名空间的名字,一般在开发里面用项目的名字为命名空间的名字

这里我是随意起了一个名字

域里面也是可以书写函数和结构体等等的

//namespace只能定义在全局,当然他还可以嵌套定义。
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
namespace Js
{
	int c = 10;
	int ADD(int a, int b)
	{
		return a + b;
	}
}
int main()
{
	printf("%d", Js::c);
	return 0;
}
  1. #include<stdio.h>:这是另一个预处理指令,用于包含标准输入输出库的头文件。这个库提供了 printf 函数,它在 main 函数中被用来输出。

  2. namespace Js { ... }:这里定义了一个名为 Js 的命名空间。命名空间是一种封装机制,用于组织代码,防止命名冲突。在这个命名空间中:

    • int c = 10; 定义了一个名为 c 的整型变量,并初始化为 10
    • int ADD(int a, int b) { ... } 定义了一个名为 ADD 的函数,它接受两个整型参数 a 和 b,并返回它们的和。
  3. int main() { ... }:这是程序的主函数,程序从这里开始执行。

    • printf("%d", Js::c); 在这里,Js::c 表示对命名空间 Js 中的成员变量 c 的引用。printf 函数使用 Js::c 作为参数,输出 c 的值,即 10

总结来说,Js::c 是对 Js 命名空间中定义的静态成员变量 c 的引用。在 main 函数中,通过 Js::c 访问该变量,并使用 printf 函数将其值输出到控制台。

这里可以看到结果,进入到命名空间里面访问c,c我们初始化给的数值是10,所以访问的时候就是10

::域作用限定符

域作用限定符这里主要的作用就是访问域里面的变量或者函数

下面的如果看不懂没关系,直到域作用限定符在这里面是干什么用的就可以

  • 访问全局变量或函数:当局部作用域(如函数内部)中存在与全局作用域中同名的变量或函数时,可以使用 :: 来指定访问全局作用域中的实体。

//C++的输出方式
int globalVar = 10; // 全局变量

void function() {
    int localVar = 20; // 局部变量
    std::cout << ::globalVar << std::endl; // 访问全局变量
}
//C语言的输出方式
int a = 110;
int main()
{
	printf("全局变量的a=110,局部变量的a=11\n\n\n");
	int a = 11;
	printf("不加域作用限定符:%d\n\n\n", a);
	printf("加上域作用限定符:%d\n\n\n", ::a);

}

  • 访问命名空间中的成员:在包含多个命名空间的情况下,:: 用于指定访问特定命名空间中的成员。

namespace A {
    int value = 5;
}

namespace B {
    int value = 10;
}

int main() {
    std::cout << ::A::value << std::endl; // 输出 A 命名空间中的 value
    std::cout << ::B::value << std::endl; // 输出 B 命名空间中的 value
}
  • 访问类的静态成员:在类的作用域内部访问静态成员时,需要使用 :: 来指定。

class MyClass {
public:
    static int staticVar;
};

int MyClass::staticVar = 0; // 定义静态成员

void function() {
    MyClass::staticVar = 1; // 在类外访问静态成员
}
  • 解决作用域冲突:当嵌套作用域中存在同名实体时,:: 用于解决这些冲突,明确指定要访问的实体。

int outerVar = 1;

void outerFunction() {
    int innerVar = 2;
    std::cout << ::outerVar << std::endl; // 访问外部变量
}
  • 访问枚举类型的值:在 C++11 之前,枚举类型没有强类型支持,使用 :: 可以访问枚举中的值。

enum Color { RED, GREEN, BLUE };

int main() {
    std::cout << ::RED << std::endl; // 访问 RED 枚举值
}

namespace嵌套的书写和调用

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
namespace Js
{
	int c = 10;
	int ADD(int a, int b)
	{
		return a + b;
	}
	namespace js1
	{
		int d = 30; int f = 20;
		int del(int d, int f)
		{
			return d - f;
		}
	}
	namespace js2
	{
		int d = 30; int f = 20;
		int ADD(int d, int f)
		{
			return d + f;
		}
	}
}
int main()
{
	printf("namespace单层调用测试:%d\n", Js::c);

	int ret = Js::js1::del(30, 10);
	printf("namespace多层调用测试:%d", ret);
	return 0;
}

最终效果

  1. 在调用的时候,我们可以利用域作用限定符
  2. 进入到我们需要的域里面调用函数,并且选择接收。
  3. 我们既可以初始化,也可以选择传参,和C语言里面函数的使用是一样的。只是多了一层的封装。

namespace多文件定义-同变量名

在 C++ 中,命名空间(namespace)是一种封装机制,用于组织代码并防止名称冲突。当你在多个文件中定义同名的命名空间时,C++ 编译器会将这些命名空间视为同一个命名空间的扩展。这意味着不同文件中定义的同名命名空间的成员实际上是共享的,它们属于同一个逻辑上的命名空间。

这种特性非常有用,因为它允许你将大型项目分解为多个模块或文件,每个模块都有自己的命名空间,同时又能够保持命名空间的一致性和统一性。

File1.cpp:

namespace MyProject {
    void function1() {
        std::cout << "Function 1" << std::endl;
    }
}

File2.cpp:

namespace MyProject {
    void function2() {
        std::cout << "Function 2" << std::endl;
    }
}

在这两个文件中,我们都定义了名为 MyProject 的命名空间,并在其中分别定义了 function1function2。当我们编译和链接这两个文件时,MyProject 命名空间将被视为同一个命名空间,function1function2 都将是 MyProject 命名空间的成员。

你可以在 main 函数或其他任何地方这样调用它们

int main() {
    MyProject::function1(); // 调用 File1.cpp 中定义的 function1
    MyProject::function2(); // 调用 File2.cpp 中定义的 function2
    return 0;
}

等同于一个域:

多⽂件中可以定义同名namespace,他们会默认合并到⼀起,就像同⼀个namespace⼀样

namespace MyProject {
    void function1() {
        std::cout << "Function 1" << std::endl;
    }
    void function2() {
        std::cout << "Function 2" << std::endl;
    }
}

当然,如果你两个域封装的函数名字也一样,但是作用不一样,那么我们只需要再封装一下就可以。

namespace实际项目举例

实际使用

如图

当为同一个命名空间下面,我们还可以嵌套定义。

防止同一个项目组命名冲突

这样就增加了团队合作的协作性,而且这里有一个关键,是C语言没有的,就是不同域之间的命名冲突是不会导致报错的,因为域的不同,但是如果域相同命名一样,还是会导致冲突,解决方式就只需要再封装一下就可以,所以这里我们就可以发现C++比C语言优势多了很多了

 namespace命名空间的展开

命名空间的展开顾名思义就是不需要继续进入到域里面了,直接就可以访问

命名空间展开的弊端和使用规则:

展开命名空间(风险很大,平时写的小算法,写的小项目,没有那麽多的冲突的时候,是可以直接展开,命名空间)

展开指定的命名空间:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
namespace Js
{
	int c = 10;
	int ADD(int a, int b)
	{
		return a + b;
	}
	namespace js1
	{
		int d = 30; int f = 20;
		int del(int d, int f)
		{
			return d - f;
		}
	}
	namespace js2
	{
		int d = 30; int f = 20;
		int ADD(int d, int f)
		{
			return d + f;
		}
	}
}
int a = 110;
//int main()
//{
//	printf("全局变量的a=110,局部变量的a=11\n\n\n");
//	int a = 11;
//	printf("不加域作用限定符:%d\n\n\n", a);
//	printf("加上域作用限定符:%d\n\n\n", ::a);
//
//	printf("namespace单层调用测试:%d\n\n\n", Js::c);
//
//	int ret = Js::js1::del(30, 10);
//	printf("namespace多层调用测试:%d\n\n", ret);
//
//	//展开命名空间
//
//	return 0;
//}

using namespace Js;
int main()
{
	int c = 0;
	printf("展开命名空间,访问局部空间有的变量:%d\n\n\n", c);
	printf("展开命名空间,访问局部空间有的变量:%d", ::c);

	return 0;
}
  • 这里可以发现,::域作用限定符存在依旧是会首先访问全局变量,不存在会首先访问局部变量
  • 这里已经展开Js这个域,所以c就暴露在全局变量了

展开嵌套的命名空间:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
namespace Js
{
	int c = 10;
	int ADD(int a, int b)
	{
		return a + b;
	}
	namespace js1
	{
		int d = 30; int f = 20;
		int del(int d, int f)
		{
			return d - f;
		}
	}
	namespace js2
	{
		int d = 30; int f = 20;
		int ADD(int d, int f)
		{
			return d + f;
		}
	}
}
int a = 110;
//int main()
//{
//	printf("全局变量的a=110,局部变量的a=11\n\n\n");
//	int a = 11;
//	printf("不加域作用限定符:%d\n\n\n", a);
//	printf("加上域作用限定符:%d\n\n\n", ::a);
//
//	printf("namespace单层调用测试:%d\n\n\n", Js::c);
//
//	int ret = Js::js1::del(30, 10);
//	printf("namespace多层调用测试:%d\n\n", ret);
//
//	//展开命名空间
//
//	return 0;
//}

using namespace Js;
using namespace Js::js2;
int main()
{
	int c = 0;
	printf("展开外层命名空间,访问局部空间有的变量:%d\n\n\n", c);
	printf("展开外层命名空间,访问局部空间有的变量:%d\n\n\n", ::c);

	int d = 00;
	printf("展开嵌套内层命名空间,访问局部空间有的变量:%d\n\n\n", d);
	printf("展开嵌套内层命名空间,访问局部空间有的变量:%d\n\n\n", ::d);

	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2131233.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

fpga系列 HDL:简化的FIFO实现

CODE 下面是一个简化的FIFO实现示例&#xff0c;基于Verilog HDL&#xff1a; module fifo (input wire clk, // 时钟信号input wire reset, // 异步复位信号input wire wr_en, // 写使能信号input wire rd_en, // 读使能…

CSS中的位置定位总结

文章目录 静态定位相对定位绝对定位固定定位 静态定位 静态定位(position:static)/默认的文档流布局 块级元素按照书写顺序从上往下依次排列行内/行内块元素按照书写顺序从左到右依次排列&#xff0c;一行放不下才换行文档流中的元素都是紧密排布的&#xff0c;没有大的空隙&…

【机器学习】9 ——最大熵模型的直观理解

系列文章目录 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 系列文章目录前奏例子硬币垃圾邮件代码 前奏 【机器学习】6 ——最大熵模型 例子 硬币 假设我们有一枚硬币&#xff0c;可能是公平的&#xff0c;…

哪些软件可以监控电脑屏幕?四款优秀的屏幕电脑监控软件

你是否曾好奇&#xff0c;员工们在电脑前的忙碌究竟是在提高公司业绩&#xff0c;还是在成为“网上冲浪”高手&#xff1f; 或者&#xff0c;作为家长&#xff0c;你是否想知道孩子们的学习状态是如火如荼&#xff0c;还是在和游戏“斗智斗勇”&#xff1f;不管是办公还是家庭…

图纸加密软件哪个最好用?2024年好用的6款图纸加密软件分享!好用不踩雷!

某知名设计公司的年度发布会上&#xff0c;管理层突然被一个坏消息打断——公司的一份核心图纸被泄露到互联网上&#xff0c;导致重要的合作项目搁浅&#xff0c;直接损失数百万。 这样的事件不是个例&#xff0c;为此&#xff0c;很多企业意识打破图纸加密对保护企业知识产权和…

机械设计基础知识---材料硬度

一、定义 硬度&#xff0c;物理学专业术语&#xff0c;材料局部抵抗硬物压入其表面的能力称为硬度。固体对外界物体入侵的局部抵抗能力&#xff0c;是比较各种材料软硬的指标。由于规定了不同的测试方法&#xff0c;所以有不同的硬度标准。各种硬度标准的力学含义不同&#xf…

业务资源管理模式语言13

解决方案&#xff1a; 创建一个与“Resource”类相关的“Resource Delivery”类来控制资源交付的确认过程。因为交货是与交易相关的&#xff0c;“Resource”类与“Resource Delivery”类是“1 to 1”关系。如果你采用了子模式“Resource Measurement”或者采用了“ItemizeThe…

动手学深度学习(pytorch土堆)-04torchvision中数据集的使用

CIFAR10 CIFAR-10 数据集由 10 个类的 60000 张 32x32 彩色图像组成&#xff0c;每个类有 6000 张图像。有 50000 张训练图像和 10000 张测试图像。 数据集分为 5 个训练批次和 1 个测试批次&#xff0c;每个批次有 10000 张图像。测试批次包含每个类中随机选择的 1000 张图像…

Unity 给模型贴上照片

Unity将真实世界的照片贴图到模型上 原因 模拟仿真&#xff0c;直接使用照片肯定是效果最好的&#xff0c;省下做材质了 直接拖动即可 导入图片到Unity中将图片修改为Sprite模式直接将图片拖动到Scene面板的物体上即可 注意&#xff1a;是将图片拖动到Scene面板的物体上&a…

【Ubuntu】安装常用软件包

安装java 直接输入java&#xff0c;如果没有安装的话会提醒你输入命令安装&#xff0c;类似 Command java not found, but can be installed with: sudo apt install jdkxxxxxxxxxxxxxx然后选一个版本安装就好&#xff0c;我这里选的jdk17,安装完确认一下 ubuntuVM-4-13-ubu…

【深度学习】注意力机制介绍,了解什么是注意力计算规则以及常见的计算规则,知道注意力机制的工作流程

1注意力机制介绍 1.1 注意力概念 我们观察事物时&#xff0c;之所以能够快速判断一种事物(当然允许判断是错误的), 是因为我们大脑能够很快把注意力放在事物最具有辨识度的部分从而作出判断&#xff0c;而并非是从头到尾的观察一遍事物后&#xff0c;才能有判断结果. 正是基于…

动物检测系统源码分享

动物检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision …

el-tree父子不互相关联时,手动实现全选、反选、子级全选、清空功能

el-tree父子不互相关联时&#xff0c;手动实现全选、反选、子级全选、清空功能 1、功能实现图示 2、实现思路 当属性check-strictly为true时&#xff0c;父子节点不互相关联&#xff0c;如果需要全部选中或选择某一节点下的全部节点就必须手动选择每个节点&#xff0c;十分麻…

速卖通在哪些国家受欢迎?速卖通怎么选品?选品方式有哪些?

速卖通&#xff08;AliExpress&#xff09;是阿里巴巴集团旗下的一家跨境电商平台&#xff0c;也是全球第三大英文在线购物网站&#xff0c;为全球消费者提供了一个方便、多样化的购物平台&#xff0c;在中国跨境出口B2C平台中占据领先地位。相关数据统计&#xff0c;今年上半年…

砥砺前行 智护健康:衢州骨伤科医院建院十五周年庆典圆满启动

2024年9月12日&#xff0c;衢州骨伤科医院建院十五周年庆典圆满启动。作为邦尔骨科医院集团的第二家医院&#xff0c;衢州骨伤科医院创办于2009年&#xff0c;建院十五年来坚持集团宗旨与愿景&#xff0c;致力于将骨科领先技术和优质服务带给老百姓&#xff0c;现已成为区域领先…

input输入框之间有间隙的解决方案

1&#xff0c;浮动 浮动是处理元素排列方式的方法之一&#xff0c;使用浮动&#xff08;float&#xff09;可以帮助更好的排列元素位置 <p>源代码</p> <input type"text" name"name1" /> <input type"text" name"na…

JAVA宠物界的Uber同城遛狗兼职系统小程序源码

宠物界的Uber同城遛狗兼职系统&#xff0c;让爱宠自由奔跑&#xff01; &#x1f43e; 开篇&#xff1a;解锁宠物新生活方式 在这个快节奏的城市里&#xff0c;我们的爱宠是否也常常因为主人的忙碌而错失户外的欢乐时光&#xff1f;别担心&#xff0c;宠物界的“Uber”——同…

ArgoWorkflow教程(四)---Workflow 日志归档

上一篇我们分析了argo-workflow 中的 artifact&#xff0c;包括 artifact-repository 配置以及 Workflow 中如何使用 artifact。本篇主要分析流水线 GC 以及归档,防止无限占用集群中 etcd 的空间。 **【ArgoWorkflow 系列】**持续更新中&#xff0c;搜索公众号【探索云原生】订…

nlohmann::json中有中文时调用dump转string抛出异常的问题

问题描述 Winodows下C开发想使用一个json库&#xff0c;使用的nlohmann::json&#xff0c;但是遇到json中使用中文时&#xff0c;转成string&#xff0c;会抛出异常。 nlohmann::json contentJson;contentJson["chinese"] "哈哈哈";std::string test con…

从卫星和飞机等不同传感器方面由QGIS 遥感分析

在地理信息科学 (GIS) 中,遥感是指从远处获取有关地球表面特征信息的行为。遥感数据是从许多不同的平台获取而来,包括卫星、飞机和具有许多不同传感器的固定仪器,包括光谱图像(相机)和激光雷达。最常见的遥感数据形式是卫星和航空图像。 为了充分实现这些照片的价值,需要…