2016-07-04 12 views
1

以下のサンプルコードがあります。私はRVO(戻り値の最適化)について少しは知っていますし、コピーコンストラクタと代入演算子を最適化中にスキップして値を返す方法は、左側のメモリに直接配置されます。したがって、共有ポインタがRVOを行う場合、共有ポインタはいつカウンタを増加させるのかを知っていますか?なぜなら何らかの理由で、共有ポインタクラスは、コピー数や割り当てに基づいてカウンタをいつ増やすべきかを知っているからだと思いました。shared_ptrは値渡しでカウンタをどのように増加させるのですか?

#include <iostream> 
#include <memory> 
using namespace std; 
class A{ 
public: 
    A(){} 
    A(const A& other){ std::cout << " Copy Constructor " << std::endl; } 
    A& operator=(const A&other){ 
     std::cout << "Assingment operator " << std::endl;   
     return *this; 
    }  
    ~A(){ 
     std::cout << "~A" << std::endl; 
    } 
}; 

std::shared_ptr<A> give_me_A(){ 
    std::shared_ptr<A> sp(new A); 
    return sp; 
} 

void pass_shared_ptr_by_val(std::shared_ptr<A> sp){ 

    std::cout << __func__ << ": count sp = " << sp.use_count() << std::endl; 
    std::shared_ptr<A> sp1 = sp; 
    std::cout << __func__ << ": count sp = " << sp.use_count() << std::endl; 
    std::cout << __func__ << ": count sp1 = " << sp1.use_count() << std::endl; 
} 

void pass_shared_ptr_by_ref(std::shared_ptr<A>& sp){ 
    std::cout << __func__ << ": count sp = " << sp.use_count() << std::endl; 
    std::shared_ptr<A> sp1 = sp; 
    std::cout << __func__ << ": count sp = " << sp.use_count() << std::endl; 
    std::cout << __func__ << ": count sp1 = " << sp1.use_count() << std::endl; 
} 

int main(){ 

    { 
     shared_ptr<A> sp3 = give_me_A(); 

     std::cout << "sp3 count = " << sp3.use_count() << std::endl; 
     pass_shared_ptr_by_val(sp3); 
     pass_shared_ptr_by_ref(sp3); 
    } 
return 0; 
} 

出力:

SP3カウント= 1


pass_shared_ptr_by_val:カウントSP = 2

pass_shared_ptr_by_val:カウントSP = 3

pass_shared_ptr_by_val:カウントSP1 = 3


pass_shared_ptr_by_ref:数SP = 1

pass_shared_ptr_by_ref:カウントSP = 2

pass_shared_ptr_by_ref:カウントSP1 = 2

+6

RVOが実行される場合、コピーが実行されないため、共有ポインタは参照カウントをインクリメントする必要はありません。私はあなたの質問が何であるか分かりません。あなたはどんなアウトプットを期待しますか? – TartanLlama

+0

@TartanLlama私はRVOも値渡しで起こったと考えました。したがって、コピーコンストラクタは呼び出されません..しかし私は間違っていました...値渡し時にコピーコンストラクタが呼び出され、カウンタが増加します。私は今疑いがあると思います – solti

答えて

4

何のコピーが存在しない場合何もカウントする必要はありません。

RVOが有効になっている場合はコピーが作成されないので、なぜref-countを増やす必要がありますか? ref-countを破棄したり減らしたりする余分なオブジェクトはありません。

+0

give_me_A関数でRVOは起こらないのですか? – solti

+0

@soltiそれは(または可能性があります)。コピーがないため、参照カウントには触れないでください。 – TartanLlama

+0

@Jesper Juhlとpass_shared_ptr_by_valはどうですか?ここでカウンタが増えます – solti

関連する問題