Qt在信号/槽中使用boost :: shared_ptr

时间:2011-01-26 17:03:50

标签: c++ qt boost

是否可能,如果是这样,我怎样才能在Qt中创建一个信号/槽,它是对shared_ptr的const引用?我想要一个看起来像这样的信号:

void signal( shared_ptr<SomeClass> const & )

我知道如何在没有常量引用的情况下执行此操作,这只是类型shared_ptr<SomeClass>,但出于效率原因,我想避免复制。引用类型的相同语法不起作用:

Q_DECLARE_METATYPE(shared_ptr<SomeClass> const &)
qRegisterMetaType<shared_ptr<SomeClass> const&>();

许多标准API都有QString const &所以我认为它基本上是可行的,我只是无法弄清楚语法。


**性能的最大问题不是复制时间,而是当对象被复制到每个接收器时互斥锁定/解锁的数量 - 有很多。当多个线程使用该对象时,这会引起明显的减速/瓶颈。如果shared_ptr实际上只是使用原子操作,这个成本也是微不足道的,那么关于信号中const引用的一般问题仍然存在。*

2 个答案:

答案 0 :(得分:7)

到目前为止,我发现我可以这样做:

Q_DECLARE_METATYPE(shared_ptr<SomeClass>)
qRegisterMetaType<shared_ptr<SomeClass> >();
qRegisterMetaType<shared_ptr<SomeClass> >("std::shared_ptr<SomeClass>const&");

我正在尝试验证这是否真的有效。这里的文档不清楚实际发生了什么。似乎信号/槽中的const引用类型将被编组为普通shared_ptr<SomeClass>,这在这里完全没问题。有一些保证,这应该是这样的,但是很好。

我觉得简单的shared_ptr<SomeClass>版本就是所有需要的,而boost命名空间正在干扰信号。第二个版本似乎只是在全局命名空间中注册信号以便于使用。


我可以通过测试确认,const &部分在排队连接中完全被忽略。每个连接的槽都获得该对象的新副本。这非常不幸。 :(

进一步的测试显示&用于插槽,但是以不寻常的方式。仍然为排队连接创建对象的副本,但如果不使用引用,则将为该调用创建另一个副本。

因此,虽然每个connect最终都会复制排队连接的数据,但引用仍然有点帮助。而且如果你确实有一些本地发送的信号(相同的线程),你可以避免更多的复制。

答案 1 :(得分:2)

根据此问题Argument type for Qt signal and slot, does const reference qualifiers matters?中的一个答案,对于排队连接,无论您如何连接信号和插槽,都会复制该对象。

由于您使用多个线程,因此连接已排队。如果您担心互斥成本,请尝试直接使用SomeClass *。