2011-03-16 42 views
8

假设我有:shared_ptr的 - 通过值VS通过引用传递

typedef boost::shared_ptr<Event> EventPtr; 

在一个线程中,我创建一个Event并发送其关闭,以获得出动:

Event* event = new Event(); 
EventPtr eventPtr(event); 
EventDispatcher::dispatch(eventPtr); //pseudocode 

EventDispatcher接收一个EventPtr并将其添加到在另一个线程中处理的队列中......但调度方法的适当方法签名是什么?

dispatch(EventPtr event); //will push_back(event) 

dispatch(const EventPtr& event); //will push_back(event); 

考虑到我此事件有一个队列:

typedef std::queue<EventPtr> EventQueue 
EventQueue theQueue; 

后来的后来,另一个线程弹出一个事件从队列并把它掉的东西来处理事件:

EventPtr event = theQueue.front(); 
EventProcessor::process(event); //pseudocode 
theQueue.pop(); 

再次,process方法的适当方法签名是什么?我想知道如果我可以通过裸体Event*的过程方法?

我想我想知道我是否应该通过价值所以引用计数是准确的?我真的只关心这样一个事实,即一个线程正在推入队列,另一个线程正在弹出队列,我不会在某处泄漏指针...

谢谢!

回答

4

EventDispatcher接收到一个EventPtr并将其添加到在另一个线程中处理的队列中......但调度方法的适当方法签名是什么?

任何一个建议都可以;通过const引用传递可能会更有效率,因为它不需要修改指针的引用计数。无论哪种情况,push_back都会将指针副本放置在队列中,使队列中的事件保持活动状态。

同样,过程方法的适当方法签名是什么?我想知道我是否可以将裸体事件*传递给过程方法?

跑过共享指针(由值或参考)将清楚地记录和执行该事件的所有权,并允许所述处理器,以保持它的保持状态的呼叫到process()后是否需要。传递一个原始指针会给所有权带来不确定性;处理器将需要一份合同,声明其未取得该事件的所有权,并且一旦process()已结束,则不得尝试访问它。

1

从宏观角度来看,无论您是通过价值还是通过参考传递都无关紧要。无论哪种方式,当您复制shared_ptr将其推入队列时,引用计数将会增加。

传递裸指针也可以,只要您小心,最终不会得到两个不同引用计数的shared_ptr实例,一个在调用者中,另一个在被调用者中。

就我个人而言,我喜欢按值传递选项,因为它更像是传递实际指针。要求shared_ptr作为参数也会提醒程序员调用函数,它希望对象的生命周期超过函数调用,并且调用者可能希望将参数存储在shared_ptr中,以防函数返回时提前抛出等

0

这两个派遣函数将正常工作。

在第一种情况下,共享指针的实例将被复制到堆栈上,然后在添加到事件队列时再次复制。这意味着复制指针并增加参考计数器。

dispatch(EventPtr event); //will push_back(event) 

在到现有的实例中的第二壳体只是一个参考将被传递给函数,然后复制到队列中。我会使用这个变体。

dispatch(const EventPtr& event); //will push_back(event); 

当通过共享指针进程(),也可以通过参考将它传递:

class EventProcessor { 
    process(const EventPtr& event); 
}