当前位置: 首页 > news >正文

C++(18):命名空间

多个库将名字放置在全局命名空间中将引发命名空间污染

命名空间可以用来防止名字冲突,它分割了全局命名空间,其中每个命名空间是一个作用域。通过在某个命名空间中定义库的名字,库的作者(以及用户)可以避免全局名字固有的限制。

命名空间定义

一个命名空间的定义包含两部分:关键字namespace + 命名空间名字。
在命名空间名字后面是一系列由花括号括起来的声明和定义。只要能出现在全局作用域中的声明就能置于命名空间内,主要包括:类、变量(及其初始化操作)、函数(及其定义)、模板和其他命名空间。

namespace cplusplus_primer{class Sales_data{/*...*/};
}  //无须分号

命名空间的名字也必须在定义它的作用域内保持唯一。
命名空间既可以定义在全局作用域内,也可以定义在其他命名空间中,但是不能定义在函数或类的内部。

命名空间作用域后面无须分号。

每个命名空间都是一个作用域

命名空间中的每个名字都必须表示该空间内的唯一实体:不同命名空间的作用域不同,所以在不同命名空间内可以有相同名字的成员。

定义在某个命名空间中的名字可以被该命名空间内的其他成员直接访问,也可以被这些成员内嵌作用域中的任何单位访问。位于该命名空间之外的代码则必须明确指出所用的名字属于哪个命名空间。

cplusplus_primer::Query q = cplusplus_primer::Query("hello")

命名空间可以不是连续的

//命名空间定义
namespace nsp{//相关声明
}

命名空间可以定义在几个不同的部分。
命名空间的一部分成员的作用是定义类,以及声明作为类接口的函数及对象,则这些成员应该置于头文件中,这些头文件将被包含在使用了这些成员的文件中。
命名空间成员的定义部分则置于另外的源文件中。

定义多个类型不相关的命名空间应该使用单独的文件分别表示每个类型(或关联类型构成的集合)。

定义命名空间成员

假定作用域中存在合适的声明语句,则命名空间中的代码可以使用同一命名空间定义的名字的简写形式。

#include "Sales_data.h"
namespace cplusplus primer{	//重新打开命名空间cplusplus_primer//命名空间中定义的成员可以直接使用名字,此时无须前缀std::istream&operator>>(std::istream& in,Sales_data& s){/* ...* /)}
}

也可以在命名空间定义的外部定义该命名空间的成员。命名空间对于名字的声明必须在作用域内,同时该名字的定义需要明确指出其所属的命名空间:

//命名空间之外定义的成员必须使用含有前缀的名字
cplusplus primer:: Sales_data
cplusplus_primer::operator+(const Sales_data& lhs, const Sales data& rhs){sales_data ret (lhs);// ...
}

模板特例化

模板特例化必须定义在原始模板所属的命名空间中。只要在命名空间中声明了特例化,就可以在命名空间外部定义它了。

全局命名空间

全局作用域中定义的名字(即在所有类、函数及命名空间之外定义的名字)也就是定义在全局命名空间中。
全局命名空间以隐式的方式声明,并且在所有程序中都存在。
全局作用域中定义的名字被隐式地添加到全局命名空间中。

作用域运算符同样可以用于全局作用域成员:

::member_name // 表示全局命名空间中地一个成员

嵌套的命名空间

嵌套的命名空间是指定义在其他命名空间中的命名空间。

内层命名空间声明的名字将隐藏外层命名空间声明的同名成员。在嵌套的命名空间中定义的名字只在内层命名空间中有效,外层命名空间中的代码要想访问它必须在名字前添加限定符。

cplusplus_primer::QueryLib::Query

内联命名空间

和普通的嵌套命名空间不同,内联命名空间中的名字可以被外层命名空间直接使用。

无须在内联命名空间的名字前添加表示该命名空间的前缀,通过外层命名空间的名字就可以直接访问它。

定义内联命名空间的方式是在关键字namespace前添加关键字inline

