文章目录
- 一,命名空间出现的意义
- 二,命名空间的定义
- 命名空间里面可以包含变量,函数,类型:
- 命名空间不可以定义在局部作用域:
- 命名空间可以嵌套:
- 三,同一个工程中允许存在多个相同名称的命名空间,编译器最后会将其合并成一个命名空间,不会报错:
- 允许存在未命名的名称空间
- 四,命名空间的使用
- 加命名空间名称及作用域限定符
- 使用using将命名空间的某个成员引入(using声明)
- 使用“using namespace 命名空间名称 ”引入(using编译指令)
- 五,命名空间的使用建议
一,命名空间出现的意义
命名空间(Namespace)在编程中的作用主要有以下几点意义
- 避免命名冲突:命名空间提供了一种将标识符(如变量、函数、类等)组织和隔离的方式。不同的命名空间可以拥有相同名称的标识符,避免了不同模块或库之间的命名冲突。
- 提高可读性和可维护性:通过使用命名空间,可以更清晰地表示代码中的层次结构和组织关系。这样,其他开发者可以更容易理解代码,并且在开发或维护时可以更方便地定位和修改相关部分。
- 模块化和组件化:命名空间可以用于划分代码逻辑上的模块和组件。每个命名空间可以包含相关的函数、类、常量等,实现了代码的模块化和组件化,使得代码更加可组织和易于扩展。
- 提供封装和访问控制:命名空间可以用于封装代码,并提供对外部的访问控制。通过在命名空间中定义私有成员和公共接口,可以限制对命名空间内部的访问,增强代码的安全性和稳定性。
- 支持库和框架开发:命名空间为库和框架的开发提供了一种清晰的组织结构。不同的模块可以通过命名空间进行逻辑上的分割和集成,使得库和框架更易于使用和扩展。
总的来说,命名空间提供了一种组织、隔离和管理代码的机制,有助于避免命名冲突、提高可读性和可维护性,以及支持模块化和封装。它在大型项目或多人协作开发中尤为重要,能够提高代码的可靠性和可扩展性。
最重要的一点还是命名冲突,下面举个例子能够直观的感受:
#include<stdlib.h>
#include <stdio.h>
int rand = 9;
int main()
{
printf("%d", rand);
return 0;
}
运行以后,这段代码会出现这样的错误:
因为在头文件stdlib.h里面定义了rand,然后我们又自定义了一个rand,就会出现重定义这个现象
这个问题的危害就是在公司做大型项目的时候,每个人都会定义很多变量,当整合在一起的时候,就会出现很多的重定义现象,这个问题在C语言里面是无解的,只能一方去妥协。在C++里面就解决了这个问题,引入了命名空间。
二,命名空间的定义
命名空间的定义需要用到namespace关键字,后面跟上一对**{}**,{}里面包含了命名空间的成员。
命名空间里面可以包含变量,函数,类型:
namespace tanghuan
{
int a = 10;
int arr[10] = { 0 };
int sum(int a, int b)
{
return a + b;
}
struct N
{
int i = 0;
};
}
int main()
{
return 0;
}
命名空间不可以定义在局部作用域:
命名空间可以嵌套:
namespace tanghuan
{
namespace Test
{
int u = 9;
}
int a = 10;
int arr[10] = { 0 };
int sum(int a, int b)
{
return a + b;
}
struct N
{
int i = 0;
};
}
int main()
{
return 0;
}
三,同一个工程中允许存在多个相同名称的命名空间,编译器最后会将其合并成一个命名空间,不会报错:
但是不允许存在相同变量/函数/类型,否则会报错:
允许存在未命名的名称空间
#include <stdio.h>
namespace
{
int a = 10;
int arr[10] = { 0 };
int sum(int a, int b)
{
return a + b;
}
struct N
{
int i = 0;
};
}
int main()
{
printf("%d ", a);
}
这种命名空间没有名称,就不能使用using声明和using编译指令来使他在其他位置也可用,从某方面来看,他和全局变量相似,具有内部链接性,也就是不能在命名空间所属文件以外的地方使用该命名空间里面的成员。
一个命名空间的定义就相当于给其中的成员围上了栏杆,没有允许的话,任何人都不能访问其中的变量,不同命名空间里面即使是相同的变量名,但是本质是两个变量:
但是套上了不同命名空间的"牌子",编译器就能正确区别出他们啦。
四,命名空间的使用
先介绍一下:
- :: 叫做域作用限定符。
- using 也是属于C++的关键字。
命名空间的使用有三种方式:
用于测试的已经定义好的命名空间:
#include <stdio.h>
namespace tanghuan
{
int a = 10;
int arr[10] = { 0 };
int sum(int a, int b)
{
return a + b;
}
struct N
{
int i = 0;
};
}
加命名空间名称及作用域限定符
int main()
{
printf("%d\n", tanghuan::a);
return 0;
}
使用using将命名空间的某个成员引入(using声明)
using tanghuan::a;
int main()
{
printf("%d", a);
return 0;
}
使用“using namespace 命名空间名称 ”引入(using编译指令)
using namespace tanghuan;
int main()
{
printf("%d\n", a);
printf("%d", sum(1, 2));
return 0;
}
注意:
-
using声明和using编译指令可以使用在全局,此时全局展开,也可在局部使用,此时仅仅在局部有用:
-
using声明和using编译指令在局部使用的时候,和其他的局部变量一样,会覆盖全局的同名函数:
五,命名空间的使用建议
- 使用在已经命名的名称空间中声明的变量,而不是使用外部全局变量。
- 使用在已经命名的名称空间中声明的变量,而不是使用静态全局变量。
- 不要在头文件中使用using编译指令,首先,这样做掩盖了要让那些名称可用。另外,包含头h文件的顺序可能影响程序的行为。如果非要使用编译指令using,应该将其放在所有预处理编译指令#include之后。
- 导入名称时,首选将其作用域解析运算符或者using声明的方法。
- 对于using声明,首选将其作用域解析运算符设置为局部而不是全局。