【C++】命名空间

本文详细解释了C++中的命名空间概念,阐述其用于避免标识符冲突的原因,以及如何定义、访问和处理不同情况下的命名空间,包括嵌套、展开和指定展开。
摘要由CSDN通过智能技术生成

目录

前序

什么是命名空间

为什么要使用命名空间

命名函数的定义

默认访问变量的顺序

命名空间的几种情况

不同命名空间中出现相同的命名

多个命名相同的命名空间

命名空间嵌套

命名空间的展开 

展开命名空间的缺点


前序

相信大家在cpp代码中经常可以看到头文件下面看到using namespace std这样一个语句,每次写c++代码时都要加上这句话,否则就会报错,不知道这句话酒精有什么作用,是什么意思;其实这是c++提供的命名空间;

什么是命名空间

所谓的命名空间就是一个域,可以由我们自己创造,我们可以在其中定义各种变量、函数、结构体、类等等;

为什么要使用命名空间

由于C++大量存在的标识符(变量、函数和类的名称),并且这些标识符处于全局作用域中,为避免命名冲突或命名污染namespace对这些标识符的名称进行了本地化,使编译器在全局作用域中不直接检索到这些标识符。
下面我们来看一段代码:

#include<stdio.h>
 int rand = 20;
 int main()
 {
	 printf("%d", rand);
	 return 0;
 }

这段代码其实是可以成功运行的,但即使能够运行,也是有着严重的缺陷,我在全局域中定义了一个变量rand,rand是什么?我们通常用来产生随机数的一个函数,rand是一个函数的名字,因此命名上发生了冲突; 我们试想一个公司员工在进行一个项目的时候,代码量可想而知是十分巨大的,在这其中存在着各种各样的命名,不免有些命名“撞”到一块去,引发冲突,就很难受了,而命名空间就是解决这样的问题而出现;

命名函数的定义

定义命名空间需要使用关键字namespace,顾名思义,就是命名空间的意思;我们依旧一上面的代码为例,倘若我将rand放在命名空间里面然后进行访问是不是就不会发生冲突了;
代码如下:

#include<stdio.h>
namespace bit {
	int rand = 20;
    int add(int a,int b)
    {
        return a+b;//函数、结构体也是可以的
    }
}
 int main()
 {
	 printf("%d", bit::rand);
	 return 0;
 }

 需要注意的是1.访问命名空间内容时,需要指明是哪个命名空间,因为命名空间不只可以定义一个,以bit::rand这样的形式进行访问其中的元素、函数等等;
2.命名空间里面的变量没有生命周期,也就是空间里的变量是全局变量,在main函数中是可以改变空间中变量的值的。

默认访问变量的顺序

我们在前面c中学过在main函数中的访问元素时,遵循局部优先,比如我定义了一个全局变量a并初始化为10,但是我在main函数中有进行了重新赋值为20,那么我打印的a的值就是20;局部要优于全局.
那么再加上命名空间这种域呢?
在c++中,我们访问元素的顺序仍然是局部大于全局,即使是有了命名空间,也不会主动访问该空间

#include<stdio.h>
namespace bit {
	int rand = 20;
}
 int main()
 {
	 printf("%d", rand);
	 return 0;
 }

就像这样我要访问rand这个变量,编译器会先在局部域中寻找,找不到了就去全局域找,如果在全局域中也找不到就会报错,系统是不会主动在命名空间中访问的,因此我们手动进行访问有时是必要的。

命名空间的几种情况

1.不同命名空间中出现相同的命名

举个例子,我们在bit1的命名空间中定义了一个普通变量a,在bit2命名空间中定义了一个普通变量b,然后进行访问,这时候只要指明指那个命名空间就不会发生冲突。代码如下:

#include<stdio.h>
namespace bit1
{
	int a=10;
}
namespace bit2
{
	int a = 20;
}
int main()
{
	printf("%d\n", bit1::a);
	printf("%d\n", bit2::a);
	return 0;
}

 命名空间中的元素具有全局变量的性质,但不能将其完全看成全局变量,在不同的域中命名是可以形同的,并不会发生冲突。

2.多个命名相同的命名空间

