【C++】弥补C语言的不足(①命名冲突问题)

Hello,这里是关于C++的入门,C++的命名冲突问题,如果你像我一样对命名空间满是疑惑,只知道using namespace std,那么可以看下这篇文章,我自己之前的一些疑惑以及一些形象的理解。

🌻命名冲突问题

首先,我们先来看一段很简单的C语言程序。

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

我们运行程序,发现程序出现了报错。如下:

rand 重定义;以前定义的是函数
我们在cpusplus.com网站上搜索rand()函数,便可简单了解。

rand()是来产生随机数的一个函数,内部使用线性同余法实现。
当我们又在程序中定义一个全局变量rand时,显然,这个变量rand与函数rand产生了命名冲突
关于命名冲突问题,既可能是我们自己定义的变量与库进行冲突,也有可能是在一个大型项目中我们彼此之间的冲突。
因此,为了解决C语言的这个问题,C++在此上进行改善。
于是C++为了解决这个问题,定义了命名空间
于是,我们可以用C++来改善我们刚刚的C语言程序。将我们的全局变量rand放进命名空间。(用命名空间将自己定义的变量“封”起来。)

这时,我们编译程序,程序没有出现报错。
当我们将我们定义的全局变量rand放进自己定义的命名空间的时候,也就是将自己定义的全局变量“封装起来”,在程序运行时,访问的rand即是库函数中的rand()函数

我们打印的是rand函数的地址,将%d改成%p函数就不会报错了。

而当我们想要访问自己定义的全局变量时,我们即“指定”即可,即使用域作用限定符号::
即改成printf("%d\n",my_space::rand);即可访问变量rand(因为我们自定义的命名空间并没有打开)。
关于命名空间,我们自定义的命名空间中不仅仅可以放变量,也可以放函数、结构体等。
我们加入一个函数,进一步扩展我们的命名空间。如下:

这里需要注意的是,既然要访问my_space中的函数,那么就要用域作用限定符来指定。(因为my_space并没有全部打开,没有"暴露"出来,我们要告诉编译系统,我们使用的Add()来自哪里,让编译系统直接去找。)
若没有限定的话,那么就会出现报错。如下。

我们可以再加入结构体:

可能有的童学会想,如果在极端情况下,我们自己定义的命名空间内的变量的名字也出现了冲突怎么办?或是在一个很大的项目中,由于代码行数过多,不经意间将自己已经定义过的的变量又再次定义怎么办呢?
其实,对于命名空间,是可以进行嵌套的。从而将一个很大的命名空间内在定义几个小的命名空间,使得逻辑更清晰。同样,在小的命名空间内还可以进行进一步的嵌套。

🌻命名空间实现声明与定义的分离

下面我们来讨论一下如何用命名空间实现声明与定义的分离。
同一个文件的相同名字的命名空间一般会合并在一起。
我们用简单的栈来看。(其中压栈那个函数简单写得不严谨。)

这样将头文件和cpp文件都分别封装,不会发生命名冲突的问题。
同一个文件多个位置的同名的命名空间,编译器会把它们合并为一个。

🌻从默认指定---->展开访问---->指定展开

即展开命名空间
展开命名空间与展开头文件的区别?
展开头文件是在预处理阶段,编译系统将头文件中的内容拷贝过来。
而展开头文件,即是打开命名空间,(打开了封住它的一堵墙),将它"暴露"出来。
而仅仅展开头文件,头文件中的内容则不一定暴露出来。
比如关于C++标准库,

我们不进行展开,就会出现报错。

展开头文件仅仅是将头文件中的内容拷贝过来,但是它被C++的标准库给封装在一起,我们如果展开这个标注库std(也是一个命名空间),我们就可以自由地使用了。

但是,关于命名空间的展开,我们也要分情况。
若是我们平时的小练习,那么我们自己定义的变量和库中重命名的概率很小很小,为了方便和简洁,就可以直接展开。
但若是在一个项目中,定义变量和函数过多既有可能与库的重冲突,又有可能与其他同事的冲突,所以,不建议展开。

比如,我们写简单的输出:
我们打开标准库:

#include <iostream>
using namespace std;
int main()
{
	cout << "hello" << endl;
	return 0;
}

也可以不打开标准库:(使用作用域限定符,指定编译系统到std命名空间去找cout。)

#include <iostream>
int main()
{
	std::cout << "hello" << std::endl;
	return 0;
}

像上面,我们每次指定展开命名空间很不方便;直接展开,全部暴露,又有冲突风险,那么我们用指定展开解决问题。
如下:

#include <iostream>
using  std::cout;
using  std::endl;
int main()
{
	cout << "hello" << endl;
	return 0;
}
  • 11
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

釉色清风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值