人们经常说取消引用智能指针不会对性能产生显着影响。(例如这里:C 智能指针性能)
我现在想知道这是不是真的。我知道它可能是,如果对引用的对象的操作是原子的。
基于此片段的代码思考:
class Worker
{
[...]
public:
void setDataProvider( shared_ptr<DataProvider> p )
{
m_provider = p;
}
void doWork()
{
[...]
for(;;) {
int d = m_provider->getSomeData();
[ do something with d ]
}
}
private:
shared_ptr<DataProvider> m_provider;
};
doWork()
将被永久执行,并且不时setDataProvider()
从第二个线程调用。相当普通的智能指针使用场景。
普遍的共识认为这setDataProvider()
有一些额外的成本,因为锁保护的引用计数必须改变,但m_provider->getSomeData()
没有。据说它与普通的指针解引用相当,至少不需要昂贵的锁定。
但这怎么能行呢?让我们假设,getSomeData()
它不是原子操作,它可能有一些逻辑和显着的执行时间。
执行时如何*m_provider
防止被删除getSomeData()
?该类可能是该对象的唯一所有者。覆盖m_provider
会将指针的引用计数减一。要么m_provider->getSomeData()
暂时必须提高引用计数,要么在运行时保护对象不被删除getSomeData()
。
在这两种情况下,都需要一些昂贵的同步/锁定机制。
附录:我在示例中使用了标准shared_ptr
,因为我一般对此感到疑惑。但是真正的代码使用QSharedPointer
所以我对此特别感兴趣。我天真地假设两者都具有相同的线程安全性,这可能是错误的。