2010-03-17 32 views
2

我正在與圖書館合作,我必須與工會合作。具體來說,我正在與SDL和SDL_Event union合作。我需要製作SDL_Events的副本,而且我無法找到有關使用聯合重載賦值運算符的好信息。C++聯合分配,是否有一個很好的方法來做到這一點?

假設我可以重載賦值運算符,我應該手動篩選工會成員並複製相關成員,或者我可以簡單地來一些成員(這對我來說似乎很危險),或者可能只是使用memcpy()(this看起來簡單而快速,但有點危險)?

如果我不能重載操作符,那麼我最好的選擇是從那裏得到什麼?我想我可以製作新的副本並傳遞一堆指針,但在這種情況下,我寧願不這樣做。

任何想法歡迎!

編輯: 的要求錯誤消息,並且順便說一句,我認爲我已經學到了一些東西......

physworld.cpp:325: error: no match for ‘operator=’ in ‘CurrentEvent = ((physworld*)this)->physworld::SDL_UserInputEvents.std::queue<_Tp, _Sequence>::pop [with _Tp = SDL_Event, _Sequence = std::deque<SDL_Event, std::allocator<SDL_Event> >]()’ /usr/include/SDL/SDL_events.h:220: note: candidates are: SDL_Event& SDL_Event::operator=(const SDL_Event&)

EDIT2: 這是如此愚蠢......我認爲Deqeues pop()成員返回了刪除的項目。我認爲代碼非常簡單,它不能直接作爲我的代碼,但結果是錯誤的。

我的代碼看起來像:

for(SDL_Event CurrentEvent; !DequeueOfSDLEvents.empty(); CurrentEvent = DequeueOfSDLEvents.pop()) 
{ 
    //Do stuff 
} 

所以,如果不出意外,我會學着在容器的成員函數更密切地關注我最近沒有使用。感謝解釋分配默認工作,否則它會花費更長的時間才能找到它。

回答

4

在一個聯盟中,所有元素都佔據相同的記憶,就像他們坐在一起。如果你寫了一個工會的其他元素,它會覆蓋其他元素。

因此,逐個元素複製是浪費時間。你可以只複製最大的元素,但是你必須知道它是哪一個(不是每個元素都必須是相同的大小)。最好的辦法就是記憶聯合。

但它比這更簡單,你應該能夠做一個任務,並且編譯器,意識到你正在複製一個結構體或聯合體,會爲你隱式執行「memcpy」。

+0

我試過任務,並且它不會編譯,我想有些成員是不可複製的,也許? – Sqeaky 2010-03-17 23:30:23

+1

@Sqeaky向我們顯示錯誤消息。我們無法猜出問題所在。查看文檔SDL_Event中沒有任何內容似乎應該是複製問題。 – 2010-03-17 23:38:06

3

由於工會(根據定義)只允許包含POD,因此您可以安全地使用memcpy來複制它們。

+0

POD?普通舊數據,如在不是類?哦,有沒有辦法讓=運算符超載? – Sqeaky 2010-03-17 23:00:05

+1

聯盟可能包含非POD(我認爲讓成員包含私有成員是合法的),並且可以聲明自己的副本構造函數(只是其成員可能沒有自己的副本構造函數)。因此memcpy任意的聯合可能不安全並且依賴。我認爲大多數工會都是這樣,memcpy是完全安全的。 – 2010-03-18 06:17:07

0

貌似的boost::variant

[編輯] 爲什麼不適合一個典型的使用情況?

#define BOOST_VARIANT_LIMIT_TYPES 14 
typedef boost::variant<Uint8, SDL_ActiveEvent, SDL_KeyboardEvent, ...,SDL_SysWMEvent> MyEvent; 
+0

哦,我希望,這似乎整潔,但不直接適用,我堅持與SDL_Events - http://www.libsdl.org/cgi/docwiki.cgi/SDL_Event – Sqeaky 2010-03-17 23:50:43

1

我可能會誤解,但是不是工會支持開箱即用嗎?

#include <cassert> 

union X 
{ 
    int a; 
    double b; 
}; 

int main() 
{ 
    X x; 
    x.a = 10; 
    X y; 
    y = x; 
    assert(y.a == x.a); 
} 

它也出現,你也可以像往常一樣重載operator =,但是你會希望與正常的默認賦值不同嗎?

+0

此代碼按預期方式工作,但我試圖分配,並且它不會編譯,我想有些成員是不可複製的,也許? – Sqeaky 2010-03-17 23:30:51

0

一般來說,您可以使用編譯器生成的賦值運算符。我能想到的唯一例外是如果你有一個可以包含一個指針的聯合體,並且你想爲該指針實現一個深層副本。爲了處理好,你必須使它成爲一個有區別的聯合,這樣你才能確定類型並適當地複製指針。但是,只要您沒有遠程所有權,編譯器生成的分配(和複製ctor)應該可以正常工作。

0

你不需要做任何特別的事情。在我看來,重載或添加運算符只會增加複雜性。 SDL_event是一個簡單的無符號字符。

SDL_Events a; 
SDL_Events b; 

a = b; // this will copy the value 
相關問題