目录
前言
一、命名空间是什么?
1.1命名空间域的定义
二、为什么有命名空间?
三、命名空间的用法
总结
前言
主要讲解命名空间是什么?为什么有命名空间?以及它的用法
一、命名空间是什么?
命名空间域(namespace Scope)是指命名空间的作用范围。它是一个逻辑上的区域,其中定义的标识符(如变量、函数、类等)具有独立的作用域。
1.1命名空间域的定义
namespace xx
{// 命名空间中可以定义变量/函数/类型 int rand = 0;int add(int q, int p){return q + p;}typedef struct slist{int* a;int size;}slsit;
}
int main()
{int rand=0;return 0;
}
namespace xx 就是一个命名空间,在这里面可以定义变量,函数,类型
二、为什么有命名空间?
都知道C++是在C语言的基础上的语言,C语言是有一些缺陷的,而C++要解决的第一个缺陷就是命名空间:
#include <stdio.h>
int rand = 0;
int main()
{printf("%d", rand);return 0;
}
这C语言没有问题:
如果是这样呢:
#include<stdlib.h>
#include <stdio.h>
int rand = 0;
int main()
{printf("%d", rand);return 0;
}
为什么会报错呢?
在C语言中定义一个变量rand通过了,但是加一个 #include <stdlib.h> 他就报错了,变量命名的关键是不能跟关键字冲突,但此时他并没有冲突啊,------其实是与库冲突的,而个函数叫rand,所以C语言有一个命名冲突,所以C++有了一个namespace命名空间来解决命名冲突,他可以定义一个域出来用域来隔离,用一个域里面不能定义两个同样的变量,但不同的域里面能够定义同一个变量,就好比一个家庭里面有两个孩子,父母不可能把两个孩子都取同一个名字,就好比同一个域名,不能定义两个一样的变量,但是不同的家庭里面,孩子的名字是可以重名的,就好比不同的域里面,能够定义同一个变量
- 在大型项目中,多个开发者可能会编写代码,他们的变量取的名字可能会一样,如果当他们代码合并的时候,就会显示报错
- 项目中会引入多个外部库。如果没有命名空间,很容易出现函数名、变量名或类名冲突的情况。例如,两个库都定义了一个名为 rand 的函数,如果没有命名空间,编译器将无法区分它们。通过将这些函数分别放在不同的命名空间中,就可以避免冲突。
三、命名空间的用法
我们看这样一段代码,他会打印哪种结果呢?
#include <stdio.h>
int rand = 0;
int main()
{int rand = 1;printf("%d", rand);return 0;
}
我们可以知道,局部变量的优先级是大于全局变量的
但是在C++中,可以用::(域作用限定符),代表着他能去全局域访问
#include <stdio.h>
int rand = 0;
int main()
{int rand = 1;printf("%d",::rand);return 0;
}
这里有一个::的知识点,在::前面是空的,说明是指定去全局域中搜寻,如果xx : :说明是去xx域中搜寻,前面是域名(全局域没有域名,所以是空白),: :后面是访问的变量
#include <stdio.h>
int rand = 0;
int main(){int rand = 1;printf("%d\n", rand);printf("%d\n",::rand);return 0;
}
那如果是三个域呢?
:
#include <stdio.h>
int rand = 0;
namespace xx
{// 命名空间中可以定义变量/函数/类型int rand = 2;
}
int main(){int rand = 1;printf("%d\n", rand);//printf("%d\n",::rand);return 0;
}
其实在namespace域名空间中,你不指定他,他是不会主动的去命名空间域中搜寻的,除非:
- 展开来命名空间:using namespace XX
- 指定访问命名空间域--->XX: :
- 指定访问命名空间域--->XX: :
#include <stdio.h>
int rand = 0;
namespace xx
{// 命名空间中可以定义变量/函数/类型int rand = 2;
}
int main(){int rand = 1;printf("%d\n", rand);printf("%d\n",::rand);printf("%d\n", xx::rand);return 0;
}
- 展开来命名空间:using namespace XX
#include <stdio.h>
int rand = 0;
namespace xx
{// 命名空间中可以定义变量/函数/类型int rand = 2;
}
using namespace xx;
int main(){//int rand = 1;printf("%d\n", rand);//printf("%d\n",::rand);//printf("%d\n", xx::rand);return 0;
}
如果是全局域VS命名空间域名呢:
#include <stdio.h>
int rand = 0;
namespace xx
{// 命名空间中可以定义变量/函数/类型int rand = 2;
}
using namespace xx;
int main()
{//int rand = 1;printf("%d\n", rand);//printf("%d\n",::rand);//printf("%d\n", xx::rand);return 0;
}
会报错:
常用的using namespace std,其实也是展开域,展开库里面的空间:
展开域,让编译器可以去这里面搜寻
总的来说,局部域 > 指定访问命名空间 > 全局域==展开了命名空间域
总结
- 命名空间的作用:避免命名冲突 : (避免不同模块或库中的标识符相互冲突。通过将标识符放在不同的命名空间中,即使它们的名称相同,也不会发生冲突。)+逻辑分组 :(命名空间可以将相关的代码组织在一起,使代码结构更加清晰。)
- 要访问命名空间中的成员,需要使用作用域运算符 :: or 展开命名空间域
- 使用 using 指令时需要谨慎,因为它可能会导致命名冲突,尤其是当多个命名空间中的成员名称相同时。(平常写代码都可以用,但是在做项目时要谨慎)
- 命名空间域的作用范围是从命名空间的定义开始,到命名空间的定义结束 : namespace { ....}
- 命名空间可以嵌套,嵌套的命名空间会形成嵌套的命名空间域。
- 在C++中,当访问一个标识符时,编译器会按照以下顺序进行作用域解析:
- 局部域:首先在当前局部作用域中查找。
- 类域:如果当前局部域中未找到,则在当前类的作用域中查找(如果有)。
- 命名空间域:如果仍未找到,则在当前命名空间的作用域中查找。
- 全局域:如果仍未找到,则在全局作用域中查找。
命名空间域是C++中标识符的作用范围,它通过提供独立的作用域来避免命名冲突,并将相关的标识符组织在一起。命名空间域可以嵌套,也可以与全局域、局部域和类域等相互配合,形成C++复杂而灵活的作用域体系。