2

我正在与图书馆合作,我必须与工会合作。具体来说,我正在使用 SDL 和SDL_Event union。我需要制作 SDL_Events 的副本,并且找不到关于使用联合重载赋值运算符的好信息。

假设我可以重载赋值运算符,我应该手动筛选工会成员并复制相关成员,还是我可以简单地来一些成员(这对我来说似乎很危险),或者只是使用 memcpy() (这看起来简单快捷,但有点危险)?

如果我不能重载运算符,那么我最好的选择是什么?我想我可以制作新副本并传递一堆指针,但在这种情况下,我宁愿不这样做。

欢迎任何想法!

编辑:根据要求的错误消息,顺便说一句,我想我学到了一些东西......

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:这太愚蠢了......我认为 Deqeus pop() 成员返回了删除的项目。我以为代码太简单了,不能直接是我的代码,但事实证明这是错误的。

我的代码看起来像:

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

因此,如果不出意外,我将学习更仔细地查看我最近没有使用过的容器的成员函数。感谢您解释默认情况下分配的工作,否则将需要更长的时间才能找到它。

4

6 回答 6

6

在一个联合中,所有元素都占据相同的内存,就像它们彼此叠放一样。如果您写入联合的另一个元素,它会覆盖其他元素。

因此,逐个元素地复制是浪费时间。您可以只复制最大的元素,但是您必须知道哪个是(并非联合的每个元素都必须具有相同的大小) 最好的办法就是只 memcpy 联合。

但它比这更简单,你应该能够只做一个赋值,编译器意识到你正在复制一个结构或联合,会隐式地为你做“memcpy”。

于 2010-03-17T23:06:41.480 回答
3

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

于 2010-03-17T22:57:59.127 回答
2

我可能弄错了,但工会不支持开箱即用的分配吗?

#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= ,但是你想要与正常的默认赋值有什么不同呢?

于 2010-03-17T23:19:39.830 回答
0

看起来像是boost::variant的典型用例

[编辑] 为什么不合适?

#define BOOST_VARIANT_LIMIT_TYPES 14
typedef boost::variant<Uint8, SDL_ActiveEvent, SDL_KeyboardEvent, ...,SDL_SysWMEvent> MyEvent;
于 2010-03-17T23:10:29.140 回答
0

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

于 2010-03-17T23:23:55.537 回答
0

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

SDL_Events a;
SDL_Events b;

a = b;  // this will copy the value
于 2010-03-18T00:21:55.517 回答