倘若我定义了多个命名空间,在这些明明空间中有几个变量的命名是相同,那他们会发生冲突吗?
会的。当我们定义了多个相同的名字的命名空间的话,那么这些命名空间编译时就会发生合并,合并成一个共同的域,在同一个域中是不能出现命名相同的元素名称的。但命名空间支持嵌套。

命名空间嵌套

我们未解决上述的问题,可以更改一个空间的名字之外,就是可以使用嵌套,代码如下:

#include<stdio.h>
namespace bit {
	namespace bit1
	{
		int a = 10;
	}
}
	namespace bit1
	{
		int a = 20;
	}
int main()
{
	printf("%d\n", bit::bit1::a);
	printf("%d\n", bit1::a);
	return 0;
}

我们可以将其一个空间进行嵌套,这样两个空间就不冲突啦,然后访问时需要进行二次::访问;

命名空间的展开 

命名空间的展开等同与展开头文件(将其内容进行拷贝),而是类似与函数的声明。举个例子,代码如下:

#include<stdio.h>
namespace bit {
    int rand = 20;
    int add(int a, int b)
    {
        return a + b;
    }
}
int main()
{
    printf("%d", bit::rand);
    printf("%d", bit::rand);
    printf("%d", bit::rand);
    printf("%d", bit::rand);
    printf("%d", bit::rand);
    printf("%d", bit::rand);
    printf("%d", bit::rand);
    return 0;
}

当我们需要多次访问空间中的元素时,我们每一次都需要进行bit::这样的访问的方式是很繁琐的,所以c++支持的命名空间的展开,就很好的解决了这类问题(在一个文件中),上代码:

#include<stdio.h>
namespace bit {
    int rand = 20;
    int add(int a, int b)
    {
        return a + b;
    }
}
using namespace bit;
int main()
{
    printf("%d", rand);
    return 0;
}

展开命名空间的格式是using namesapce +名称,在定义好的命名空间的下面进行展开,这样下面的访问的空间中的元素就可以直接访问;但为什么说是在一个文件中好用的?因为我们平时写代码都是只使用一个文件就足够了,在一个文件中我们通常只会定义一个命名空间,所以不会与其他命名空间发生冲突;

展开命名空间的缺点

试想如果我在一个文件中展开了,2个命名空间,一个空间存在该元素另一个不存在还好;但是我要访问的元素在两个空间中都存在,那到底访问的是哪一个呢?这就会发生冲突了。所以在使用时也需要注意使用的情况;

命名空间的指定展开

有时候我们并不需要将整个命名空间全部展开,所以我们可以只对其中的指定的元素进行展开;
代码如下:

#include<stdio.h>
namespace bit {
    int rand = 20;
    int add(int a, int b)
    {
        return a + b;//函数、结构体也是可以的
    }
}
using bit::rand;
int main()
{
    printf("%d", rand);
    printf("%d", bit::add(2, 5));
    return 0;
}

通过using bit ::rand我们可以对rand进行展开,访问时可以直接访问,但是其他没有指定展开的依旧要使用原来的方式进行访问,当然指定访问的个数并不是唯一的,可以多写几个using bit ::元素,来根据情况使用; 

using namespace std;涉及到C++输入、输出流;请看下篇博客;

  • 36
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
命名空间的使用有三种方式: 1. 使用命名空间名称及作用域限定符,比如c::a。 2. 使用using关键字将命名空间中的成员引入,比如using c::a。 3. 使用using namespace命名空间名称引入命名空间的所有成员,比如using namespace c。 其中,方法一是通过在成员前加上命名空间名称和作用域限定符来访问命名空间中的成员。方法二是通过using关键字将特定的成员引入,使得可以直接使用该成员。方法三是使用using namespace关键字引入整个命名空间的所有成员,使得可以直接使用命名空间中的所有成员。 需要注意的是,在使用命名空间时,可以采用方法一、方法二或方法三的任意一种方式,具体选择哪种方式取决于实际需求和代码的清晰度。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [C++命名空间](https://blog.csdn.net/zhang21722668/article/details/83869631)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [C++命名空间(namespace)的使用](https://blog.csdn.net/qq_43533553/article/details/123257675)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值