使用namespace(命名空間)的正確方法

2021-06-08 13:35:28 字數 1748 閱讀 6610

命名空間(namespace)在c++中的作用非同一般。本文目的不在於闡述命名空間的語法,而在於演示命名空間的使用方法,或者說是使用命名空間的小竅門。

命名空間可以簡單的將一些命名(name)用另乙個命名打包封裝起來。比方說:

namespace net ;

}...

net::socket socket;經過這樣的封裝以後,如果在兩個庫(library)都實現了socket類,只要它們命名空間的名字不同,你就可以同時使用它們而沒有任何命名上的衝突。

但這樣做還是有問題:假如兩個公司都要寫乙個network庫,那麼當她們編寫**的時候都使用socket命名他們的類的可能性有多大?我猜是接近100%。

命名空間的名字最好是方便輸入的,就是說命名空間的名字最好別太長了,2-4個字元就可以了。抱著這樣的想法,那兩個公司把他們的命名空間叫做net的機會又是多大呢?5%還是10%?

不難看出,命名空間並沒有解決所有問題,它只是使發生命名衝突的機會相對小了而已。

有一種叫做「工業化長度」的方法(industrial strength solution),這種方法在命名namespace的時候使用長的唯一的名稱,而在程式裡使用短的別名。如此network庫就可能會是這個樣子:

namespace net_33843894 ;

}net_後面的數字是由乙個隨機數產生器產生的。為了以後描述方便,這裡我們假定上面的**是放在標頭檔案裡。

使用者使用我們的庫的時候,就要編寫他自己的標頭檔案,包含下面的內容:

#include

namespace net = net_33843894;他建立了乙個在本工程內有效的別名,用來代表提供給他的庫中的命名空間。如果名稱net已經被別的庫使用了,那麼他還可以另選乙個名字代替,例如:net2,sock,或者別的什麼。

這樣就萬事大吉了麼?還沒有。你還要做一件事:使你的庫用起來更簡單、更方便。在這個講究完美的社會裡,人們雙擊乙個安裝檔案後,你的庫在他們的開發環境裡就應該是可用的,接下來就是#include ,再接下來他們就可以去忙別的了。

然而,現在的情況是,使用者為了使用你的庫需要建立乙個他自己的標頭檔案,雖然這並沒有什麼大不了的,但不是每個使用者都能忍受這一點。解決的方法就是直接提供乙個合理的預設值,如果使用者覺得不合適也可以取消,所以,在你的標頭檔案裡使用預編譯選項,如下:

namespace net_33843894 ;

}#ifndef no_net_33843894_alias

namespace net = net_33843894;

#endif這樣我們就給命名空間的名字提供了乙個預設值,如果這個名字已經有人用了,那麼使用者可以定義乙個no_net_33843894_alias巨集,別名就會被取消。

不幸的是,即使是使用了短的別名net,當你使用socket類的方法不對的時候,在我所用過的編譯器中,沒有乙個能夠在錯誤提示資訊裡顯示的短的別名,而是仍然使用net_33843894::socket。讀起來有些費勁。

怎麼辦?看我的。

#ifdef no_net_33843894_alias

namespace net_33843894 ;

}#ifndef no_net_33843894_alias

namespace net_33843894 = net;

#endif如果沒有定義巨集no_net_33843894_alias, 就直接給命名空間起個短一點的名字,把別名弄長點就可以了。這樣,錯誤資訊讀起來就會順眼多了。

Namespace 命名空間

namespace 命名空間。命名空間是用來解決不同的類和函式擁有相同的名稱的問題。解決了命名衝突的問題。namespace gxg namespace gaoxiaoguang 使用方法 gxg a gxga gaoxiaoguang a gaoxiaoguanga gxg bfunction g...

命名空間namespace

對using namespace std 的解釋 所謂namespace,是指識別符號的各種可見範圍。c 標準程式庫中的所有識別符號都被定義於乙個名為std的namespace中。由於namespace的概念,使用c 標準程式庫的任何識別符號時,可以有三種選擇 1 直接指定識別符號。例如std os...

namespace 命名空間

在討論如何使用命名空間之前,必須了解 php 是如何知道要使用哪乙個命名空間中的元素的。可以將 php 命名空間與檔案系統作乙個簡單的模擬。在檔案系統中訪問乙個檔案有三種方式 相對檔名形式如foo.txt。它會被解析為 currentdirectory foo.txt,其中 currentdirec...