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的專欄