C++中引入了名字空间(namespace
)的概念。名字空间有两方面的用途,一是将逻辑上相关的元素组织在一起,更重要的一点是解决函数和变量重名问题。
命名空间的定义方式如下:
namespace 名字空间名称
{
//声明和定义
}
当在一个名字空间内访问另一个名字空间的函数、变量等时,需要额外添加限定词形如“名字空间名称::变量或函数名”。访问同一个名字空间的函数不需要限定符。
/****************************************
* using_namespace_1.cpp *
* *
* C++名字空间的使用 *
****************************************/
#include <iostream>
namespace namespace1
{
int x = 5;
}
namespace namespace2
{
int y = 10;
void PrintY()
{
std::cout<<"y="<<y<<std::endl;
}
void PrintX()
{
std::cout<<"x="<<namespace1::x<<std::endl;
}
}
int main()
{
namespace2::PrintX();
namespace2::PrintY();
return 0;
}
当在一个代码块中需要多次使用同一个限定符或使用多个限定符时,可以在变量或函数等元素使用之前,使用名字空间声明语句将名字空间中的所有元素或名字空间中特定的元素引入到本命名空间。相应地,名字空间声明语句包含两类,一类是引入某个命名空间中特定的元素,
using 名字空间名称::特定元素名称;
一类是引入某个命名空间中所有的元素,
using namespace 名字空间名称;
/****************************************
* using_namespace_2.cpp *
* *
* C++名字空间的使用 *
****************************************/
#include <iostream>
namespace namespace1
{
int x = 5;
int y = 15;
}
namespace namespace2
{
int z = 10;
int m = 20;
}
namespace namespace3
{
using namespace1::x;
using namespace1::y;
void PrintX()
{
std::cout<<"x="<<x<<std::endl;
}
void PrintY()
{
std::cout<<"y="<<y<<std::endl;
}
}
namespace namespace4
{
using namespace namespace2;
void PrintZ()
{
std::cout<<"Z="<<z<<std::endl;
}
void PrintM()
{
std::cout<<"m="<<m<<std::endl;
}
}
int main()
{
using namespace3::PrintX;
PrintX();
using namespace namespace4;
PrintZ();
PrintM();
return 0;
}
可以定义没有名称的名字空间,称为无名名字空间
namespace
{
//声明
}
无名名字空间中声明的元素可以在本编译单位(预处理后形成的定义文件)中可用。不同编译单位的名字空间互不相同。
/****************************************
* using_namespace_3.cpp *
* *
* C++名字空间的使用 *
****************************************/
#include <iostream>
namespace
{
int x = 5;
}
namespace
{
int y = 10;
void PrintY()
{
std::cout<<"y="<<y<<std::endl;
}
void PrintX()
{
std::cout<<"x="<<x<<std::endl;
}
}
int main()
{
PrintX();
PrintY();
return 0;
}
当使用某个名字空间中声明的类型的元素作为函数的参数时,如果在该编译单元中找不到该函数的定义,则自动去该类型声明所在的命名空间中去查找相应函数。如果该函数是类的成
员函数,则优先从该类及其基类的成员函数中选择。
/****************************************
* using_namespace_4.cpp *
* *
* C++名字空间的使用 *
****************************************/
#include <iostream>
namespace namespace1
{
struct Test
{
int x;
int y;
};
void Print(Test test)
{
std::cout<<"x = "<<test.x<<std::endl;
std::cout<<"y = "<<test.y<<std::endl;
}
}
namespace namespace2
{
void PrintX(namespace1::Test test)
{
/*没有显式引入Print,但由于参数类型是*
*namespace1的,所以可以查到该函数 */
Print(test);
}
}
int main()
{
namespace1::Test a = {10,20};
namespace2::PrintX(a);
return 0;
}
可以为名字空间指定别名,使用以下命令:
namespace 新名字空间名称 = 旧名字空间名称;
名字空间别名可以用作原名字空间中的限定符,但不能通过该别名来扩展名字空间(添加新的声明或定义等)。
/****************************************
* using_namespace_5.cpp *
* *
* C++名字空间的使用 *
****************************************/
#include <iostream>
namespace namespace1
{
int x = 5;
}
namespace namespace2
{
int y = 10;
void PrintY()
{
std::cout<<"y="<<y<<std::endl;
}
void PrintX()
{
std::cout<<"x="<<namespace1::x<<std::endl;
}
}
int main()
{
namespace NNN = namespace2;
NNN::PrintX();
NNN::PrintY();
return 0;
}
参考文献
1.Bjarne Stroustrup著,裘宗燕译. C++程序设计语言(特别版).机械工业出版社 2009.