inline namespace FifthEd{//该命名空间表示本书第5版的代码
}
namespace FifthEd{	//隐式内联class Query base {/* ...*/};//其他与 Query有关的声明
}

关键字inline必须出现在命名空间第一次定义的地方,后续再打开命名空间的时候可以写inline,也可以不写。

未命名的命名空间

未命名的命名空间是指关键字namespace后紧跟花括号括起来的一系列声明语句。
未命名的命名空间中定义的变量拥有静态生命周期:它们在第一次使用前创建,并且直到程序结束才销毁。

一个未命名的命名空间可以在某个给定的文件内不连续,但是不能跨越多个文件。
如果两个文件都含有未命名的命名空间,则这两个空间相互无关。在这两个未命名的命名空间中可以定义相同的名字,并且这些定义表示的是不同实体。
如果一个头文件定义了未命名的命名空间,则该命名空间中定义的名字将在每个包含了该头文件的文件中对应不同实体。

使用命名空间

命名空间的别名

命名空间的别名可以为命名空间的名字设定一个短得多的同义词。

namespace cplusplus_primer {/* ...*/};
//可以为其设定一个短得多的同义词;
namespace primer = cplusplus_primer;//命名空间的别名也可以指向一个嵌套的命名空间:
namespace Qlib = cplusplus_primer::QueryLib;
Qlib::Query q;

using

一条using声明语句一次只引入命名空间的一个成员。
using的有效范围从using声明的地方开始,一直到using声明所在的作用域结束为止。这有助于减少代码中的冗余,提高可读性。

namespace MyNamespace {int value = 42;void Print() {std::cout << "Hello from MyNamespace" << std::endl;}
}int main() {using MyNamespace::value; // 引入命名空间中的变量using MyNamespace::Print; // 引入命名空间中的函数std::cout << value << std::endl; // 可以直接使用value,不需要MyNamespace::Print(); // 可以直接使用Print,不需要MyNamespace::return 0;
}

using指示以关键字using开始,后面是关键字namespace 以及命名空间的名字。

using 指示不能用在类的作用域内。但是 using 声明是可以的。

using 指示令引入的命名空间成员的作用域提升到包含命名空间本身和 using 指示的最近作用域。可以使用该命名空间内的所有名称,而无需使用限定符。

namespace MyNamespace {int value = 42;void Print() {std::cout << "Hello from MyNamespace" << std::endl;}
}int main() {using namespace MyNamespace; // 引入整个命名空间std::cout << value << std::endl; // 可以直接使用value,不需要MyNamespace::Print(); // 可以直接使用Print,不需要MyNamespace::return 0;
}

头文件如果在其顶层作用域中含有 using 指示或 using 声明,则会将名字注入到所有包含了该头文件的文件中。
因此头文件最多只能在它的函数或命名空间内使用 using 指示或 using 声明。

避免使用 using 指示:一般不要使用 using 指示,很危险。
using 指示的用处:在命名空间本身的实现文件中可以使用 using 指示。

类、命名空间与作用域

对命名空间内部名字的查找遵循常规的查找规则:即由内向外依次查找每个外层作用域。
外层作用域也可能是一个或多个嵌套的命名空间,直到最外层的全局命名空间查找过程终止。只有位于开放的块中且在使用点之前声明的名字才被考虑。

实参相关的查找与类类型形参

实参相关的查找与类类型形参

std::string s;
std::cin >> s;

重载操作符 >> 定义在标准库 string 中,string 定义在命名空间 std 中。但是不用 std:: 限定符就可以调用 >> 操作符。
这是因为:给一个函数传递一个类类型的对象时,除了在常规的作用域查找外还会查找实参类所属的命名空间。

>>操作符的形参(iostream 和 string)是类类型的,所以编译器还会查找 iostreamstring 所属的命名空间。

查找与 std::move 和 std::forward

moveforward 都是模板函数,在标准库的定义中它们都接受一个右值引用的函数形参。在函数模板中,右值引用形参可以匹配任何类型。
如果用户自己也定义了一个 move 函数并且它只接受一个参数,那么必然会与标准库的 move 函数冲突。forward 函数也是如此。所以 moveforward 的名字冲突非常频繁,使用时应该写 std::movestd::forward

