1. 程式人生 > >C++11新特性(86)-類型別的union成員(2)

C++11新特性(86)-類型別的union成員(2)

經過一番準備,我們進入正題。

 

類型別的union成員

C++的早期版本不允許union的成員是定義了建構函式或拷貝控制成員的類型別成員,C++11中取消了這個限制。但是也別高興得太早,因為這類union在發生涉及到類型別成員的值轉換時需要根據需求呼叫相關類成員的建構函式或解構函式。

 

假設我們有下面的StrValue類。引入這個類的目的是為了在物件操作時可以輸出日誌資訊。

程式碼有點長,慢慢看。這個類主要用於儲存字串。它包含3個建構函式,一個解構函式,一個賦值運算子。另外還過載了輸出運算子用於輸出內部的字串。C++11以後,允許把這個類作為下面union的成員。

為union引入類型別成員後,帶來了一個麻煩:在切換union有效成員的時候需要恰當的呼叫類成員的建構函式和解構函式。例如下面的程式碼:

最初有效的是ival成員,接下來希望儲存字串時需要使用定位new方式呼叫建構函式;反之,當我們希望再次使用ival成員的時候,又需要呼叫sval成員的解構函式。如果不這樣做,就無法保證記憶體管理正常進行。

 

使用類管理union成員

 

解決上述問題的方法就是C++最基本的特徵:封裝。我們可以將union封裝到另一個類中。

我們分類說明SmartUnion類的各個成員。

 

兩個資料成員,一個是用於儲存型別資訊的ut,通過這個成員,SmartUnion類可以判斷當前是哪個成員有效;另一個是包含整數和StrValue成員的匿名union,它是主角。

 

三個建構函式,一個預設建構函式,另外兩個分別接受整數和字串輸入。注意這裡的SmartUnion只是示例程式碼,真正使用的時候可能還要新增不少內容,例如拷貝建構函式。

 

三個賦值運算子,分別提供從整數,StrValue物件和SmartUnion物件賦值的功能。

 

經過一番準備之後,用法就簡單了:

 

作者一句話

本文內容偏多,希望各位可以參照C++Primer第五版 19.6節的內容加深理解。

 

程式碼下載連結

https://github.com/xueweiguo/OOThinking/blob/master/20180612%20ClassUnionMember.cpp

 

 

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

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