C++联合分配,是否有一个很好的方法来做到这一点?

问题描述:

我正在与图书馆合作,我必须与工会合作。具体来说,我正在与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 
} 

所以,如果不出意外,我会学着在容器的成员函数更密切地关注我最近没有使用。感谢解释分配默认工作,否则它会花费更长的时间才能找到它。

在一个联盟中,所有元素都占据相同的记忆,就像他们坐在一起。如果你写了一个工会的其他元素,它会覆盖其他元素。

因此,逐个元素复制是浪费时间。你可以只复制最大的元素,但是你必须知道它是哪一个(不是每个元素都必须是相同的大小)。最好的办法就是记忆联合。

但它比这更简单,你应该能够做一个任务,并且编译器,意识到你正在复制一个结构体或联合体,会为你隐式执行“memcpy”。

+0

我试过任务,并且它不会编译,我想有些成员是不可复制的,也许? – Sqeaky 2010-03-17 23:30:23

+1

@Sqeaky向我们显示错误消息。我们无法猜出问题所在。查看文档SDL_Event中没有任何内容似乎应该是复制问题。 – 2010-03-17 23:38:06

由于工会(根据定义)只允许包含POD,因此您可以安全地使用memcpy来复制它们。

+0

POD?普通旧数据,如在不是类?哦,有没有办法让=运算符超载? – Sqeaky 2010-03-17 23:00:05

+1

联盟可能包含非POD(我认为让成员包含私有成员是合法的),并且可以声明自己的副本构造函数(只是其成员可能没有自己的副本构造函数)。因此memcpy任意的联合可能不安全并且依赖。我认为大多数工会都是这样,memcpy是完全安全的。 – 2010-03-18 06:17:07

貌似的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

我可能会误解,但是不是工会支持开箱即用吗?

#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

一般来说,您可以使用编译器生成的赋值运算符。我能想到的唯一例外是如果你有一个可以包含一个指针的联合体,并且你想为该指针实现一个深层副本。为了处理好,你必须使它成为一个有区别的联合,这样你才能确定类型并适当地复制指针。但是,只要您没有远程所有权,编译器生成的分配(和复制ctor)应该可以正常工作。

你不需要做任何特别的事情。在我看来,重载或添加运算符只会增加复杂性。 SDL_event是一个简单的无符号字符。

SDL_Events a; 
SDL_Events b; 

a = b; // this will copy the value