C++面向对象程序设计 - 命名空间

        命名空间是ANSI C++引入的可以由用户命名的作用域,用来处理程序中常见的同名冲突。

        在C语言中定义了三个层次的作用域,即文件(编译单元)、函数和复合语句。C++又引入了类作用域,类是出现在文件内的。在不同的作用域中可以定义相同名字的变量,互不干扰,系统能够区别它们。

           例如两个不同的头文件中,命名了的类名相同,同时引入进来会报错【[Error] redefinition of 'class Student'】- 这个错误表明类 Student 被重复定义了。示例如下:

1、s1.h头文件代码:

#include <string>
using namespace std;
// 定义Student学生类
class Student{private:int num;string name;int age;public:Student(int num, string name, int age): num(num), name(name), age(age){}
};

2、s2.h头文件代码:

#include <string>
using namespace std;
// 定义Student学员类
class Student{private:int num;string name;int age;float wage;		//工资public:Student(int num, string name, int age, float wage): num(num), name(name), age(age), wage(wage){}
};

3、主文件代码:

#include "s1.h"
#include "s2.h"
using namespace std;int main(){return 0;
}

        以上代码在编译的时候就会出现名字冲突,为了解决这个问题,ANSI C++增加了命名空间(namespace)。所谓命名空间,实际上一个由程序设计者命名的内存区域,可以根据需要指定一些有名字的空间域,把一些全局实体分别放到各个命名空间中,从而与其他全局实体分隔开来。

        如下代码:

namespace ns1{int a;double b;
}

一、命名空间

        在声明一个命名空间时,花括号内不仅可以包括变量,而且还可以包括以下类型:

  • 变量(可以有初始化)
  • 常量
  • 函数(可以是定义或声明)
  • 结构体
  • 模板
  • 命名空间(在一个命名空间中又定义一个命名空间,即嵌套的命名空间)

示例如下:

#include <iostream>
using namespace std;
namespace ns1{const double PI = 3.1415926;int age = 30;double area(){return 2 * 20 * PI;}namespace ns2{float wage = 1500.0f;}
}int main(){cout <<ns1::PI <<endl;cout <<ns1::age <<endl;cout <<ns1::area() <<endl;cout <<ns1::ns2::wage <<endl;return 0;
}

        运行结果如下图:

二、使用命名空间解决同名冲突

        有了以上的基础后,就可以利用命名空间来解决前端Student类的名字冲突问题了。代码如下:

1、s1.h文件

#include <iostream>
#include <string>
using namespace std;namespace ns1{// 定义Student学生类class Student{private:int num;string name;int age;public:Student(int num, string name, int age): num(num), name(name), age(age){}void print(){cout <<"num:" <<num <<", name:" <<name <<", age:" <<age <<endl;}};
}

2、s2.h文件

#include <iostream>
#include <string>
using namespace std;namespace ns2{// 定义Student学员类class Student{private:int num;string name;int age;float wage;		//工资public:Student(int num, string name, int age, float wage): num(num), name(name), age(age), wage(wage){}void print(){cout <<"num:" <<num <<", name:" <<name <<", age:" <<age <<", wage:" <<wage <<endl;}};
}

3、main主文件

#include "s1.h"
#include "s2.h"
using namespace std;int main(){ns1::Student s1(100, "Tom", 20);ns2::Student s2(1001, "John", 30, 1500.0f);// 打印结果信息s1.print();s2.print();return 0;
}

        运行结果如下图:

三、使用命名空间成员的方法

        在引用命名空间成员时,要用命名空间名和作用域分辨符对命名空间成员进行限定,以区别不同的命名空间中的同名标识符,如:

命名空间名::命名空间成员名

        这种方法是有效的,并保证所引用的实体有惟一的名字。但是如果命名空间名字比较长,尤其在有命名空间嵌套的情况下,为引用一个实体,需要写很长的名字。为此,C++提供了一些机制,能简化使用命名空间成员的手续。

(1)使用命名空间别名

        可以为命名空间起一个别名(namespace alias),用来代替较长的命名空间名。例如下:

#include <iostream>
using namespace std;
namespace ns1{const double PI = 3.1415926;int age = 30;double area(){return 2 * 20 * PI;}namespace ns2{float wage = 1500.0f;}
}int main(){cout <<ns1::PI <<endl;cout <<ns1::age <<endl;cout <<ns1::area() <<endl;// 用别名n2代替ns1::ns2namespace n2 = ns1::ns2;cout <<n2::wage <<endl;return 0;
}

        运行结果还是一样的,如下图:

(2)使用using命名空间成员

        using后面的命名空间成员名必须是由命名空间限定的名字。例如:

#include <iostream>
using namespace std;
namespace ns1{const double PI = 3.1415926;int age = 30;double area(){return 2 * 20 * PI;}
}int main(){// 声明其后出现的变量或函数都是属于命名空间ns1中的using ns1::PI;using ns1::age;using ns1::area;// 此处引用相当于ns1::PI, ns1::age, ns1::area()cout <<PI <<endl;cout <<age <<endl;cout <<area() <<endl;return 0;
}

        当然,前面Student示例如,如使用using则会产生二义性,编译出错,代码如下:

#include <iostream>
#include "s1.h"
#include "s2.h"
using namespace std;int main(){using ns1::Student;Student s1(100, "Tom", 20);// 错误,会出现二义性using ns2::Student;Student s2(1001, "John", 30, 1500.0f);// 打印结果信息s1.print();s2.print();return 0;
}

        所以要注意,在同一作用域中用using声明的不同命名空间的成员中不能有同名的成员。

(3)使用using namespace 命名空间名

        在上面介绍的using命名空间成员,一次只能声明一个命名空间成员,如果在一个命名空间中定义了多个实体,就需要使用多次using命名空间成员名。C++为此提供了using namespace 语句为实现只要用一个语句就能一次声明命名空间中全部成员。示例如下:

#include <iostream>
#include "s1.h"
using namespace std;
using namespace ns1;
int main(){Student s1(100, "Tom", 20);// 打印结果信息s1.print();return 0;
}

        运行结果如下图:

        当然,此用法同“(2)使用using命名空间成员”一样,使用多个命名空间时,当多个命名空间中出现同名时,容易出错。如下代码:

#include <iostream>
#include "s1.h"
#include "s2.h"
using namespace std;
using namespace ns1;
using namespace ns2;int main(){Student s1(100, "Tom", 20);//错误,会出现二义性Student s2(1001, "John", 30, 1500.0f);// 打印结果信息s1.print();s2.print();return 0;
}

        此时编译时会报错【[Error] reference to 'Student' is ambiguous】- 因同一作用域中引入两个命名空间ns1和ns2,其中有同名的类,此时无法判定是哪个命名空间的Student,所以会出现二义性,编译出错。

四、无名的命名空间

        C++还允许使用没有名字的命名空间,如在文件中声明了以下无名命名空间,代码如下:

#include <iostream>
using namespace std;
// 定义无名命名空间
namespace{void test(){cout <<"Test...";}
}int main(){test();return 0;
}

        运行结果如下图:

        由于命名空间没有名字,在其他文件中显然无法引用,它只在本文件的作用域内有效。其作用是更该函数的作用域限定于本文件。C++保留了用static声明函数的用法,同时提供了用无命名空间来实现这一功能,使用无命名空间成员的方法将会取代以前习惯用的对全局变量的静态声明。

五、标准命名空间std

        为了解决C++标准库中的标识符与程序中的全局标识符之间以及不同库中的标识符之间的同名冲突,应该将不同库的标识符在不同的命名空间中定义(或声明)。标准C++库的所有标识符都在一个名为std的命名空间中定义的,或者说标准头文件中函数、类、对象和类模板是在命名空间std中定义的。std是standard(标准)的缩写,表示这是存放标准库的有关内容的命名空间。

        在程序中用到C++标准库时,需要使用std作为限定,代码如下:

std::cout <<"OK" <<endl;

        C++介绍到这里,想必大家已了解命名空间的使用。这就是大家有时看到文件中未引用命名空间std时,标准库中的成员侧需要使用std引用,代码如下:

std::cout <<"Hello World" <<std::endl;

        当引用了命名空间std时,又可以省略掉std,代码如下:

using namespace std;cout <<"Hello World" <<endl;

        所以在标准的C++编程中,应对命名空间std的成员进行声明或限定。

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

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

