1. 程式人生 > >C++11新特性(79)-內聯名稱空間(inline namespace)

C++11新特性(79)-內聯名稱空間(inline namespace)

名稱空間簡介

隨著軟體開發規模的擴大,類名,函式名重複的可能性也越來越大。最樸素的解決辦法就是改名,這種方法在向已經存在的類庫中新增程式碼時問題不大,但是如果是將兩個從未謀面的程式碼庫結合在一起時就不再適用了。

C++解決這個問題的辦法就是引入名稱空間。假設有下面兩個名稱空間:

程式碼中分別定義了std_namespace1和lstd_namespace2兩個名稱空間。在兩個名稱空間內分別定義了相同名稱的Normal類。這兩個類的成員函式是否一樣其實不重要,這裡姑且使用了相同的名稱。

有了名稱空間以後,使用【名稱空間名稱::類名】的方式,就可以對這兩個同名的Normal類加以區分了。

如果使用using語句,可以讓某個名稱空間的內容釋放出來,就好像它們都存在與外層名稱空間一樣。

這種方法的一個弊端就是有可能發生類名重複的情況,這時就需要程式設計師來小心控制了。

 

內聯名稱空間

C++11中引入了內聯名稱空間(inline namespace),它的特點就是不需要使用using語句就可以直接在外層名稱空間使用該名稱空間內部的內容,而且無需使用名稱空間字首。先看程式碼:

內聯名稱空間的宣告方法就是在原來的宣告語法前面增加inline關鍵字。除此之外上面程式碼還有以下特點:

  1. 兩處宣告的名稱空間同名,它們同屬一個名稱空間。這是C++名稱空間從來就有的特性。

  2. 第一次宣告名稱空間時使用了inline關鍵字,這叫顯式內聯;第二次沒有使用inline關鍵字,但是由於第一次已經聲明瞭inline,這裡宣告的還是內聯名稱空間。這種情況成為隱式內聯。

內聯名稱空間宣告之後,就可以在外層名稱空間不適用字首而直接使用它們了。

上述程式碼中test_inline_namespace處在linline_namespace1的外層,所以可以直接使用Inline1和Inline2。test_inline_namespace2處在更外層,這時也只是需要使用外層名稱空間inline_test字首即可。

看起來inline_namespace就像不存在一樣。

 

嚴肅的問題

前面提到內聯名稱空間就像不存在一樣,那麼就產生了一個嚴肅的問題:它有什麼用?為了回答這個問題,我們舉一個更加接近實際開發的例子。假設有如下類庫程式碼:

很簡單的類,當然使用這些類的程式碼也同樣簡單:

到這裡為止算是鋪墊,接下來才是重點:假設我們隊類庫進行了升級,同時又希望:

  1. 使用者程式碼不受影響,除非使用者自己想改。

  2. 可以自由使用新類庫的功能

  3. 如果有需要仍然可以使用原來的類庫

解決方法當然是使用內聯名稱空間。首先是對類庫進行處理:

程式碼中為每個版本的類庫定義了名稱空間,同時將最新版本定義為內聯名稱空間。有了這樣的準備之後,使用者程式碼可以是下面這樣:

使用最新類庫的時候,就好像沒有定義過名稱空間一樣;如果實在是需要原來的類庫,可以通用版本字首加類名的方式。

還有一點很重要:由於隱式內聯語法的存在,將來出現ver3的時候,只要將唯一的一個inline關鍵字移動到第一次出現的ver3定義之前就可以了!

 

作者一句話

內聯名稱空間的應用場景相當有限,但是一旦用上了,還是比較神奇的。

示例程式碼下載地址

https://github.com/xueweiguo/OOThinking/blob/master/20180524%20InlineNamespace.cpp

 

覺得本文有幫助?請分享給更多人。

閱讀更多更新文章,請掃描下面二維碼,關注微信公眾號【面向物件思考】