为什么c++要在c语言的基础上添加命名空间?命名空间如何定义和使用?

1、为什么c++要在c语言上增添命名空间的概念

r 复制代码
  在c语言中,定义的全局变量与库中相同,或者和别人代码结合的时候可能存在相同的命名,此时就会命名冲突。c语言是没有办法很好的解决这个问题的。

假设这样一种情况,当一个班上有两个名叫 Zara 的学生时,为了明确区分它们,我们在使用名字之外,不得不使用一些额外的信息,比如他们的家庭住址,或者他们父母的名字等等。

​ 同样的情况也出现在 C++ 应用程序中。例如,您可能会写一个名为 xyz() 的函数,在另一个可用的库中也存在一个相同的函数 xyz()。这样,编译器就无法判断您所使用的是哪一个 xyz() 函数。因此,引入了命名空间这个概念,专门用于解决上面的问题,它可作为附加信息来区分不同库中相同名称的函数、类、变量等。使用了命名空间即定义了上下文。本质上,命名空间就是定义了一个范围。 全

2、如何定义命名空间

​ ::域作用限定符 ,把作用域限定在全局,左边没有或者空格都行,默认就是全局,如果过你左边写了名字,那么就是就是命名空间的域。namespace{}就是命名空间的用法。

c++ 复制代码
#include <stdio.h>
#include <stdlib.h>
int rand = 10;
// C语言没办法解决类似这样的命名冲突问题,所以C++提出了namespace来解决
int main()
{
 	printf("%d\n", rand);
	return 0;
}
// 编译后后报错:error C2365: "rand": 重定义;以前的定义是"函数"

局部变量和局部变量可以重名,函数里面优先使用局部变量,找不到才是全局变量。

c 复制代码
#include <stdio.h>

int a = 2;
void fu()
{
	int a = 1;
	printf("%d", a);//1
	printf("%d",::a);//2
}

命名空间的定义:

c++ 复制代码
// bit是命名空间的名字,一般开发中是用项目名字做命名空间名。
// 我们上课用的是bit,大家下去以后自己练习用自己名字缩写即可,如张三:zs

// 1. 正常的命名空间定义
namespace bit
{
 // 命名空间中可以定义变量/函数/类型
 int rand = 10;
 int Add(int left, int right)
 {
 return left + right;
 }
    
    struct Node
 {
 struct Node* next;
 int val;
 };
}
//2. 命名空间可以嵌套
// test.cpp
namespace N1
{
int a;
int b;
int Add(int left, int right)
 {
     return left + right;
 }
namespace N2
 {
     int c;
     int d;
     int Sub(int left, int right)
     {
         return left - right;
     }
 }
}
//3. 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。
// ps:一个工程中的test.h和上面test.cpp中两个N1会被合并成一个
// test.h
namespace N1
{
int Mul(int left, int right)
 {
     return left * right;
 }
}

定义了命名空间,里面的变量不能直接使用。

c++ 复制代码
namespace bit
{
 // 命名空间中可以定义变量/函数/类型
 int a = 0;
 int b = 1;
 int Add(int left, int right)
 {
 return left + right;
      }
 struct Node
 {
 struct Node* next;
 int val;
 };
}
int main()
{
 // 编译报错:error C2065: "a": 未声明的标识符
 printf("%d\n", a);
return 0;
}

总结:

  • 各个文件链接展开后,如果重名也会报错,c语言无法解决这个问题

  • 于是在c基础上添加了命名空间域,只影响使用,不影响生命周期。

  • 多个文件中命名空间的名字可以一样,他们会合并,但是里面的变量名字你就不能一样了,你要一样的就只能改成两个命名空间。或者可以在命名空间里面再嵌套一层命名空间,访问时::::两个符号就可以了。

  • std是c++标准库的命名空间,using namespace std就是全局展开,一般不建议这样。

3、使用命名空间的三种方式

1、制定命名空间访问std::

c++ 复制代码
int main()
{
    printf("%d\n", N::a);
    return 0;    
}

2、全局展开using namespace std,一帮不建议全局展开

c++ 复制代码
using namespce N;
int main()
{
    printf("%d\n", N::a);
    printf("%d\n", b);
    Add(10, 20);
    return 0;    
}

3、常用部分展开 using std:: cout

c++ 复制代码
using N::b;
int main()
{
    printf("%d\n", N::a);
    printf("%d\n", b);
    return 0;    
}
相关推荐
幽络源小助理1 分钟前
SpringBoot+小程序高校素拓分管理系统源码 – 幽络源免费分享
spring boot·后端·小程序
程序员爱钓鱼1 分钟前
Node.js 编程实战:测试与调试 —— 日志与监控方案
前端·后端·node.js
雄大6 分钟前
使用 QWebChannel 实现 JS 与 C++ 双向通信(超详细 + 踩坑总结 + Demo)
后端
计算机学姐7 分钟前
基于SpringBoot的汉服租赁系统【颜色尺码套装+个性化推荐算法+数据可视化统计】
java·vue.js·spring boot·后端·mysql·信息可视化·推荐算法
回家路上绕了弯8 分钟前
定期归档历史数据实战指南:从方案设计到落地优化
分布式·后端
+VX:Fegn08958 分钟前
计算机毕业设计|基于springboot + vue建筑材料管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
掘金者阿豪9 分钟前
Redis `WRONGTYPE` 错误的原因及解决方法
后端
天天摸鱼的java工程师12 分钟前
线程池深度解析:核心参数 + 拒绝策略 + 动态调整实战
java·后端
小杨同学4920 分钟前
C 语言实战:动态规划求解最长公共子串(连续),附完整实现与优化
后端
Cache技术分享22 分钟前
290. Java Stream API - 从文本文件的行创建 Stream
前端·后端