为什么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;    
}
相关推荐
A尘埃2 分钟前
SpringBoot的数据访问
java·spring boot·后端
yang-23073 分钟前
端口冲突的解决方案以及SpringBoot自动检测可用端口demo
java·spring boot·后端
Marst Code9 分钟前
(Django)初步使用
后端·python·django
代码之光_198016 分钟前
SpringBoot校园资料分享平台:设计与实现
java·spring boot·后端
编程老船长28 分钟前
第26章 Java操作Mongodb实现数据持久化
数据库·后端·mongodb
IT果果日记1 小时前
DataX+Crontab实现多任务顺序定时同步
后端
姜学迁2 小时前
Rust-枚举
开发语言·后端·rust
爱学习的小健3 小时前
MQTT--Java整合EMQX
后端
北极小狐3 小时前
Java vs JavaScript:类型系统的艺术 - 从 Object 到 any,从静态到动态
后端
tangdou3690986553 小时前
两种方案手把手教你多种服务器使用tinyproxy搭建http代理
运维·后端·自动化运维