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.rhkb.cn/news/349544.html

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

相关文章

14.shell awk数组

awk数组 awk数组awk数组示例Nginx日志分析 awk数组 1.什么是awk数组 数组其实也算是变量,传统的变量只能存储一个值,但数组可以存储多个值 2.awk数组应用场景 通常用来统计、比如:统计网站访问TOP10、网站url访问TOP10等等 3.awk数组统计技巧 1.在awk中,使用数组时,不仅可以…

ceisum只聚合效果展示

忙于开发三维引擎的扩展功能&#xff0c;实在时间太少了&#xff0c;仓促截几张图&#xff0c;看一下聚合效果。 1.聚合又文字标签 四种效果&#xff1a;如下 2.聚合无文字标签

Docker(一)-认识Docker

1.docker理念 Docker是基于Go语言实现的云开源项目。 Docker的主要目标是“Build,Ship and Run Any App,Anywhere”&#xff0c;也就是通过对应用组件的封装&#xff0c;分发&#xff0c;部署&#xff0c;运行等生命周期的管理&#xff0c;使用户的应用及其运行环境能够做到”…

jenkins使用注意问题

1.在编写流水线时并不知道当前处在哪个目录&#xff0c;导致名使用不当&#xff0c;以及文件位置不清楚 流水线任务默认路径是&#xff0c;test4_mvn为jenkins任务名 [Pipeline] sh (hide)pwd /var/jenkins_home/workspace/test4_mvn maven任务也是&#xff0c;看来是一样的…

CV每日论文--2024.6.14

1、ICE-G: Image Conditional Editing of 3D Gaussian Splats 中文标题&#xff1a;ICE-G&#xff1a;3D 高斯斑点的图像条件编辑 简介&#xff1a;近年来,出现了许多技术来创建高质量的3D资产和场景。然而,当涉及到这些3D对象的编辑时,现有方法要么速度慢、要么牺牲质量,要么…

数组(C语言)(详细过程!!!)

目录 数组的概念 一维数组 sizeof计算数组元素个数 二维数组 C99中的变⻓数组 数组的概念 数组是⼀组相同类型元素的集合。 数组分为⼀维数组和多维数组&#xff0c;多维数组⼀般比较多见的是二维数组。 从这个概念中我们就可以发现2个有价值的信息&#xff1a;(1)数…

flask_sqlalchemy时间缓存导致datetime.now()时间不变问题

问题是这样的&#xff0c;项目在本地没什么问题&#xff0c;但是部署到服务器过一阵子发现&#xff0c;这个时间会在某一刻定死不变。 重启uwsgi后&#xff0c;发现第一条数据更新到了目前最新时间&#xff0c;过了一会儿再次发送也变了时间&#xff0c;但是再过几分钟再发就会…

软件测试--Mysql快速入门

文章目录 软件测试-mysql快速入门sql主要划分mysql常用的数据类型sql基本操作常用字段的约束&#xff1a;连接查询mysql内置函数存储过程视图事务索引 软件测试-mysql快速入门 sql主要划分 sql语言主要分为&#xff1a; DQL&#xff1a;数据查询语言&#xff0c;用于对数据进…

基于Verilog表达的FSM状态机

基于Verilog表达的FSM状态机 1 FSM1.1 Intro1.2 Why FSM?1.3 How to do 在这里聚焦基于Verilog的三段式状态机编程&#xff1b; 1 FSM 1.1 Intro 状态机是一种代码实现功能的范式&#xff1b;一切皆可状态机&#xff1b; 状态机编程四要素&#xff1a;– 1.状态State&#…

通用大模型与垂直大模型:双轨并进的人工智能未来

在人工智能(AI)的浩瀚宇宙中&#xff0c;大模型以其强大的学习能力和广泛的适用性&#xff0c;正逐步成为推动技术进步和产业革新的核心动力。在这股浪潮中&#xff0c;通用大模型与垂直大模型如同两颗璀璨的星辰&#xff0c;各自散发着独特的光芒&#xff0c;共同照亮了AI发展…

STL入门指南:从容器到算法的完美结合

目录 ​编辑 一、什么是STL 二、STL的版本 三、STL的六大组件 1. 容器&#xff08;Containers&#xff09;&#xff1a; 2. 算法&#xff08;Algorithms&#xff09;&#xff1a; 3. 迭代器&#xff08;Iterators&#xff09;&#xff1a; 4. 仿函数&#xff08;Functo…

中国算力基础设施“第一阵营”变局?

2024年6月IDC最新数据显示&#xff0c;2024年第一季度&#xff0c;联想服务器跃升至中国市场份额第三位。中国算力基础设施“第一阵营”正生变局。 在去年服务器本地化品牌联想问天发布之后&#xff0c;联想就发出了向国内服务器市场冲锋的信号。如今仅一年&#xff0c;就进入…

工业4.0下的PLC进化论:ARMxy计算机如何重塑自动化

智能物流系统的高效与精准成为企业竞争力的关键。在这个背景下&#xff0c;传统的PLC系统因其固有的局限性&#xff0c;如扩展性差、系统封闭等&#xff0c;开始显得力不从心。ARMxy工业计算机作为新一代的PLC替代方案&#xff0c;凭借其低功耗、高性能以及高度的灵活性&#x…

Android Studio历史版本

android studio的历史版本

自然语言处理领域的重大挑战:解码器 Transformer 的局限性

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

本地Zabbix开源监控系统安装内网穿透实现远程访问详细教程

文章目录 前言1. Linux 局域网访问Zabbix2. Linux 安装cpolar3. 配置Zabbix公网访问地址4. 公网远程访问Zabbix5. 固定Zabbix公网地址 &#x1f4a1;推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【…

【机器学习】机器学习赋能医疗健康:从诊断到治疗的智能化革命

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀目录 &#x1f4d2;1. 引言&#x1f4d9;2. 机器学习在疾病诊断中的应用&#x1f9e9;医学影像分析&#xff1a;从X光到3D成像带代码&#x1…

我的考研经历

当我写下这篇文章时&#xff0c;我已经从考研 的失败中走出来了&#xff0c;考研的整个过程都写在博客日志里面了&#xff0c;在整理并阅读考研的日志时&#xff0c;想写下一篇总结&#xff0c;也算是为了更好的吸取教训。 前期日志模板&#xff1a;时间安排的还算紧凑&#x…

vivado HW_VIO

描述 虚拟输入/输出&#xff08;VIO&#xff09;调试核心hw_VIO可以监视和驱动内部 在编程的XilinxFPGA上实时显示信号。在没有物理访问的情况下 目标硬件&#xff0c;可以使用此调试功能来驱动和监视 存在于物理设备上。 VIO核心具有硬件探测器hw_probe对象&#xff0c;用于监…

DeepSpeed Monitoring Comm. Logging

Monitoring 支持多种后端&#xff1a;Tensorboard、WandB、Comet、CSV文件&#xff1b; TensorBoard例子&#xff1a; 自动监控&#xff1a;DeepSpeed自动把重要metric记录下来。只需在配置文件里enable相应的看板后端即可&#xff1a; {"tensorboard": {"enabl…