2014-02-19 3 views
1

Я использую зЬй :: shared_ptr в C++ 11, и я хотел бы понять, если бы это лучше назначить структуры типа T таким образом:станд :: shared_ptr присвоение данных против тетсру

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); 

С уважением

Mike

+0

PS. Я переводил старый код C, который использует указатели и memcpy/free/malloc, как будто идет дождь.Я хотел бы уменьшить это количество операций с помощью shared_ptr – madduci

+0

'memcpy' не предоставляет требуемые функции. Избегай это. И только один из двух компиляторов. –

+0

на данный момент, все 3 из них компилируются. Но я не могу их проверить. – madduci

ответ

4

Они каждый делают другую вещь.

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); 
+0

ОК спасибо! Допустим ли это для структур типа T, которые содержатся внутри других shared_ptr для других структур? (да, этот старый код C у меня есть кошмар) – madduci

+0

@blackibiza Мои два решения будут работать очень хорошо (выполняя * мелкую копию). Кажется, вам стоит больше взглянуть на то, как копирование и назначение выполняются на C++; возможно, возьмите [хорошую книгу] (http://stackoverflow.com/q/388242/1782465)? – Angew

+0

Я знаю, как задание работает на C++. У меня были сомнения только из-за умных указателей, которых я никогда раньше не использовал. – madduci

Смежные вопросы