重载与命名空间

与实参相关的查找与重载

对于接受类类型实参的函数来说,其名字查找将在实参类所属的命名空间中进行。

重载与 using 声明

using 声明语句声明的是一个名字,而非一个特定的函数。当我们为函数书写using声明时,该函数的所有版本都被引入到当前作用域中。

重载与 using 指示

using指示将命名空间的成员提升到外层作用域中,如果命名空间的某个函数与该命名空间所属作用域的函数同名,则命名空间的函数将被添加到重载集合中。

using声明不同的是,对于using 指示来说,引入一个与已有函数形参列表完全相同的函数并不会产生错误。只需要调用时指明是哪个版本即可。

跨越多个 using 指示的重载

如果存在多个命名空间,则来自每个命名空间的名字都将成为候选函数集的一部分。

相关文章:

C++(18):命名空间

多个库将名字放置在全局命名空间中将引发命名空间污染。 命名空间可以用来防止名字冲突&#xff0c;它分割了全局命名空间&#xff0c;其中每个命名空间是一个作用域。通过在某个命名空间中定义库的名字&#xff0c;库的作者&#xff08;以及用户&#xff09;可以避免全局名字…...

K8S最新版本集群部署(v1.28) + 容器引擎Docker部署(上)

温故知新 &#x1f4da;第一章 前言&#x1f4d7;背景&#x1f4d7;目的&#x1f4d7;总体方向 &#x1f4da;第二章 基本环境信息&#x1f4d7;机器信息&#x1f4d7;软件信息&#x1f4d7;部署用户kubernetes &#x1f4da;第三章 Kubernetes各组件部署&#x1f4d7;安装kube…...

生产环境部署与协同开发 Git

目录 一、前言——Git概述 1.1 Git是什么 1.2 为什么要使用Git 什么是版本控制系统 1.3 Git和SVN对比 SVN集中式 Git分布式 1.4 Git工作流程 四个工作区域 工作流程 1.5 Git下载安装 1.6 环境配置 设置用户信息 查看配置信息 二、git基础 2.1 本地初始化仓库 ​编辑…...

Qt/C++编写视频监控系统80-远程回放视频流

一、前言 远程回放NVR或者服务器上的视频文件&#xff0c;一般有三种方式&#xff0c;第一种是调用厂家的SDK&#xff0c;这个功能最全&#xff0c;但是缺点明显就是每个厂家的设备都有自己的SDK&#xff0c;只兼容自家的设备&#xff0c;如果你的软件需要接入多个厂家的&…...

用于设计和分析具有恒定近心点半径的低推力螺旋轨迹研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

MongoDB - 构造复杂查询条件执行查询

