详细了解C++中的namespace命名空间

键盘敲烂,月薪过万,同学们,加油呀!

目录

键盘敲烂,月薪过万,同学们,加油呀!

  一、命名空间的理解

二、::作用域运算符

三、命名空间(namespace)

3.1、namespace的由来

3.2、命名空间使用语法

3.3、using声明

3.4、using编译指令


 

  一、命名空间的理解

同学们好!今天王老师来带大家了解C++中的命名空间(namespace)的一个概念。首先要了解什么是命名空间,这个大家就可以把它理解成一个工具箱,如下图:

众所周知,我们C++一般用在大型项目中,现在假设我们一共有张三,李四,王五三个人完成一个大型项目, 因为项目太大了,所以我们在创建变量的时候就有很大的概率会造成变量名相同的一个问题,这个时候就会发生命名冲突的一个问题了,这个时候怎么办呢?这时我们就可以用到C++中的命名空间了,这个就像把我们所创建好的东西放入一个工具箱中,但是这个工具箱有好多个,每个工具箱中有个别工具是相同的(外貌相同,并不是同一个),这个时候我们需要用到哪个工具箱中的工具我们就去哪个工具箱中拿,这样就能解决命名冲突的一个问题了,这也是命名空间最大的一个用处。

比如上图中,我们如果需要用到A空间中的a我们就去A中拿,要用到B中的a我们就去B中拿,这样编译器就不会不知道我要用的这个变量是来自于哪里了。

二、::作用域运算符

在正式了解命名空间之前我们还需要了解::作用域运算符。

通常情况下,如果有两个同名变量,一个全局变量,一个局部变量,那么局部变量在其作用域范围内有更高的优先级,它将屏蔽全局变量。

如下代码:

int a = 10;
void fun(void)
{
    int a = 20;
    cout<<a<<endl;    
}

程序的输出结果是:

a = 20 

在这个fun函数中,cout输出语句使用的变量a是fun函数中内部定义的局部变量a,因此输出的结果为局部变量a 的值。在C语言中,我们无法解决这个问题,无法在fun函数中访问到全局变量a,但是在C++中我们可以用作用域运算符解决这个变量重名问题。

代码如下:

//全局变量
int a = 10;
//1. 局部变量和全局变量同名
void test(){
int a = 20;
//打印局部变量 a
cout << "局部变量 a:" << a << endl;
//打印全局变量 a
cout << "全局变量 a:" << ::a << endl;
}
从这个例子可以看出,作用域运算符可以解决局部变量与全局变量的重名问题,即在局部变量的作用域中,可用::对被屏蔽的同名的全局变量进行访问。

三、命名空间(namespace)

3.1、namespace的由来

在C++中,我们在好多地方都需要命名,比如说结构体、常量、变量、函数、枚举、类和对象等等,我们都需要去给它们取个名字。工程越大,名称互相冲突的可能性越大。另外使用多个厂商的类库时,也可能导致名称冲突,为了避免,在大规模程序的设计中,以及在程序员使用各种各样的C++库时,这些标识符的命名发生冲突,标准C++引入了关键字namespace(命名空间),可以更好地控制标识符的作用域

3.2、命名空间使用语法

创建一个命名空间:

namespace A{
    int a = 10;
}

namespace B{
    int a = 20;
}

void test(){
    cout<<"A::a"<<A::a<<endl;
    cout<<"B::a"<<B::a<<endl;
}

命名空间只能全局范围内定义(以下写法错误)

//错误写法
void test(){
    namespace A{
        int a = 10;
    }
    cout<<"A::a"<<A::a<<endl;
}

命名空间可以嵌套命名空间

namespace A{
    int a = 10;
    namespace B{
        int a = 20;
    }
}

void test(){
    cout<<"A::a"<<A::a<<endl;
    cout<<"A::B::a"<<A::B::a<<endl;
}

命名空间是开放的,即可以随时把新的成员加入已有的命名空间中: 

 

namespace A {
    int a = 100;
    int b = 200;
}
//将c添加到已有的命名空间A中
namespace A {
    int c = 300;
}

void test04()
{
    cout<<"A中a = "<<A::a<<endl;//100
    cout<<"A中c = "<<A::c<<endl;//200
}

函数的声明和实现可以分离

namespace A {
    int a=100;//变量

    void func();
}

void A::func()//成员函数 在外部定义的时候 记得加作用域
{
    //访问命名空间的数据不用加作用域
    cout<<"func遍历a = "<<a<<endl;
}

无名的命名空间,意味着命名空间中的标识符只能在本文件中访问,相当于给这个标识符加上了static,使得其可以作为内部连接(了解)

namespace{
    int a = 10;
    void func(){ cout << "hello namespace" << endl; }
}
void test(){
    cout << "a : " << a << endl;
    func();
}

命名空间取别名(了解)

