【问题标题】:shared_ptr - pass by value vs pass by referenceshared_ptr - 按值传递与按引用传递
【发布时间】:2011-03-16 19:36:55
【问题描述】:

假设我有:

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);

考虑到我的 EventDispatcher 有一个队列:

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

然后,另一个线程从队列中弹出一个 Event 并将其交给某个东西来处理该事件:

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

同样,process 方法的适当方法签名是什么?我想知道我是否可以将裸Event* 传递给 process 方法?

我想我想知道我是否应该只按值传递以便引用计数准确?我真的只关心一个线程正在推入队列而另一个线程正在从队列中弹出并且我不会在某处泄漏指针的事实......

谢谢!

【问题讨论】:

    标签: c++ boost smart-pointers


    【解决方案1】:

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

    任何一个建议都可以;通过 const 引用传递可能会更有效,因为它不必修改指针的引用计数。在任何一种情况下,push_back 都会将指针的副本放在队列中,从而在队列中保持事件处于活动状态。

    再一次,什么是过程方法的合适的方法签名?我想知道我是否可以将裸 Event* 传递给 process 方法?

    传递共享指针(通过值或引用)将清楚地记录和强制事件的所有权,并允许处理器在调用process() 后保留它(如果需要)。传递原始指针会给所有权带来不确定性;处理者需要一份合同,说明它不拥有该事件的所有权,并且在process() 结束后不得尝试访问它。

    【讨论】:

      【解决方案2】:

      在大局中,通过值传递还是通过引用传递并不重要。无论哪种方式,当您将 shared_ptr 复制到队列中时,引用计数都会增加。

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

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

      【讨论】:

        【解决方案3】:

        两个调度函数都可以正常工作。

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

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

        在第二种情况下,只有对现有实例的引用将被传递给函数,然后复制到队列中。我会使用这个变体。

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

        将共享指针传递给process()时,也可以通过引用传递:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-10-22
          • 2023-03-02
          • 2012-07-03
          • 2013-04-12
          • 2017-01-19
          • 2011-05-08
          相关资源
          最近更新 更多