为什么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;    
}
相关推荐
2301_8112743121 分钟前
springboot嗨玩旅游网站
spring boot·后端·旅游
mit6.8241 小时前
[Redis#4] string | 常用命令 | + mysql use:cache | session
数据库·redis·后端·缓存
疯狂学习GIS1 小时前
创建第一个IDEA的Java项目的方法
java·后端·intellij idea
捂月2 小时前
Spring Boot 核心逻辑与工作原理详解
java·spring boot·后端
Nightselfhurt2 小时前
RPC学习
java·spring boot·后端·spring·rpc
Estar.Lee9 小时前
查手机号归属地免费API接口教程
android·网络·后端·网络协议·tcp/ip·oneapi
2401_8576100311 小时前
SpringBoot社团管理:安全与维护
spring boot·后端·安全
凌冰_11 小时前
IDEA2023 SpringBoot整合MyBatis(三)
spring boot·后端·mybatis
码农飞飞11 小时前
深入理解Rust的模式匹配
开发语言·后端·rust·模式匹配·解构·结构体和枚举
一个小坑货11 小时前
Rust 的简介
开发语言·后端·rust