namespace veryLongName{
    int a = 10;
    void func(){ cout << "hello namespace" << endl; }
}
void test(){
    namespace shortName = veryLongName;
    cout << "veryLongName::a : " << shortName::a << endl;
    veryLongName::func();
    shortName::func();
}

3.3、using声明

using声明可以使得指定的标识符可用

namespace A{
    int paramA = 20;
    int paramB = 30;
    void funcA(){ cout << "hello funcA" << endl; }
    void funcB(){ cout << "hello funcA" << endl; }
}
void test(){
    //1. 通过命名空间域运算符
    cout << A::paramA << endl;
    A::funcA();
    //2. using 声明
    using A::paramA;
    using A::funcA;
    cout << paramA << endl;
    //cout << paramB << endl; //不可直接访问
    funcA();
    //3. 同名冲突
    //int paramA = 20; //相同作用域注意同名冲突
}

using声明碰到函数重载

namespace A{
    void func(){}
    void func(int x){}
    int func(int x,int y){}
}
void test(){
    using A::func;
    func();
    func(10);
    func(10, 20);
}

如果命名空间包含一组用相同名字重载的函数,using声明就声明了这个重载函数的所有集合

3.4、using编译指令

using编译指令使整个空间标识符可用

namespace A{
    int paramA = 20;
    int paramB = 30;
    void funcA(){ cout << "hello funcA" << endl; }
    void funcB(){ cout << "hello funcB" << endl; }
}
void test01(){
    using namespace A;
    cout << paramA << endl;
    cout << paramB << endl;
    funcA();
    funcB();
    //不会产生二义性
    int paramA = 30;
    cout << paramA << endl;
}

