这是我的问题。 我有一个类来创建定时事件。它需要:
void (*func)(void* arg)
参数的void*
延迟
问题是我可能想创建我不希望成为类中的静态变量的动态变量,或全局变量。如果不满足其中任何一个,我就不能这样做:
void doStuff(void *arg)
{
somebool = *(bool*)arg;
}
void makeIt()
{
bool a = true;
container->createTimedEvent(doStuff,(void*)&a,5);
}
这不起作用,因为当函数返回时bool被破坏了。所以我必须在堆上分配这些。然后问题变成了,谁分配谁删除。我想做的是能够接收任何东西,然后复制它的内存并在定时事件类中管理它。但我不认为我可以做memcpy,因为我不知道这个问题。
在时间事件负责内存管理的情况下,实现这一目标的好方法。
由于
我不使用boost
class AguiTimedEvent {
void (*onEvent)(void* arg);
void* argument;
AguiWidgetBase* caller;
double timeStamp;
public:
void call() const;
bool expired() const;
AguiWidgetBase* getCaller() const;
AguiTimedEvent();
AguiTimedEvent(void(*Timefunc)(void* arg),void* arg, double timeSec, AguiWidgetBase* caller);
};
void AguiWidgetContainer::handleTimedEvents()
{
for(std::vector<AguiTimedEvent>::iterator it = timedEvents.begin(); it != timedEvents.end();)
{
if(it->expired())
{
it->call();
it = timedEvents.erase(it);
}
else
it++;
}
}
void AguiWidgetBase::createTimedEvent( void (*func)(void* data),void* data,double timeInSec )
{
if(!getWidgetContainer())
return;
getWidgetContainer()->addTimedEvent(AguiTimedEvent(func,data,timeInSec,this));
}
void AguiWidgetContainer::addTimedEvent( const AguiTimedEvent &timedEvent )
{
timedEvents.push_back(timedEvent);
}
答案 0 :(得分:1)
答案 1 :(得分:1)
使用C ++ 0x unique_ptr非常适合这项工作。这是未来的标准,但G ++和Visual Studio已经支持unique_ptr。对于C ++ 98(当前标准),auto_ptr的工作方式类似于难以使用的unique_ptr版本...对于C ++ TR1(在Visual Studio和G ++中实现),您可以使用std :: tr1 :: shared_ptr。
基本上,你需要一个智能指针。以下是unique_ptr的工作原理:
unique_ptr<bool> makeIt(){ // More commonly, called a "source"
bool a = true;
container->createTimedEvent(doStuff,(void*)&a,5);
return new unique_ptr<bool>(a)
}
稍后使用代码时......
void someFunction(){
unique_ptr<bool> stuff = makeIt();
} // stuff is deleted here, because unique_ptr deletes
// things when they leave their scope
您也可以将其用作“接收器”功能
void sink(unique_ptr<bool> ptr){
// Use the pointer somehow
}
void somewhereElse(){
unique_ptr<bool> stuff = makeIt();
sink(stuff);
// stuff is now deleted! Stuff points to null now
}
除此之外,除了奇怪的移动规则之外,你可以像使用普通指针一样使用unique_ptr。有许多智能指针,unique_ptr只是其中之一。 shared_ptr在Visual Studio和G ++中实现,是更典型的ptr。我个人喜欢尽可能经常使用unique_ptr。
答案 2 :(得分:0)
如果你不能使用boost或tr1,那么我要做的就是编写我自己的函数,其行为类似于auto_ptr。事实上,这就是我在这里没有任何提升或tr1访问的项目所做的。当所有关心数据的事件都完成后,它会自动被删除。
答案 3 :(得分:0)
您可以只更改函数定义以获取一个额外的参数,该参数表示传入的对象的大小。然后只需传递大小。所以你的新函数声明如下所示:
void (*func)(void* arg, size_t size)
void doStuff(void *arg, size_t size)
{
somebool = *(bool*)arg;
memcpy( arg, myStorage, size );
}
void makeIt()
{
bool a = true;
container->createTimedEvent(doStuff,(void*)&a,sizeof(bool), 5);
}
然后,您可以传递仍在堆栈中的变量,并在定时事件类中记忆它们。唯一的问题是你不再知道这种类型......但是当你转向虚空时会发生什么*
希望有所帮助。
答案 4 :(得分:0)
您应该重新使用您的类来使用继承,而不是函数指针。
class AguiEvent {
virtual void Call() = 0;
virtual ~AguiEvent() {}
};
class AguiTimedEvent {
std::auto_ptr<AguiEvent> event;
double timeSec;
AguiWidgetBase* caller;
public:
AguiTimedEvent(std::auto_ptr<AguiEvent> ev, double time, AguiWidgetBase* base)
: event(ev)
, timeSec(time)
, caller(base) {}
void call() { event->Call(); }
// All the rest of it
};
void MakeIt() {
class someclass : AguiEvent {
bool MahBool;
public:
someclass() { MahBool = false; }
void Call() {
// access to MahBool through this.
}
};
something->somefunc(AguiTimedEvent(new someclass())); // problem solved
}