相关文章

Electron无感打印 静默打印(vue3 + ts + vite)

&#xff08;electron vue3 项目搭建部分 自行查找其他资源 本文只讲解Electronvue3 如何实现静默打印&#xff09; 第一步获取打印机资源 渲染端代码&#xff08;vue里面&#xff09; // 因使用了vite所以在浏览器中打开 require会报错 只能在electron中 const { ipcRender…

统计信号处理基础 习题解答10-11

题目 我们希望根据一个人的身高来估计他的体重。为了判断其可行性,对N100个人取数据&#xff0c;产生有序的数据对(h,w),其中h代表身高,w代表体重。得到的数据如图10.9(a)所示的。解释你如何利用MMSE估计量根据一个人的身高来猜测他的体重。对于这些数据的建模有些什么样的假设…

RT-thread内核对象的基础应用

RT-thread的内核对象基础应用 启动流程&#xff1a; 以RT-Thread Studio为例&#xff0c;用户程序入口为位于 main.c 文件中 的main 函数。系统启动后先运行startup_stm32f103xe.s文件中的汇编代码&#xff0c;运行“bl entry”指令后跳转到components.c 文件中调用entry函数&a…

WebMvcConfigurer配置不当导致鉴权失败

最近同事说他们有个新需求&#xff0c;需要对接口进行加解密&#xff0c;所以他给项目配置了一个拦截器&#xff0c;但这个拦截器直接导致了每个接口鉴权失败&#xff0c;每次调用接口都是提示没有session信息。 公司内的所有java项目是公用同一套基础依赖&#xff0c;所以我也…

蚂蚁分类信息系统二开仿么么街货源客模板微商货源网源码(带手机版)

源码介绍 网站采用蚂蚁分类信息系统二次开发&#xff0c;模板仿么么街货源客模板&#xff0c;微商货源网定制版。 模板设计风格简洁&#xff0c;分类信息采用列表形式发布&#xff0c;这种设计方式非常符合度娘 SEO 规则。收录效果是杠杠的。 这个网站风格目前是用来做货源推…

【网络安全】【深度学习】【入侵检测】SDN模拟网络入侵攻击并检测,实时检测,深度学习【一】

文章目录 1. 前言2. Mininet 和 Ryu 的区别2.1 Mininet2.2 Ryu2.3 总结 3. 模拟攻击3.1 环境准备3.2 创建 Mininet 网络拓扑3.2 启动 Ryu 控制器3.3 模拟网络攻击3.4 捕获流量 4. 实时异常检测4.1 在 Ryu 控制器中4.2 在 h2 机器上的实验结果4.3 深度学习模型部署上h2机器 帮助…

ArcGIS Pro SDK (三)Addin控件 4 工程项目结构类

25 ArcGIS Pro 自定义项目 目录 25 ArcGIS Pro 自定义项目25.1 添加控件25.2 Code26 ArcGIS Pro 自定义工程项目26.1 添加控件26.2 Code25.1 添加控件 25.2 Code ProCustomItemTest.cs using ArcGIS.Desktop.Core; using ArcGIS.Desktop

分布式文件存储 - - - MinIO从入门到飞翔

MinIO从入门到飞翔 文章目录 MinIO从入门到飞翔0、前言1、分布式文件系统2、MinIO 介绍3、 MinIO安装&#xff08;docker&#xff09;4、基本概念5、通过代码上传文件到MinIO6、封装MinIO为starter7、在其他项目中集成封装好的模块 0、前言 对象存储是一种数据存储架构&#x…

互联网应用主流框架整合之SpringMVC基础组件开发

多种传参方式 在前一篇文章互联网应用主流框架整合之SpringMVC初始化及各组件工作原理中讨论了最简单的参数传递&#xff0c;而实际情况要复杂的多&#xff0c;比如REST风格&#xff0c;它往往会将参数写入请求路径中&#xff0c;而不是以HTTP请求参数传递&#xff1b;比如查询…

audio标签隐藏播放器尾部的三个点

问题&#xff1a; 在谷歌浏览器上&#xff0c;展示audio音频控件时&#xff0c;后面有三个点&#xff0c;点击后会显示下载和播放速度&#xff0c;想隐藏这两个控件。 注意&#xff1a; 不是所有版本都有这三个点&#xff0c;甚至有的版本里面三个点里面的控件只有下载。 解…