namespace B{
    int paramA = 20;
    int paramB = 30;
    void funcA(){ cout << "hello funcA" << endl; }
    void funcB(){ cout << "hello funcB" << endl; }
}
void test02(){
    using namespace A;
    using namespace B;
    //二义性产生,不知道调用 A 还是 B 的 paramA
    //cout << paramA << endl;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vulnhub靶机:Bellatrix

一、介绍 运行环境&#xff1a;Virtualbox 攻击机&#xff1a;kali&#xff08;10.0.2.4&#xff09; 靶机&#xff1a;Bellatrix&#xff08;10.0.2.9&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1a;https://www.vulnhub.com/entry/hogwa…

【C++】const成员

个人主页 &#xff1a; zxctscl 如有转载请先通知 文章目录 1. 前言2. const成员3. 取地址及const取地址操作符重载 1. 前言 在之前已经已经分享过了关于 【C】类和对象之常引用与运算符重载&#xff0c;这次分享的有关const的内容&#xff0c;话不多说&#xff0c;正文开始。…

spring-security 项目实战(一)个人健康档案

spring-security 项目实战&#xff08;一&#xff09;个人健康档案 项目说明项目地址框架信息 代码分析配置类解析默认登录页登录接口执行逻辑登录认证成功之后重定向到main页面过程未登录之前访问 /main生成默认登录页点击登录 登录之后访问 /main执行流程清空认证信息 项目来…

Leetcoder Day27| 贪心算法part01

语言&#xff1a;Java/Go 理论 贪心的本质是选择每一阶段的局部最优&#xff0c;从而达到全局最优。 什么时候用贪心&#xff1f;可以用局部最优退出全局最优&#xff0c;并且想不到反例到情况 贪心的一般解题步骤 将问题分解为若干个子问题找出适合的贪心策略求解每一个子…

数据类型和变量

1.数据类型 在Java中数据类型主要分为两类&#xff1a;基本数据类型和引用数据类型。 基本数据类型有四类八种&#xff1a; 1. 四类&#xff1a;整型、浮点型、字符型以及布尔型 2.八种&#xff1a; 整形是分为如上四种 byte short int long 浮点型分为 float 和double …

【Java EE】线程安全的集合类

目录 &#x1f334;多线程环境使用 ArrayList&#x1f38d;多线程环境使⽤队列&#x1f340;多线程环境使⽤哈希表&#x1f338; Hashtable&#x1f338;ConcurrentHashMap ⭕相关面试题&#x1f525;其他常⻅问题 原来的集合类, 大部分都不是线程安全的. Vector, Stack, HashT…

Java---文件,流✨❤️

文章目录 1.遍历文件夹2.遍历子文件夹3.练习流4.以字节流的形式读取文件内容5.以字节流的形式向文件写入数据顶折纠问6 .写入数据到文件 1.遍历文件夹 一般说来操作系统都会安装在C盘&#xff0c;所以会有一个 C:\WINDOWS目录。 遍历这个目录下所有的文件(不用遍历子目录) 找出…

全栈入门,前后端入门--springboot3+vue3制作一个后台管理项目

一&#xff1a;前言 1&#xff1a;因为本人也是全栈初学者&#xff0c;现在主职是公司前端&#xff0c;鉴于当前行业形式&#xff0c;单单只掌握一门语言已经不再吃香&#xff0c;甚至有点危险&#xff0c;35岁危机极大可能提前。作为00后要始终保持危机意识&#xff0c;不至于…

[C++]使用纯opencv去部署yolov9的onnx模型

【介绍】 部署 YOLOv9 ONNX 模型在 OpenCV 的 C 环境中涉及一系列步骤。以下是一个简化的部署方案概述&#xff0c;以及相关的文案。 部署方案概述&#xff1a; 模型准备&#xff1a;首先&#xff0c;你需要确保你有 YOLOv9 的 ONNX 模型文件。这个文件包含了模型的结构和权…

opencv生成一张图片

opencv也可以创造出一张照片&#xff0c;下面就是创造一张照片&#xff0c;并存放到项目文件夹下的示例 #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> #include <vector> using namespace cv…

sql注入之sqli-labs-less-2 数值型报错注入

输入?id1 进行试探,第二关数值型&#xff0c;没有字符串的单引号&#xff0c;所以输入单引号报错&#xff0c; 经试探?id1 order by 5 -- 如果是错误的数值&#xff0c;显示如下&#xff1a; 正确 的为&#xff1a; ?id1 order by 3 -- 进行注入查看回显点&#xff1a; …

个体工商户营业执照怎么在网上年检?

第一步PC端登录国家企业信用信息公示系统&#xff01; 第二步点企业信息填报&#xff01; 第三步选择省份&#xff01; 第四步登陆方式&#xff01; 第五步点左上角年度报告填写&#xff01; 第六步下滑浏览点确认&#xff01; 第七步按照实际情况填写&#xff01; 第八步…

Linux笔记--文件权限

一、相关概念 Linux最优秀的地方之一就在于多人多任务环境。为了让各个使用者有较为保密的文件数据&#xff0c;文件的权限管理尤为重要。 ●文件的可存取身份: owner:文件拥有者 group:文件所属用户组 others:其他人 ●文件权限: r: read&#xff0c;读 文件:是否能查看文件内…

代码随想录刷题笔记 DAY 41 | 整数拆分 No.343 | 不同的二叉搜索树 No.96

文章目录 Day 4101. 整数拆分&#xff08;No. 343&#xff09;<1> 题目<2> 笔记<3> 代码 02. 不同的二叉搜索树&#xff08;No. 96&#xff09;<1> 题目<2> 笔记<3> 代码 Day 41 01. 整数拆分&#xff08;No. 343&#xff09; 题目链接 …

2024.3.1 小项目

1、机械臂 #include <myhead.h> #define SER_IP "192.168.125.32" //服务器端IP #define SER_PORT 8888 //服务器端端口号#define CLI_IP "192.168.68.148" //客户端IP #define CLI_PORT 9999 /…

Mybatis plus扩展功能-Db静态工具

目录 1 前言 2 使用方法 2.1 Db静态工具拥有的部分方法 2.2 举例 1 前言 在我们的服务层中&#xff0c;有时为了实现一个方法需要引入其它的Mapper层方法&#xff0c;但是&#xff0c;这样可能出现循环依赖。虽然Spring已经给我们解决了简单的循环依赖问题&#xff0c;但是…

【书生·浦语大模型实战营】第4节 课后作业

XTuner 大模型单卡低成本微调实战 0. 课程链接1. 课后作业1.2 进阶作业 0. 课程链接 课程链接&#xff1a;https://github.com/InternLM/tutorial/blob/main/xtuner/README.md 1. 课后作业 构建数据集&#xff0c;使用 XTuner 微调 InternLM-Chat-7B 模型, 让模型学习到它是你…

数字化转型导师坚鹏:证券公司数字化思维升级之道

证券公司数字化思维升级之道 ——数字化思维之六脉神剑 课程背景&#xff1a; 很多证券公司存在以下问题&#xff1a; 不知道数字化转型如何改变思维模式&#xff1f; 不清楚需要建立什么样的数字化思维&#xff1f; 不知道如何开展数字化思维提升工作&#xff1f; 课…

Redis小白入门教程

Redis入门教程 1. Redis入门1.1 Redis简介1.2 Redis服务启动与停止1.2.1 Redis下载1.2.2 服务启动命令1.2.3 客户端连接命令1.2.4 修改Redis配置文件 2. Redis数据类型2.1 五种常用数据类型介绍2.1.1 字符串操作命令2.1.2 哈希操作命令2.1.3 列表操作命令2.1.4 集合操作命令2.1…

JWT的原理与隐患

什么是JWT JWT通常由三部分组成&#xff1a;头信息&#xff08;header&#xff09;, 消息体&#xff08;payload&#xff09;和签名&#xff08;signature&#xff09;。 头信息指定了该JWT使用的签名算法 header {"alg":"HS256","typ":"…
最新文章