參考C++ Primer plus第五版
第九章
名稱空間(namespace)
可以解決什么問題:
很簡單的例子,比如說在使用多個廠商的類庫時,如果兩個庫都定義了名為List、Tree、Node這樣的類,但定義的方式不兼容,我們可能希望使用一個庫的List類,而使用另一個類庫的Tree類,這就導致了名稱的沖突,這種沖突被稱為名稱空間問題。
c++標準提供了名稱空間工具,可以更好的控制名稱的作用域。
先來看兩個概念:聲明區域、潛在作用域
聲明區域
可以在其中進行聲明的區域,例如可以在函數外聲明全局變量,對于這種變量,其聲明區域為其聲明所在的文件,對于在函數中聲明的變量,其聲明區域為其聲明所在的代碼塊。
潛在作用域
變量的潛在作用域從聲明點開始到其聲明區域的結尾。因此潛在作用域比聲明區域小,這是由于變量必須定義后才能使用。
變量并非在其潛在作用域內的任何位置都是可見的
image.png
Header.h
#ifndef Header_h
#define Header_h
#endif /* Header_h */
namespace Jake {
double pail;
void fetch();
int pal;
struct Well{
};
}
Header2.h
#ifndef Header2_h
#define Header2_h
#endif /* Header2_h */
namespace Jill {
void bucket(double n)
{
};
double fetch;
int pal;
struct Hill{
};
}
main.cpp
#include <iostream>
#include <stdio.h>
#include "Header.h"
#include "Header2.h"
int main(int argc, const char * argv[]) {
Jill::fetch=234;
Jake::fetch();
return 0;
}
另外名稱空間是開發的,即可以把名稱加入到已有的名稱空間中,也可以利用名稱空間為聲明的函數提供函數代碼
#include <iostream>
#include <stdio.h>
#include "Header.h"
#include "Header2.h"
namespace Jake {
int age;//為Jake namespace添加成員變量age
void fetch()//為Jake中的方法fetch添加函數體
{
printf("%s\n","Jake");
}
}
int main(int argc, const char * argv[]) {
Jill::fetch=234;
Jake::fetch();
return 0;
}
作用域解析符(::)
未被裝飾的名稱(如pail)被稱為未限定的名稱,包含名稱空間的名稱(如Jack::pail)被稱為限定的名稱。
using聲明和using編譯指令
using聲明:using Jill::fetch;
using編譯指令:using namespace Jill;
using 聲明使特定的操作符可用,using編譯指令使整個名稱空間可用
using聲明將特定的名稱添加到它所屬的聲明區域中,如果在main函數中使用using聲明 Jill::fetch將fetch添加到main()定義的聲明區域中,完成該聲明后便可以使用名稱fetch代替Jill::fetch
看代碼演示:
#include <iostream>
#include <stdio.h>
#include "Header.h"
#include "Header2.h"
int fetch;
int main(int argc, const char * argv[]) {
using Jill::fetch;
fetch=234;
::fetch=678;
printf("外面定義的fetch=%d,Jill中的fetch=%f\n",::fetch,fetch);
return 0;
}
image.png
image.png
image.png
using聲明與using編譯指令比較
使用using聲明
image.png
使用using編譯指令
image.png
image.png
namespace的其他特性
image.png