0.来由
- 由于最近要将代码里集成MQTT的clinet,我使用了Qt的版本—-QMQTT,这个版本使用两个重要的类Message,Frame。当我把代码添加进来进编译发现重定义的错误,引起来个错误的原因是我自己的工程里也有Message这个结构体,而且是来自于C语言的文件中,我的没有使用命名空间。
oops!!! 命名空间污染。
1、命名空间
在C语言中,没有命名空间的概念,那么C语言怎么处理命名污染呢?一般来说是通过将全局的实体的名字设计得很长来避免命名空间的污染。这种方法对于程序的编写与阅读都带来了麻烦。在C++中引入了命名空间的概念。
我们见得最多的是,在使用C++的标准输入输出时:
using namespace std;
cout<<"hello world";
这里就使用std这个命名空间。
1.1 命名空间的定义
//无名空间
namespace
{
int type;
class book
{
};
double qureyType();
} //无分号
无名空间相当于static的作用,其它作用域只在模块内。
//有名空间
namespace Library
{
int type;
class book
{
};
double qureyType();
} //无分号
2、命名空间的使用
2.0 直接使用命名空间的限定符
当一个文件中两个命名空间同名的结构,类,函数等都要使用时,用这种方法:
Library::book b = Library::book();
BookStore::book bb = BookStore::book();
2.1 using 声明
当一个文件中只使用了一个命名空间的对象时,使用这种方法:
using namespace Library;
book b = book();
using 的使用域是从using的声明开始,直到包含该using的声明的作用域的末尾,名字都可可见。
一般放在文件头部,当然也可以在函数体内使用,当放在头文件的头部时,则源文件也是可见的,当放在函数体内部是,则是函数体内部可见。
- 一般应避免使用这种方法,因为如次再次引入库时,很容易再次命名污染。
2.2 Qt 使用对象传信号时的定义
Q_DECLARE_METATYPE(Library::Book)
qRegisterMetaType<Library::Book>("Book");
3、 C++调用C时的命名空间定义
C语言是没有命名空间的,而我们的C++程序有很大的可能是要使用C的函数,结构等。一般我们会使用预编译的方法,如:
#ifdef __cplusplus
namespace Library {
extern "C" {
#endif
struct Message
{
};
#ifdef __cplusplus
}
}
#endif
总结
- 命名空间是可以是不连续的
命名空间可以在几个部分中定义,空间由综的分离部分的总和构成,可以分散在不同的文件中。 - 命名空间可以使用别名
- 命名空间可以嵌套,(见得比较少)