【发布时间】:2011-06-16 00:02:56
【问题描述】:
是否有可能,如果可以,我如何在 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 引用的一般问题仍然存在。*
【问题讨论】:
-
不将 shared_ptr 作为 const ref 传递是否首先否定了 shared_ptr 的意义?只需将 const ref / 指针传递给相关对象即可。
-
@messenger,const 引用是为了避免在调用函数时复制 shared_ptr 的优化。这是一种相当常见的模式。如果你总是按值传递(信号或普通函数)shared_ptr 与普通指针相比变得相当昂贵。此处不能使用普通指针,因为不能保证“发射”端的对象的生命周期。
-
@edA-qa mort-ora-y:boost shared_ptr 是否使用互斥体???为什么???你需要的不是原子增量/减量吗?
-
@edA-qa,如果不能保证生命周期,那么您为什么尝试使用引用而不是复制指针对象?如果对象在另一端被销毁,您不会得到一个悬空引用吗?
-
@edA-qa,哦,现在我明白了。您只想制作一个通过引用传递给每个连接的插槽的副本。现在这是一个好主意,但不幸的是 Qt 以不同的方式做事。我想你可以通过首先将指针的副本传递给接收线程中的某个代理对象来解决它,这反过来会使用直接连接向所有接收器发出信号,但我担心双重信号开销会破坏非常避免不必要的复制。