私は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つの個別の割り当て操作よりも効率的です。new
make_shared
それどころか、なぜこれがのコピーコンストラクターへの2回の呼び出しのコストを伴う必要があるのか理解できませんObject
。このため、すべての場合に使用するmake_shared
割り当てよりも効率的であるとは確信していません。私はここで間違っていますか?さて、1つはのための移動コンストラクターを実装することができますが、それでもこれが単にを割り当てるよりも効率的であるかどうかはわかりません。少なくともすべての場合ではありません。コピーが参照カウンターにメモリを割り当てるよりも安価である場合は、それが当てはまります。しかし、内部参照カウンターは、いくつかのプリミティブデータ型を使用して実装できますよね?new
Object
Object
new
Object
shared_ptr
make_shared
概説されたコピーのオーバーヘッドにもかかわらず、なぜ効率の観点から進むべきかを助け、説明できますか?