我正在尝试shared_ptr
and make_shared
从 C++11 编写了一个小玩具示例来看看调用时实际发生了什么make_shared
。作为基础设施,我使用 llvm/clang 3.0 以及 XCode4 中的 llvm std c++ 库。
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:完成。
使用新创建 smart_ptr...
新建构造函数
使用 new:done 创建 smart_ptr。
析构函数
析构函数
看起来make_shared
调用复制构造函数两次。如果我为一个分配内存Object
使用常规的new
这不会发生,只有一个Object
被建造。
What I am wondering about is the following. I heard that make_shared
is supposed to be more efficient than using new
(1 http://en.cppreference.com/w/cpp/memory/shared_ptr/make_shared, 2 http://channel9.msdn.com/Events/GoingNative/GoingNative-2012/STL11-Magic-Secrets). One reason is because make_shared
allocates the reference count together with the object to be managed in the same block of memory. OK, I got the point. This is of course more efficient than two separate allocation operations.
相反,我不明白为什么这必须伴随两次调用复制构造函数的成本Object
。因此我不相信make_shared
比使用分配更有效new
in every案件。我这里错了吗?好吧,我们可以实现一个移动构造函数Object
但我仍然不确定这是否比仅仅分配更有效Object
通过new
。至少不是在所有情况下都是如此。如果复制的话那就是真的Object
比为引用计数器分配内存更便宜。但是shared_ptr
- 内部引用计数器可以使用几种原始数据类型来实现,对吧?
你能帮忙解释一下原因吗make_shared
尽管有概述的复制开销,但就效率而言,这是可行的方法吗?