C++核心準則C.181:避免使用"暴露的"聯合體

C++核心準則C.181:避免使用

C.181: Avoid "naked" unions

C.181:避免使用"暴露的"聯合體

Reason(原因)

A naked union is a union without an associated indicator which member (if any) it holds, so that the programmer has to keep track. Naked unions are a source of type errors.

暴露的聯合體指的是不包含用來表示哪個(如果存在的話)成員有效的標誌的聯合體,程序員必須對數據流保持跟蹤。暴露狀態的聯合體是錯誤的源頭之一。

Example, bad(反面示例)

<code>union Value {
int x;
double d;
};

Value v;
v.d = 987.654; // v holds a double/<code>

So far, so good, but we can easily misuse the union:

到目前為止還好,但是我們會很容易地錯誤使用這個聯合體:

<code>cout << v.x << '\\n';    // BAD, undefined behavior: v holds a double, but we read it as an int/<code>

Note that the type error happened without any explicit cast. When we tested that program the last value printed was 1683627180 which is the integer value for the bit pattern for 987.654. What we have here is an "invisible" type error that happens to give a result that could easily look innocent.

注意類型錯誤是在沒有任何顯式類型轉換的情況下發生的。但我們測試這段程序的時候,輸出的最後一個值是1863627180,它是987.654的二進制對應的整數值。我們在這裡遇到的是一個"不可見"類型錯誤,它恰巧給出一個很容易被判斷為沒有問題的結果。

And, talking about "invisible", this code produced no output:

另外,談到"不可見",下面的代碼不會產生輸出:

<code>v.x = 123;
cout << v.d << '\\n'; // BAD: undefined behavior/<code>

Alternative(可選項)

Wrap a union in a class together with a type field.

將聯合體和一個類型字段封裝為一個類。

The C++17 variant type (found in <variant>) does that for you:/<variant>

C++17的variant類型(可以在<variant>中找到)可以為你做同樣的事:/<variant>

<code>variant v;
v = 123; // v holds an int
int x = get(v);
v = 123.456; // v holds a double
w = get<double>(v);/<double>
/<code>

Enforcement(實施建議)

???

原文鏈接:

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c181-avoid-naked-unions


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

面向對象開發,面向對象思考!


分享到:


相關文章: