C++ 命名空间
C++ 命名空间
命名空间用于解决合作开发时的名字冲突问题。
1、namespace
关键字
用于定义命名空间。
//定义命名空间 namespace name{ //variables, functions, classes } //使用命名空间内的成员 name::成员名;
name
是命名空间的名字,它里面可以包含变量、函数、类、typedef、#define 等。
::
是作用域运算符,在C++中用来指明要使用的命名空间。
-
只能在全局范围内定义,不能在函数内部定义。
-
命名空间可嵌套定义(一个
namespace
嵌套一个namespace
,使用时连续使用作用域解析符::
) -
如果include了
using
了某个命名空间的其他文件到当前文件,则using
的效果会被传播到当前文件。 -
如果将一个命名空间拆分到多个文件中来写,则如下:
// name.h namespace A{ extern int x; void func(); } // name.cpp namespace A{ int x = 2; void func(){std::cout<<"haha";} } -
命名空间是开放的,即可以随时把新的成员加入已有的命名空间中
namespace A{ int a = 10; namespace B{ int b = 11; } } namespace A{//往A中加入一个func void func(){ cout << "hello namespace!" << endl; } } void test(){ cout << "A::a : " << A::a << endl; cout << "A::B::b :" << A::B::b << endl; A::func(); } -
命名空间内的成员声明和定义可以分离(命名空间体内声明函数签名,命名空间外用
::
定义) -
无名命名空间:无名命名空间中的标识符只能在本文件内访问,相当于给这个标识符加上了
static
,使得其可以作为内部连接namespace{ int a = 10; void func(){ cout << "hello namespace" << endl; } } -
全局命名空间:定义变量、函数或其他标识符时,如果没有放置在任何命名空间中,则属于全局命名空间。全局命名空间中的标识符可以被整个程序中的任何地方访问。使用
::
来强制使用全局命名空间:// 全局命名空间 int x = 5; // 一个普通命名空间 namespace MyNamespace { int x = 10; } int main() { // 使用全局命名空间中的x std::cout << "Global x: " << ::x << std::endl; // 使用普通命名空间中的x std::cout << "Namespace x: " << MyNamespace::x << std::endl; } -
命名空间可以起别名
namespace veryLongName{ int a = 10; void func(){ cout << "hello namespace" << endl; } } void test(){ namespace shortName = veryLongName; // 起别名 cout << "veryLongName::a : " << shortName::a << endl; veryLongName::func(); shortName::func(); }
关于嵌套命名空间的补充
1.什么是嵌套命名空间?
嵌套命名空间就是在命名空间里面在定义其它的命名空间,就像是俄罗斯套娃。
namespace np1 { namespace np2 { namespace np3 {} } // namespace np2 ... } // namespace np1
2.实验
2.1 外部引用嵌套命名空间内的符号
情况一
#include <iostream> using namespace std; namespace np1 { namespace np2 { void func2() { cout << "np1::np2::func2" << endl; } } // namespace np2 void func1() { cout << "np1::func1" << endl; } } // namespace np1 int main() { np1::func1(); np1::np2::func2(); return 0; }
实验结果:
表明嵌套命名空间的引用是符合namespace语法的,没有特殊之处。
情况二
using namespace np1; int main() { func1(); np2::func2(); return 0; }
输出结果一样。
2.2 命名空间内容不同层次间符号的引用
情况一:第一层调用第二层
#include <iostream> using namespace std; namespace np1 { namespace np2 { void func2() { cout << "np1::np2::func2" << endl; } } // namespace np2 void func1() { np2::func2(); } } // namespace np1 int main() { np1::func1(); return 0; }
实验结果:
表明在命名空间内部的不同层次符号引用依然遵循namespace语法。
情况二:第二层调用第一层
#include <iostream> using namespace std; namespace np1 { void func1() { cout << "np1::func1" << endl; } namespace np2 { void func2() { func1(); // np1::func1(); } } // namespace np2 } // namespace np1 int main() { np1::np2::func2(); return 0; }
实验结果:
表明np1相对于np2来说,是默认命名空间。
情况三:第二层调用第一层,但是第一层和第二层存在相同的符号
#include <iostream> using namespace std; namespace np1 { void func1() { cout << "np1::func1" << endl; } namespace np2 { void func1() { cout << "np1::np2::func1" << endl; } void func2() { func1(); } } // namespace np2 } // namespace np1 int main() { np1::np2::func2(); return 0; }
实验结果:
表明np2优先会调用自己内部的符号。正如一个函数的内部,它会优先调用自己的局部变量,接着才考虑寻找外部变量。
2、using
关键字
用于声明命名空间中的单个成员或声明整个命名空间,使得指定的标识符可用。
//声明单个成员 using name::成员名; //声明整个命名空间 using namespace name;
(1)一个cpp文件里可以使用多个using
语句。
using namespace A; using namespace B;
如果编译器发现某个名字在多个缺省的名字空间都出现过,会显示编译错误,这时就必须使用::
操作符强行指定名字空间了。
例如你自己定义了一个变量,名字也叫cout
。这时你就必须指定是std::cout
还是::cout
(2)using声明碰到函数重载:如果命名空间包含一组用相同名字重载的函数,using声明就声明了这个重载函数的所有集合。
namespace A{ void func(){} void func(int x){} int func(int x,int y){} } void test(){ using A::func; //所有的func均可用 func(); func(10); func(10, 20); }
本文作者:3的4次方
本文链接:https://www.cnblogs.com/3to4/p/17949811
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步