2016-05-10 4 views
1

私はしばしば関数のconst参照によってshared_ptrを渡すべきであることを読んでいます。私はそれについて考えてみると、これが本当に良いアドバイスであるかどうかは分かりません。なぜなら、これがスレッド化されるかどうかわからないからです。これがconst refを渡すためのスレッドスレフであるかどうか誰にでも教えてください。shared_pointerをconst参照で渡すのはスレッドセーブですか?

答えて

1

任意のクラスのコピーのオーバーヘッドを避けるには、const&を渡すことをお勧めします。たとえば、std::stringのようなものでは特に重要です。

shared_ptrconst&に渡す場合、オーバーヘッドは原子のためほとんどが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は、スレッドの安全性のための完璧な候補であるが、それはレース条件やデッドロックからあなたを保護しません。

+1

'std :: thread'コンストラクタはすべての引数をコピー/移動します。 – GeorgeAl

+0

@GeorgeAl Thx、その精度を追加 – BlakBat

1

&を使用すると、オブジェクト自体が表示されます。

あなたは参照カウントを増やすことはありません。ただオブジェクトを渡すだけです。人々がconst&を渡すことを提案している理由は、スレッド数が安全にrefカウントを増やすコストを避けるためです。 const&として渡すときのコストは、intまたはポインタのコピーと同じコストであり、shared_ptrのコンストラクタがexplicitとマークされているため、const&には一時オブジェクトはバインドされません。

オブジェクトへの参照(呼び出し先関数から参照がバインドされているオブジェクト)が常に1つ以上存在するため、ローカル参照を使用している間にオブジェクトが破棄される恐れはありません。

+0

参照がバインドされているオブジェクトが範囲外になるとどうなりますか?これが起こると、私はrefを使うと破壊されるメモリを使います – Exagon

+0

'const&'と普通の '&'との違いはどのくらいですか?どちらも参照のみなので、refカウントの変更は適用されません。 – rozina

+0

@Exagon、どのように範囲外に出るのですか?あなたは関数をローカルの 'shared_ptr'を渡して呼び出しました。あなたがその関数から戻り、現在のブロック 'shared_ptr'が到達するまで、少なくともスコープから外れることはありません。例えば ​​'{std :: shared_ptr my_shared = make_shared (...); pass_by_constref(my_shared); 0を返します。 } ' – GeorgeAl

0

const参照を渡すことはスレッドに依存しません。簡単なコード以下を見てください:

void foo(const std::shared_ptr<int>& x) { 
    sleep(100000); 
} 


void bar() { 
    //... 
    std::shared_ptr y = ...; 
    foo(y); 
} 

yfoo戻るまでバーに住んでいるために起こっている - これshared_ptrが有効のまま確認すること。 foo()が別のスレッドを作成してxを渡すと、それをコピーする必要があります。これにより、参照カウンタが増加します。

0

参照渡しは、どのオブジェクトが渡されても常にスレッドセーフです。 constへの参照であるかどうかは関係ありません。

関連する問題