网站建设图片滑动代码,多平台推广,seo优化公司如何做,wordpress如何导入数据库目录搁这 什么是命名空间命名空间的作用如何定义命名空间命名空间的种类如何使用命名空间内的成员作用域限定符命名空间展开命名空间全部展开命名空间部分展开 总结 什么是命名空间
命名空间是一种用来避免命名冲突的机制#xff0c;它可以将一段代码的名称隔离开#xff0c… 目录搁这 什么是命名空间命名空间的作用如何定义命名空间命名空间的种类如何使用命名空间内的成员作用域限定符命名空间展开命名空间全部展开命名空间部分展开 总结 什么是命名空间
命名空间是一种用来避免命名冲突的机制它可以将一段代码的名称隔离开使其与其他代码的名称不冲突 命名空间的原理是将一个全局的作用域分成一个个命名空间每个命名空间是个单独的作用域同时若是在同一个作用域内可能出现的命名冲突也不会造成影响有效避免了命名空间的污染 命名空间的作用 在学习C语言的过程中我们知道有一个函数叫做rand函数该函数用于生成伪随机整数 #includestdio.h
int rand 10;
int main()
{printf(%d\n,rand);return 0;
}上面的代码在.c文件下的情况执行会得出什么结果
代码被运行成功且没有什么错误 但若是在包含rand函数所在的头文件为前提的结果是什么? 当包含了rand函数所在的头文件即报错 原因是在程序运行时计算机先会在局部寻找变量当局部内未找到时则回去全局找 在全局找时找到了两个 rand (一个为头文件内的rand函数一个为所创建的变量rand) 此时也不知该打印哪一个rand这就叫命名冲突 但在C中出现了一个新的概念叫做命名空间一般来说rand这类的函数都存放于C中标准库类型对象的命名空间std中
若是在编译器中执行这段代码结果是什么
#includeiostream//标准输入输出流头文件
using namespace std;//展开标准库命名空间stdnamespace Sweet{//设置命名空间且名为Sweetint rand 10;
}int main()
{cout rand endl;//打印randcout Sweet::rand endl;//打印Sweet中的rand(::符号为作用域限定符)return 0;
}打印出来的结果没有报错原因是在这里并没有发生命名冲突在这段代码中使用了 namespace Sweet{int rand 10;
}设置了一个名为Sweet的命名空间且在命名空间内声明变量rand在打印过程中就相当于虽然重名但是所在班级不同的学生 但此时的rand仍然处于全局空间中只是隐藏在名为Sweet的命名空间内 若是运行下面的代码则结果是什么 #includeiostreamusing namespace std;
namespace Sweet{int rand 10;
}
using namespace Sweet;
int main()
{cout rand endl;cout Sweet::randendl;return 0;
}为什么上面的代码运行时并没报错而这段代码报错了 如何定义命名空间
从上面可知命名空间的作用既然命名空间能够有效防止命名冲突那该如何定义命名空间 在定义命名空间时应该使用 namespace 修饰且在该修饰词后定义名字 并在其后跟**{ }** 在{ }内的元素即为该命名空间的成员 #includeiostreamusing namespace std;//展开std命名空间namespace A1 {//定义一个名为A1的命名空间int a 0;int b 20;//变量void Add()//函数{cout IsAddFunc1 endl;}struct TestNode//结构体{int test1;double test2;};
}namespace A2 {//定义一个名为A2的命名空间int a 10;int b 21;void Add(){cout IsAddFunc2 endl;}struct TestNode{int test3;double test4;};
}
int main()
{cout A1::b A1::b endl;//打印A1中的bcout A2::b A2::b endl;//打印A2中的bA1::Add();//调用A1中的Add函数A2::Add();//调用A2中的Add函数struct A1::TestNode AT1;//声明结构体变量struct A2::TestNode AT2;cout AT1 endl;//打印结构体变量地址cout AT2 endl;return 0;
}从该段代码可知命名空间内不仅可以声明定义变量还可以包含函数、类、typedef以及#define宏等等 命名空间的种类
在一般情况下命名空间还可以进行嵌套即可以在一个命名空间内嵌再嵌套命名空间,以此类推 #includeiostream
using namespace std;
namespace A1{int mi 0;int qi 5;namespace A2 {int qi 10;namespace A3 {int mi 25;}}
}
int main()
{cout A1::mi A1::mi endl;cout A1::qi A1::qi endl;cout A1::A2::qi A1::A2::qi endl;cout A1::A2::A3::mi A1::A2::A3::mi endl;return 0;
} 该处A1命名空间内嵌套着A2A2嵌套A3 注意 命名空间只能在全局范围定义 故上图的使用方法为错误方法 如何使用命名空间内的成员
既然命名空间可以防止发生命名冲突那放在命名空间的成员应该如何使用?
作用域限定符 在一般情况下若是想使用命名空间内的成员可以使用作用域限定符 ::(域解析操作符) #includeiostream
using namespace std;
namespace A1{int mi 0;int qi 5;namespace A2 {int qi 10;namespace A3 {int mi 25;}}
}
int main()
{cout A1::mi A1::mi endl;cout A1::qi A1::qi endl;cout A1::A2::qi A1::A2::qi endl;cout A1::A2::A3::mi A1::A2::A3::mi endl;return 0;
}该段代码即使用了作用域限定符 该符号的作用是通知编译器应从作用域限定符左侧的名字所示的作用域中寻找右侧那个名字即指定访问哪个名字空间的哪个成员。 命名空间展开
除了可以使用作用域限定符进行操作以外还可以将命名空间展开同时命名空间展开有两种 ①命名空间全部展开 ②命名空间部分展开 命名空间全部展开 命名空间全部展开需要使用
cpp using namespace xxx; 进行修饰
#includeiostream
using namespace std;
int main()
{coutusing namespace stdendl;return 0;
}如上代码将标准库中的std命名空间展开即可以在不受作作用域限定符的限制使用std命名空间内的cout与endl 但若是将命名空间全部展开则也有一些麻烦 例如 该处将两个命名空间都进行了展开导致程序在运行中从全局范围中找到了两个rand从而导致的“悲剧” 故一般情况下在项目中不支持以命名空间全部展开的方式使用命名空间内的成员 命名空间部分展开
除了命名空间全部展开以外还有一种方式即相对的进行命名空间部分展开 using XXX :: xxx;以该方式将命名空间中的部分分支进行展开即可以在不全部展开以及不使用作用域限定符的情况下使用命名空间内的成员 #includeiostreamusing std::cout;//进行命名空间部分展开将std命名空间内的cout以及endl进行部分展开
using std::endl;//命名展开后可以在不影响该命名空间以内其他成员的情况下使用cout与endlint main()
{cout Hello World endl;//打印Hello Worldreturn 0;
}总结
①命名空间可以避免命名冲突问题 ②命名空间可以进行嵌套 ③命名空间必须在全局范围内定义不可再局部范围内定义 ④在使用命名空间内的成员时共有三种方法(作用域限定符、命名空间全部展开、命名空间部分展开)在一般练习中尽量不要进行全部展开