文章目录 1. 构造 keyword 的查询条件2. 构造 threatSubType 的查询条件3. 相应的实体类 /*** 查询白名单详情** param offset 第几页开始* param limit 每页显示的最大值* param keyword 模糊搜索值* param order 排序方式&#xff08;升序/降序…...

如何从ChatGPT中获得最佳聊天对话效果

从了解ChatGPT工作原理开始&#xff0c;然后从互动中学习&#xff0c;这是一位AI研究员的建议。 人们利用ChatGPT来撰写文章、论文、生成文案和计算机代码&#xff0c;或者仅仅作为学习或研究工具。然而&#xff0c;大多数人不了解它的工作原理或它能做什么&#xff0c;所以他…...

深入浅出:手把手教你实现单链表

一、什么是链表 链表是一种链状数据结构。简单来说&#xff0c;要存储的数据在内存中分别独立存放&#xff0c;它们之间通过某种方式相互关联。 如果我们使用C语言来实现链表&#xff0c;需要声明一个结构体作为链表的结点&#xff0c;结点之间使用指针关联。 二、单向链表的结…...

vite 打包项目后访问显示空白页的问题,开发环境正常,生产环境无报错。

有没有可能&#xff0c; 你跟我遇到同样的问题 白屏的写法 const routes [{path: /,component: import(../views/index.vue),} ]正确的写法 const routes [{path: /,component: () > import(../views/index.vue),} ]有时候方向很重要&#xff0c;当在错误的方向上无脑冲…...

打造成功的砍价营销大解析,销量飙升

砍价活动是吸引顾客的一种有效方式&#xff0c;可以帮助提高销量和提升品牌知名度。在乔拓云平台上&#xff0c;我们提供了一套简单易用的工具&#xff0c;让您能够轻松地制作一个成功的砍价活动。下面&#xff0c;我将详细介绍具体步骤&#xff0c;让您能够轻松上手。 第一步&…...

【Flink进阶】- Flink kubernetes operator 常用的命令

目录 1、应用程序管理 (1)提交 Flink 应用程序 (2)查看 Flink 应用程序列表...

ASP.NET Core 的日志系统

ASP.NET Core 提供了丰富日志系统。 可以通过多种途径输出日志&#xff0c;以满足不同的场景&#xff0c;内置的几个日志系统包括&#xff1a; Console&#xff0c;输出到控制台&#xff0c;用于调试&#xff0c;在产品环境可能会影响性能。Debug&#xff0c;输出到 System.Di…...

android13(T) 以太网设置工具类

13 版本的以太网设置和以前版本有所变动&#xff0c;在 AS 中就能直接调用对应 API 将 build.gradle 版本修改 compileSdkVersion 31, 即可直接调用 EthernetManager 相关&#xff0c; 设置静态等方法可以通过反射调用设置。 以下是核心设置静态和动态参数工具类&#xff0c…...

电脑报错提示xinput1_3.dll缺失怎么办?xinput1_3.dll丢失的简单恢复方案

今天&#xff0c;我将为大家分享一个与我们日常工作息息相关的话题——xinput1_3.dll丢失的4种解决方法。在我们的日常工作和生活中&#xff0c;电脑出现问题是常有的事&#xff0c;而xinput1_3.dll丢失则是其中较为常见的一种问题。那么&#xff0c;什么是xinput1_3.dll?它为…...

unity 之参数类型之引用类型

文章目录 引用类型引用类型与值类型的差异 引用类型 在Unity中&#xff0c;引用类型是指那些在内存中存储对象引用的数据类型。以下是在Unity中常见的引用类型的介绍&#xff1a; 节点&#xff08;GameObject&#xff09;&#xff1a; 在Unity中&#xff0c;游戏对象&#xff…...

SpringBoot自定义工具类—基于定时器完成文件清理功能

直接复制粘贴既可&#xff01;&#xff01; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.io.File; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneOff…...

安卓设置混淆后,gson报错解决方法

一&#xff0c;设置开启混淆release {minifyEnabled truezipAlignEnabled trueshrinkResources trueproguardFiles getDefaultProguardFile(proguard-android-optimize.txt), proguard-rules.pro } 二&#xff0c;混淆的文件中&#xff0c;对gson相关类不进行混淆&#xff0c;否…...

WPF实战项目十四(API篇):登录注册接口

1、新建UserDto.cs public class UserDto : BaseDto{private string userName;/// <summary>/// 用户名/// </summary>public string UserName{get { return userName; }set { userName value;OnPropertyChanged(); }}private string account;/// <summary>…...

10个免费PPT下载资源网站分享

PPT超级市场https://pptsupermarket.com/ PPT超级市场是一个完全免费的PPT模板下载网站&#xff0c;不需要注册登录&#xff0c;点击下载就能直接使用。 叮当设计https://www.dingdangsheji.com/ 叮当设计是一个完全免费的PPT模板下载网站&#xff0c;每一套PPT的质量都很高。除…...

SpringCloud入门——微服务调用的方式 RestTemplate的使用 使用nacos的服务名初步(Ribbon负载均衡)

目录 引出微服务之间的调用几种调用方法spring提供的组件 RestTemplate的使用导入依赖生产者模块单个配置的情况多个配置的情况没加.yaml的报错【报错】两个同名配置【细节】 完整代码config配置主启动类controller层 消费者模块进行配置restTemplate配置类controller层 使用na…...

Python基础篇(16):python中__new__方法

一、__new__方法的定义 __new__() 方法是一种负责创建 类实例 的 静态方法 二、__new__方法的作用 在内存中为对象分配空间返回对象的引用 三、__new__方法的使用 创建对象时自动调用__new__方法&#xff0c;并且是在__init__初始化方法之前被调用Python解释器获得对象的引…...

linux并发服务器 —— 文件IO相关函数(三)

文件IO 以内存为主体&#xff0c;看待输入输出&#xff1b; 标准C库IO函数带有缓冲区&#xff0c;效率较高&#xff1b; 虚拟地址空间 虚拟地址空间是不存在的&#xff0c;一个应用程序运行期间对应一个虚拟地址空间&#xff1b; 虚拟地址空间的大小由CPU决定&#xff0c;位…...

matlab使用教程(27)—微分代数方程(DAE)求解

1.什么是微分代数方程&#xff1f; 微分代数方程是一类微分方程&#xff0c;其中一个或多个因变量导数未出现在方程中。方程中出现的未包含其导数的变量称为代数变量&#xff0c;代数变量的存在意味着您不能将这些方程记为显式形式 y ′ f t , y 。相反&#xff0c;您可以…...

vue3组合式api <script setup> props 父子组件的写法

父组件传入子组个的变量&#xff0c; 子组件是无法直接修改的&#xff0c; 只能通过 emit的方式&#xff0c; 让父组件修改&#xff0c; 之后子组件更新 <template><div class"parent">我是父组件<son :msg"msg" :obj"obj" chan…...

Compose - 自定义作用域限制函数

一、概念 在 Compose 中对于作用域的应用特别多。比如 weight 修饰符只能用在 RowScope 或者 ColumnScope 作用域中&#xff0c;item 组件只能用在 LazyListScope 作用域中。 标准库中的作用域函数如 apply()、let() 会以不同方式持有和返回上下文对象&#xff0c;调用它们时 L…...

【Flutter】Flutter 使用 photo_view 实现图片查看器

【Flutter】Flutter 使用 photo_view 实现图片查看器 文章目录 一、前言二、photo_view 简介三、安装与基本使用四、使用 PhotoViewGallery 展示多张图片五、完整示例六、总结 一、前言 大家好&#xff0c;我是小雨青年&#xff0c;今天我要给大家介绍一个在 Flutter 中非常实…...

电脑组装教程分享!

案例&#xff1a;如何自己组装电脑&#xff1f; 【看到身边的小伙伴组装一台自己的电脑&#xff0c;我也想试试。但是我对电脑并不是很熟悉&#xff0c;不太了解具体的电脑组装步骤&#xff0c;求一份详细的教程&#xff01;】 电脑已经成为我们日常生活中不可或缺的一部分&a…...

【云原生之Docker实战】使用Docker部署flatnotes笔记工具

【云原生之Docker实战】使用Docker部署flatnotes笔记工具 一、flatnotes介绍1.1 flatnotes简介1.2 flatnotes特点 二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、下载flatnotes…...

XSSchallenge1-20

test1 第一题直接在test插入XSS代码即可 test2 第二关对内容进行”“包裹 这里可以采用”>来绕过 test3 代码审计发现这里用了htmlspecialchars函数&#xff0c;这个函数对<>和’ “等进行了转义&#xff0c;这里可以用事件来绕过 test4 这里用了str_replace&a…...

centos 7的超详细安装教程

打开虚拟机&#xff0c;创建一个新电脑 我们选择经典&#xff0c;然后选择下一步 我们选择稍后安装&#xff0c;我们在后面进行改设备 因为centos系统是linux系统的一个版本&#xff0c;所有我们选择linux&#xff0c;版本选择centos 7 64位&#xff0c;然后就是点击下一步 这一…...