【Windows10】查看WIFI密码

操作步骤 电脑上查看已连接Wi-Fi的密码的步骤如下: 连接需要查看密码的Wi-Fi。右键点击任务栏上的 [网络] 图标&#xff0c;选择 [开启"网络和Internet"设置]。在 高级网络设置 项目中&#xff0c;点选 [网络和共享中心]。开启网络和共享中心的窗口后&#xff0c;点…

vue打包exe实战记录

vue项目不支持直接打包exe,可以依靠electron进行打包,处理方式是将vue打包的dist文件夹放到electron项目中,通过配置后打包electron.先看下本地环境 下面是实操记录: 1.vue项目打包 vue.config.js中设置项目路径为 module.exports {//publicPath: /chat_pc/, // 前端项目…

苍穹外卖笔记-13-导入地址簿功能代码、用户下单、订单支付

文章目录 1. 导入地址簿功能代码1.1 需求分析和设计1.1.1 产品原型1.1.2 接口设计1.1.3 表设计 1.2 代码导入1.2.1 Mapper层1.2.2 Service层1.2.3 Controller层 1.3 功能测试 2. 用户下单2.1 需求分析和设计2.1.1 产品原型2.1.2 接口设计2.1.3 表设计 2.2 代码开发2.2.1 DTO设计…

Spotify 音乐平台宣布成立内部创意机构,测试生成式人工智能配音广告

Spotify是一家流媒体音乐平台&#xff0c;提供广泛的音乐、播客和视频内容。用户可以通过订阅服务Spotify Premium来享受更多高级功能&#xff0c;如无广告播放、离线听歌等。 Spotify 周四宣布&#xff0c;它将通过其首家名为 Creative Lab 的内部创意机构进一步进军广告领域…

集合查询-并(UNION)集运算、交(INTERSECT)集运算、差(EXCEPT)集运算

一、概述 集合查询是对两个SELECT语句的查询结果进行再进行处理的查询 二、条件 1、两个SELECT语句的查询结果必须是属性列数目相同 2、两个SELECT语句的查询结果必须是对应位置上的属性列必须是相同的数据类型 三、并(UNION)运算 1、语法格式&#xff1a; SELECT 语句1…

Vite - 项目打包从 0 到 1(完美解决打包后访问白屏问题)

目录 开始 修改资源相对地址 引入 vitejs/plugin-legacy 插件并配置 修改打包指令 修改 router 中的 history 前端配置跨域相关 打包后成功访问 开始 修改资源相对地址 在 vite.config.js 文件中配置如下&#xff1a; export default defineConfig({base: ./, //1.打包…

揭秘循环购模式:为何商家愿“送钱”,用户能边消费边赚钱?

大家好&#xff0c;我是你们的电商专家吴军。今天&#xff0c;我将带大家走进一个神秘而又吸引人的商业模式——循环购模式。你可能会疑惑&#xff0c;为什么消费者能在这里“消费1000送2000”&#xff0c;每天还能领取现金并提现&#xff1f;商家真的在“送钱”吗&#xff1f;…

(css)el-tabs滚动按钮浮动问题

(css)el-tabs滚动按钮浮动问题 修改前&#xff1a; 修改后&#xff1a; 思路&#xff1a;找到相应元素&#xff0c;降低层级 css写法&#xff1a; ::v-deep .el-tabs__nav {z-index: 1; }

MySql出现的问题

1.在控制面吧输入mysql显示不是内部命令 2.找到mysql安装的目录,复制目录路径 3.打开系统属性设置环境变量中的Path将路径添加到里面 4.添加好以后将控制面板重新打开输入命令 2.解决安装mysql错误 导致多个mysql服务删除教程 1.用管理员身份打开cmd命令板 2.在…

各地区城乡居民基本养老保险情况数据,Shp+excel格式

基本信息. 数据名称: 各地区城乡居民基本养老保险情况数据 数据格式: Shpexcel 数据几何类型: 面 数据坐标系: WGS84 数据时间&#xff1a;2008-2018年 数据来源&#xff1a;网络公开数据 数据可视化.