第17章 用于大型程序的工具(7)
17.2 命名空间
命名空间(namespace)为防止名字冲突提供了更加可控的机制,命名空间能够划分全局命名空间,这样使用独立开发的库就更加容易了。一个命名空间是一个作用域,通过在命名空间内部定义库中的名字,库的作者(以及用户)可以避免全局名字固有的限制。
17.2.1 命名空间的定义
命名空间定义以关键字namespace开始,后接命名空间的名字。
namespace Anders
{
namespace NameSpace2
{
class Class1{
};
class Class2{
};
}
}
namespace Anders
{
namespace NameSpace1
{
class Class1{
};
class Class2{
};
}
}
namespace Anders
{
namespace NameSpace2
{
class Class1{
};
class Class2{
};
}
}
namespace Anders
{
namespace NameSpace1
{
class Class1{
};
class Class2{
};
}
}using namespace Anders::NameSpace1;
using namespace Anders::NameSpace2;
using namespace Anders::NameSpace1;
using namespace Anders::NameSpace2;像其他名字一样,命名空间的名字在定义该命名空间的作用域中必须是唯一的。命名空间可以在全局作用域或其他作用域内部定义,但不能在函数或类内部定义。
命名空间名字后面接着由花括号括住的一块声明和定义,可以在命名空间中放入可以出现在全局作用域的任意声明:类、变量(以及它们的初始化)、函数(以及它们的定义)、模板以及其他命名空间。
命名空间作用域不能以分号结束。
1. 每个命名空间是一个作用域
定义在命名空间中的实体称为命名空间成员。像任意作用域的情况一样,命名空间中的每个名字必须引用该命名空间中的唯一实体。因为不同命名空间引入不同作用域,所以不同命名空间可以具有同名成员。
在命名空间中定义的名字可以被命名空间中的其他成员直接访问,命名空间外部的代码必须指出名字定义在哪个命名空间中。
2. 从命名空间外部使用命名空间成员
using Anders::NameSpace1::Class1;
using Anders::NameSpace1::Class1;3. 命名空间可以是不连续的
与其他作用域不同,命名空间可以在几个部分中定义。命名空间由它的分离定义部分的总和构成,命名空间是累积的。一个命名空间的分离部分可以分散在多个文件中,在不同文本文件中的命名空间定义也是累积的。当然,名字只在声明名字的文件中可见,这一常规限制继续应用,所以,如果命名空间的一个部分需要定义在另一文件中的名字,仍然必须声明该名字。
//Namespace1.h
#ifndef NAMESPACE1_H
#define NAMESPACE1_H
namespace Andersoft
{
namespace Namespace1
{
class Class1{};
}
}
#endif
//Namespace1.h
#ifndef NAMESPACE1_H
#define NAMESPACE1_H
namespace Andersoft
{
namespace Namespace1
{
class Class1{};
}
}
#endif//Namespace2.h
#ifndef NAMESPACE2_H
#define NAMESPACE2_H
namespace Andersoft
{
namespace Namespace2
{
class Class1{};
}
}
#endif
//Namespace2.h
#ifndef NAMESPACE2_H
#define NAMESPACE2_H
namespace Andersoft
{
namespace Namespace2
{
class Class1{};
}
}
#endif4. 接口与实现的分离
命名空间定义可以不连续意味着,可以用分离的接口文件与实现文件构成命名空间,因此可以用与管理自己的类或函数定义相同的方法来组织命名空间:
(1)定义类的命名空间成员,以及作为类接口的一部分的函数声明或对象声明,可以放在头文件中,使用命名空间成员的文件可以包含这些头文件。
(2)命名空间成员的定义可以放在单独的源文件中。
//Namespace2.h
#ifndef NAMESPACE2_H
#define NAMESPACE2_H
namespace Andersoft
{
namespace Namespace2
{
class Class1;
}
}
#endif
//Namespace2.h
#ifndef NAMESPACE2_H
#define NAMESPACE2_H
namespace Andersoft
{
namespace Namespace2
{
class Class1;
}
}
#endif//Namespace2.cpp
#include "stdafx.h"
#include "NameSpace2.h"
namespace Andersoft
{
namespace Namespace2
{
class Class1{};
}
}
//Namespace2.cpp
#include "stdafx.h"
#include "NameSpace2.h"
namespace Andersoft
{
namespace Namespace2
{
class Class1{};
}
}按这种方式组织命名空间,也满足了不同实体(非内联函数、静态数据成员、变量等)只能在一个程序中定义一次的要求,这个要求同样适用于命名空间中定义的名字。通过将接口和实现相分离,可以保证函数和其他我们需要的名字只定义一次,但相同的声明可以在任何使用该实体的地方见到。
定义多个不相关类型的命名空间应该使用分离的文件,表示该命名空间定义的每个类型。
//Namespace2.h
#ifndef NAMESPACE2_H
#define NAMESPACE2_H
namespace Andersoft
{
namespace Namespace2
{
class Class1;
class Class2;
}
}
#endif
//Namespace2.h
#ifndef NAMESPACE2_H
#define NAMESPACE2_H
namespace Andersoft
{
namespace Namespace2
{
class Class1;
class Class2;
}
}
#endif//Class1.cpp
#include "stdafx.h"
#include "NameSpace2.h"
namespace Andersoft
{
namespace Namespace2
{
class Class1{};
}
}
//Class1.cpp
#include "stdafx.h"
#include "NameSpace2.h"
namespace Andersoft
{
namespace Namespace2
{
class Class1{};
}
}//Class2.cpp
#include "stdafx.h"
#include "NameSpace2.h"
namespace Andersoft
{
namespace Namespace2
{
class Class2{};
}
}
摘自 xufei96的专栏
补充:软件开发 , C++ ,