为什么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;    
}
相关推荐
kangkang-25 分钟前
PC端基于SpringBoot架构控制无人机(二):MavLink协议
java·spring boot·后端·无人机
麦兜*1 小时前
Spring Boot秒级冷启动方案:阿里云FC落地实战(含成本对比)
java·spring boot·后端·spring·spring cloud·系统架构·maven
喷火龙8号2 小时前
MSC中的Model层:数据模型与数据访问层设计
后端·架构
5ycode2 小时前
dify项目结构说明与win11本地部署
后端·开源
LaoZhangAI2 小时前
GPT-image-1 API如何传多图:开发者完全指南
前端·后端
fouryears_234172 小时前
深入拆解Spring核心思想之一:IoC
java·后端·spring
codervibe2 小时前
从 0 到 1,我如何独立开发一套教务系统(EduCore)
后端
error_cn2 小时前
podman安全性设置
后端
一个热爱生活的普通人2 小时前
Go 泛型终极指南:告别 interface{},写出更安全、更强大的代码!
后端·go
求知摆渡2 小时前
从零开始搭建typecho
前端·后端