我在C ++ 11中使用std :: shared_ptr,我想了解以这种方式分配类型T的结构是否更好:
T a_data;
std::shared_ptr<T> my_pointer(new T);
*my_pointer = a_data;
或者喜欢:
memcpy(&my_pointer, data, sizeof(T));
或者喜欢:
my_pointer.reset(a_data);
此致
麦克
答案 0 :(得分:6)
他们各自做了不同的事情。
1
T a_data;
std::shared_ptr<T> my_pointer(new T);
*my_pointer = a_data;
此处,n
类型的新对象(称为T
)将由my_pointer
进行管理。然后,对象a_data
将被复制分配到n
。
2
memcpy(&my_pointer, a_data, sizeof(T)); // I assume you meant a_data here, not data
这完全是胡说八道 - 用shared_ptr
的内容覆盖a_data
本身。未定义的行为(最好是崩溃或内存损坏)。
也许你实际上是指my_pointer.get()
而不是&my_pointer
(也就是说,你想复制到被指向的对象中)?如果是这种情况,它可以工作,只要T
可以轻易复制 - 这意味着它没有非平凡的副本或移动ctors,没有非平凡的复制或移动赋值运算符,并有一个简单的析构函数。但是,为什么依赖于此,当正常分配(*my_pointer = a_data;
)对于该情况完全相同时, 也适用于非平凡的可复制类?
3
my_pointer.reset(a_data);
这通常不会按原样编译,它需要是my_pointer.reset(&a_data);
。这是等待发生的灾难 - 您将my_pointer
指向自动(=本地)变量a_data
并赋予其所有权。这意味着当my_pointer
超出范围时(实际上,当最后一个指针与它共享所有权时),它将调用删除器,通常调用delete
。在a_data
上,未分配new
。再次欢迎来到UB土地!
如果您只需要使用a_data
管理动态分配的shared_ptr
副本,请执行以下操作:
T a_data;
std::shared_ptr<T> my_pointer(new T(a_data));
甚至更好:
T a_data;
auto my_pointer = std::make_shared<T>(a_data);