私はしばしば関数のconst参照によってshared_ptrを渡すべきであることを読んでいます。私はそれについて考えてみると、これが本当に良いアドバイスであるかどうかは分かりません。なぜなら、これがスレッド化されるかどうかわからないからです。これがconst refを渡すためのスレッドスレフであるかどうか誰にでも教えてください。shared_pointerをconst参照で渡すのはスレッドセーブですか?
答えて
任意のクラスのコピーのオーバーヘッドを避けるには、const&
を渡すことをお勧めします。たとえば、std::string
のようなものでは特に重要です。
shared_ptr
をconst&
に渡す場合、オーバーヘッドは原子のためほとんどがincrementing and decrementing of the reference countです。
BUT! const& shared_ptr
でスレッドを作成するときに問題があります。参照カウントが増加します。インクリメントされているので、値渡しした場合とほぼ同じです。実際にはby-valueをstd::thread
ctorに渡しているので、増分が関数に渡されます。
自身のために参照してください:
// gcc (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4
void test(const shared_ptr<int>& i)
{
cout << "c = " << i.use_count() << endl;
}
int main(int argc, char** argv)
{
shared_ptr<int> i(new int);
cout << "c = " << i.use_count() << endl;
test(i);
cout << "thread!" << endl;
thread t(test, i);
t.join();
cout << "c = " << i.use_count() << endl;
}
結果があること:
c = 1
c = 1
thread!
c = 2 // <= incremented!
c = 1 // <= thread joined!
shared_ptr
は、スレッドの安全性のための完璧な候補であるが、それはレース条件やデッドロックからあなたを保護しません。
&
を使用すると、オブジェクト自体が表示されます。
あなたは参照カウントを増やすことはありません。ただオブジェクトを渡すだけです。人々がconst&
を渡すことを提案している理由は、スレッド数が安全にrefカウントを増やすコストを避けるためです。 const&
として渡すときのコストは、intまたはポインタのコピーと同じコストであり、shared_ptr
のコンストラクタがexplicit
とマークされているため、const&
には一時オブジェクトはバインドされません。
オブジェクトへの参照(呼び出し先関数から参照がバインドされているオブジェクト)が常に1つ以上存在するため、ローカル参照を使用している間にオブジェクトが破棄される恐れはありません。
参照がバインドされているオブジェクトが範囲外になるとどうなりますか?これが起こると、私はrefを使うと破壊されるメモリを使います – Exagon
'const&'と普通の '&'との違いはどのくらいですか?どちらも参照のみなので、refカウントの変更は適用されません。 – rozina
@Exagon、どのように範囲外に出るのですか?あなたは関数をローカルの 'shared_ptr'を渡して呼び出しました。あなたがその関数から戻り、現在のブロック 'shared_ptr'が到達するまで、少なくともスコープから外れることはありません。例えば '{std :: shared_ptr
const参照を渡すことはスレッドに依存しません。簡単なコード以下を見てください:
void foo(const std::shared_ptr<int>& x) {
sleep(100000);
}
void bar() {
//...
std::shared_ptr y = ...;
foo(y);
}
y
はfoo
戻るまでバーに住んでいるために起こっている - これshared_ptr
が有効のまま確認すること。 foo()
が別のスレッドを作成してx
を渡すと、それをコピーする必要があります。これにより、参照カウンタが増加します。
参照渡しは、どのオブジェクトが渡されても常にスレッドセーフです。 constへの参照であるかどうかは関係ありません。
- 1. shared_pointerへの参照の参照カウント
- 2. テンプレートはconst参照で渡す
- 3. 比較関数でconst参照VS非const参照対値渡し
- 4. C++では、const boolを参照渡しするのは悪いですか?
- 5. RWCString - 値渡しまたはconst参照
- 6. Delphiのconstへの参照渡し
- 7. constポインタへの参照を正しく渡すには?
- 8. 参照でC++ const lost
- 9. const参照を返す
- 10. 参照ツーのconst
- 11. __FILE__はC++のconst char *で参照できますか?
- 12. Mutexオブジェクトは参照渡しですか?
- 13. ポインタは参照渡しですか? (サニティチェック)
- 14. 参照でベクトルを渡す
- 15. 非constオブジェクトへのconst参照
- 16. C++のオーバーライド+ = const参照と
- 17. getterメソッドのconst参照
- 18. は参照で引数を渡すと
- 19. const参照で一時的に渡すときにコピーコンストラクタが呼び出されるのはなぜですか?
- 20. 渡す参照
- 21. Javaは値渡しか参照渡しですか?
- 22. コンストラクタでconstへの参照を使用したいのはなぜですか?
- 23. C++変換constが参照渡しテンプレートを考える
- 24. ベクトル要素への非const参照を返すConstメソッド
- 25. constポインタ参照を返します
- 26. セマンティクスとconst参照を移動する
- 27. std :: remove_constとconst参照
- 28. 参照でポインタをC++で渡す
- 29. 参照で渡さずにC++で参照する
- 30. PHPで参照渡しを使うのは良いですか?
'std :: thread'コンストラクタはすべての引数をコピー/移動します。 – GeorgeAl
@GeorgeAl Thx、その精度を追加 – BlakBat