想做网站多少钱,网站建设的税收编码,石家庄企业名录大全,品牌营销做得好的品牌有哪些文章目录 前言1. namespace 的价值2. namespace 的定义3. 命名空间的本质4. 嵌套的命名空间5. 命名空间的使用6. using 指令7. 补充结语 前言
假设这样一种情况#xff0c;当一个班上有两个名叫 Zara 的学生时#xff0c;为了明确区分它们#xff0c;我们在使用名字之外当一个班上有两个名叫 Zara 的学生时为了明确区分它们我们在使用名字之外不得不使用一些额外的信息比如他们的家庭住址或者他们父母的名字等等。
同样的情况也出现在 C 应用程序中。例如您可能会写一个名为 xyz() 的函数在另一个可用的库中也存在一个相同的函数 xyz()。这样编译器就无法判断您所使用的是哪一个 xyz() 函数。
我们举一个计算机系统中的例子一个文件夹(目录)中可以包含多个文件夹每个文件夹中不能有相同的文件名但不同文件夹中的文件可以重名。 1. namespace 的价值
在C/C中变量、函数和后面要学到的类都是大量存在的这些变量、函数和类的名称将都存在于全局作用域中可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化以避免命名冲突或名字污染namespace关键字的出现就是针对这种问题的。
c语言项目类似下面程序这样的命名冲突是普遍存在的问题C引入了命名空间这个概念就是专门用于解决这种问题它可作为附加信息来区分不同库中相同名称的函数、类、变量等。使用了命名空间即定义了上下文。本质上命名空间就是定义了一个范围。
#include stdio.h
#include stdlib.h
int rand 10;
int main()
{// 编译报错error C2365: “rand”: 重定义以前的定义是“函数”printf(%d\n, rand);return 0;
}2. namespace 的定义
命名空间的定义使用关键字 namespace后跟命名空间的名称然后接⼀对{}即可{}中即为命名空间的成员。命名空间中可以定义变量/函数/类型等。如下所示
namespace namespace_name {// 代码声明
}为了调用带有命名空间的函数或变量需要在前面加上命名空间的名称如下所示 name::code; // code 可以是变量或函数这里面的::是作用域限定符。
让我们来看看命名空间如何为变量或函数等实体定义范围
#include iostream
using namespace std;// 第一个命名空间
namespace first_space{void func(){cout Inside first_space endl;}
}
// 第二个命名空间
namespace second_space{void func(){cout Inside second_space endl;}
}
int main ()
{// 调用第一个命名空间中的函数first_space::func();// 调用第二个命名空间中的函数second_space::func(); return 0;
}当上面的代码被编译和执行时它会产生下列结果
Inside first_space
Inside second_space3. 命名空间的本质
namespace本质是定义出一个域这个域跟全局域各自独立不同的域可以定义同名变量所以下面的rand不在冲突了。
#include stdio.h
#include stdlib.h
// 1. 一般的命名空间定义
// xhh是命名空间的名字一般开发中是用项目名字做命名空间名。
namespace xhh
{// 命名空间中可以定义变量/函数/类型int rand 10;int Add(int left, int right){return left right;}struct Node{struct Node* next;int val;};
}
int main()
{// 这⾥默认是访问的是全局的rand函数指针printf(%p\n, rand);// 这⾥指定xhh命名空间中的randprintf(%d\n, xhh::rand);return 0;
}C中域有函数局部域全局域命名空间域类域域影响的是编译时语法查找一个变量/函数/类型出处(声明或定义)的逻辑所有有了域隔离名字冲突就解决了。局部域和全局域除了会影响编译查找逻辑还会影响变量的生命周期命名空间域和类域不影响变量生命周期。 4. 嵌套的命名空间
namespace 只能定义在全局当然还可以嵌套定义示例如下。
//2. 命名空间可以嵌套
namespace bit
{namespace pig{int rand 1;int Add(int left, int right){return left right;}}namespace bird{int rand 2;int Add(int left, int right){return (left right) * 10;}}
}
int main()
{printf(%d\n, bit::pig::rand);printf(%d\n, bit::bird::rand);printf(%d\n, bit::pig::Add(1, 2));printf(%d\n, bit::bird::Add(1, 2));return 0;
}5. 命名空间的使用
编译查找一个变量的声明/定义时默认只会在局部或者全局查找不会到命名空间里面去查找。所以下面程序会编译报错。
#includestdio.h
namespace N
{int a 0;int b 1;
}
int main()
{// 编译报错error C2065: “a”: 未声明的标识符printf(%d\n, a);return 0;
}所以声明了命名空间之后如果在命名空间外部访问命名空间内部的成员需要在成员名前面加上 命名空间::示例如下。
// 指定命名空间访问
int main()
{printf(%d\n, N::a);return 0;
}6. using 指令
有没有什么比较方便的方法能让我们直接通过成员名访问命名空间内的成员呢答案是肯定的。我们可以使用 using 指令。
using 指令有如下两种形式
using 命名空间::成员名; 这条指令可以让我们省略某个成员名前的命名空间直接通过成员名访问成员相当于将这个成员导入了当前的作用域。 // using将命名空间中某个成员展开
using N::b;
int main()
{printf(%d\n, N::a);printf(%d\n, b);return 0;
}using namespace 命名空间; 这条指令可以直接通过成员名访问命名空间中的任何成员相当于将这个命名空间的所有成员导入了当前的作用域。 // 展开命名空间中全部成员
using namespce N;
int main()
{printf(%d\n, a);printf(%d\n, b);return 0;
}因此如果执行了 using namespace N;就会将 N 中的所有名字都会引入到全局命名空间当中。 注意 指定命名空间访问。项目中推荐这种方式。 using将命名空间中某个成员展开。项目中经常访问的不存在冲突的成员推荐这种方式。 展开命名空间中全部成员由于这种方式会将此命名空间中的所有名字引入因此如果声明了与其中重名的变量或函数就可能会因为命名冲突而导致编译错误。所以说项目中不推荐冲突风险很大日常小练习程序为了方便推荐使用。 7. 补充 项目工程中多文件中定义的同名namespace会认为是一个namespace不会冲突。 C标准库都放在一个叫std(standard)的命名空间中。
结语
今天的分享到这里就结束啦如果觉得文章还不错的话可以三连支持一下。
也可以点点关注避免以后找不到我哦
Crossoads主页还有很多有趣的文章欢迎小伙伴们前去点评您的支持就是作者前进的动力