私はC++11を試したり、C ++ 11から実験しshared_ptrたりmake_sharedして、小さなおもちゃの例をプログラムして、を呼び出したときに実際に何が起こっているかを確認しましたmake_shared。インフラストラクチャとして、XCode4内のllvm stdc++ライブラリとともにllvm/clang3.0を使用していました。
class Object
{
public:
Object(const string& str)
{
cout << "Constructor " << str << endl;
}
Object()
{
cout << "Default constructor" << endl;
}
~Object()
{
cout << "Destructor" << endl;
}
Object(const Object& rhs)
{
cout << "Copy constructor..." << endl;
}
};
void make_shared_example()
{
cout << "Create smart_ptr using make_shared..." << endl;
auto ptr_res1 = make_shared<Object>("make_shared");
cout << "Create smart_ptr using make_shared: done." << endl;
cout << "Create smart_ptr using new..." << endl;
shared_ptr<Object> ptr_res2(new Object("new"));
cout << "Create smart_ptr using new: done." << endl;
}
次に、出力を見てください。
make_sharedを使用してsmart_ptrを作成します...
コンストラクタmake_shared
コンストラクターをコピーします。
コンストラクターをコピーします。
デストラクタ
デストラクタ
make_sharedを使用してsmart_ptrを作成します:done。
new...を使用してsmart_ptrを作成します。
新しいコンストラクタ
new:doneを使用してsmart_ptrを作成します。
デストラクタ
デストラクタ
make_sharedコピーコンストラクタを2回呼び出しているようです。Objectレギュラーを使用してメモリを割り当てる場合、newこれは発生せず、1つだけObjectが構築されます。
私が疑問に思っているのは次のとおりです。(1、2)をmake_shared使用するよりも効率的だと聞いています。1つの理由は、同じメモリブロックで管理されるオブジェクトと一緒に参照カウントを割り当てるためです。OK、要点はわかりました。もちろん、これは2つの個別の割り当て操作よりも効率的です。newmake_shared
それどころか、なぜこれがのコピーコンストラクターへの2回の呼び出しのコストを伴う必要があるのか理解できませんObject。このため、すべての場合に使用するmake_shared割り当てよりも効率的であるとは確信していません。私はここで間違っていますか?さて、1つはのための移動コンストラクターを実装することができますが、それでもこれが単にを割り当てるよりも効率的であるかどうかはわかりません。少なくともすべての場合ではありません。コピーが参照カウンターにメモリを割り当てるよりも安価である場合は、それが当てはまります。しかし、内部参照カウンターは、いくつかのプリミティブデータ型を使用して実装できますよね?newObjectObjectnewObjectshared_ptr
make_shared概説されたコピーのオーバーヘッドにもかかわらず、なぜ効率の観点から進むべきかを助け、説明できますか?