2017-03-28 64 views
3

我在某處讀取了一段用於定義三維座標的代碼。於是,他們用xy & z協調這樣如下:使用聯合的結構和相同大小的數組有什麼優勢

union 
    { 
     struct 
     { 
      float x, y, z; 
     }; 
     float _v[3]; 
    }; 

我的問題是,爲什麼union這裏需要也是爲什麼要使用結構與陣列的優勢在哪裏?

+6

無,除非你想未定義行爲或需要調查和檢查的編譯器擴展。 _「...未定義的行爲可以從最近未編寫的工會成員中讀取。」_參見:http://en.cppreference.com/w/cpp/language/union –

+5

聯合使結構陣列佔據相同的空間。試圖讓'x'成爲'_v [0]'的同義詞是一種破解。它假定結構中沒有填充,並且會在添加它們的系統上突破。 – StoryTeller

+0

這將是一個非常奇怪的編譯器,將不同地填充結構和數組。雖然它在C++語言標準方面是未定義的行爲,但它通常在編譯器將生成的代碼方面理解得很好。雖然語言純粹主義者討厭它,但編寫嵌入代碼的人通常依賴於這種事情。 –

回答

2

重要注意事項:此構造會導致未定義的行爲。接下來是對作者意圖的描述,不幸的是,許多編譯器正是將作者期望的行爲翻譯成了,這反過來又導致了類似的代碼氾濫。

union構造不是真的需要在這裏:作者使用它的方便。他們之所以把union沒有給自己一個語法來訪問xy,並且z兩種不同的方式:

  • 通過指定字段名 - 也就是說,coord.xcoord.y,或coord.z,或
  • 通過指定字段索引 - 即coord._v[0],coord._v[1]coord._v[2]

,提供類似的功能,而不會在不確定的行爲的一種方法是使用內聯成員函數爲您的訪問:

struct Vector3D { 
    int v[3]; 
    int& x() { return v[0]; } 
    int& y() { return v[1]; } 
    int& z() { return v[2]; } 
}; 

int main() { 
    Vector3D coord; 
    coord.v[0] = 5; 
    cout << coord.x() << endl; 
    coord.y() = 10; 
    cout << coord.v[1] << endl; 
    return 0; 
} 

Demo.

1

這種方式可以解決三維座標爲結構..

foo.x; 
foo.y; // etc 

但它也可以讓你獲得3個變量作爲數組,而佔據相同的空間(這是該計劃至少)訪問它們像..

foo._v[0] // x, etc 

無論如何,這就是主意。但是,當結構在成員之間有任何填充的時候,你的數組將會錯位,並且你最終會讀取垃圾值。長話短說,這段代碼有未定義的行爲,一個不應該使用的不好的實現。

4

正如吉爾·貝茨說,這樣你可以(也許)訪問的3個座標都爲x, y, zv[0], v[1], v[2] 但根據@Richard Critten的評論,這實際上是一個UB。

你可以像這樣得到同樣的結果在一個「安全」的方式:

struct Coordinates 
{ 
    Coordinates():x(v[0]), y(v[1]), z(v[2]) 
    { 
    } 

    int v[3]; 
    int& x; 
    int& y; 
    int& z; 
}; 

即使用引用數組值和構造函數初始化它們

這個結構的尺寸會比你在OP表示雙方的結合顯然是不同的(大)

+0

「這個結構的大小將明顯不同(更大)」這是一個相當輕描淡寫的問題:大小將*顯着*更大。實際上,在考慮內存對齊的填充效果之前,您至少要花費兩倍的內存,這非常昂貴。在ideone上,大小從12個字節增長到40個字節([demo](http://ideone.com/oAOwAC))。 – dasblinkenlight

相關問題