スマート ポインターを逆参照しても、パフォーマンスに大きな影響はないとよく言われます。(例: C Smart Pointer Performance )
これが本当なのか今疑問に思っています。参照されているオブジェクトに対する操作がアトミックである場合、それが可能であることを理解しています。
このスニペットに基づいてコードを考える:
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()
2 番目のスレッドから呼び出されます。ごく普通のスマート ポインターの使用シナリオ。
一般的なコンセンサスではsetDataProvider()
、ロックで保護された参照カウントを変更する必要があるため、追加のコストがかかると言われていますが、そうでm_provider->getSomeData()
はありません。通常のポインター逆参照に匹敵すると言われていますが、少なくともコストのかかるロックは必要ありません。
しかし、それはどのように機能しますか?getSomeData()
はアトミック操作ではなく、いくつかのロジックと顕著な実行時間があると仮定しましょう。
*m_provider
実行中に削除されないようにするにはどうすればよいgetSomeData()
ですか? クラスがオブジェクトの唯一の所有者である可能性があります。上書きm_provider
すると、ポインターの参照カウントが 1 つ減少します。m_provider->getSomeData()
一時的に参照カウントを上げる必要があるか、実行中にオブジェクトが削除されないように保護されていますgetSomeData()
。
どちらの場合も、コストのかかる同期/ロック メカニズムが必要です。
補遺:shared_ptr
一般的にこれについて疑問に思っているので、例では標準を使用しました。ただし、実際のコードで使用されてQSharedPointer
いるため、これについて特に興味があります。どちらも同じスレッド セーフであると単純に想定していましたが、これは間違っている可能性があります。