Конструктор of unique_ptr<T>
приймає сирий вказівник на об'єкт типу T
(отже, він приймає a T*
).
У першому прикладі:
unique_ptr<int> uptr (new int(3));
Покажчик є результатом new
виразу, тоді як у другому прикладі:
unique_ptr<double> uptr2 (pd);
Покажчик зберігається у pd
змінній.
Концептуально нічого не змінюється (ви будуєте a unique_ptr
з необробленого вказівника), але другий підхід є потенційно більш небезпечним, оскільки це дозволить вам, наприклад, зробити:
unique_ptr<double> uptr2 (pd);
unique_ptr<double> uptr3 (pd);
Таким чином, маючи два унікальних вказівники, які ефективно інкапсулюють один і той же об’єкт (тим самим порушуючи семантику унікального вказівника).
Ось чому перша форма для створення унікального вказівника є кращою, коли це можливо. Зверніть увагу, що в C ++ 14 ми зможемо зробити:
unique_ptr<int> p = make_unique<int>(42);
Що одночасно і зрозуміліше, і безпечніше. А щодо цього вашого сумніву:
Мені також незрозуміло, так це те, як покажчики, оголошені таким чином, будуть відрізнятися від покажчиків, оголошених "нормальним" способом.
Розумні вказівники повинні моделювати право власності на об'єкт і автоматично дбати про знищення загостреного об'єкта, коли останній (розумний, володіючий) вказівник на цей об'єкт виходить за межі області дії.
Таким чином, вам не потрібно пам’ятати, як це робили delete
об’єкти, які розподіляються динамічно - деструктор розумного вказівника зробить це за вас, - і не турбуватися про те, чи не буде ви розрингувати (звисаючий) вказівник на вже зруйнований об’єкт:
{
unique_ptr<int> p = make_unique<int>(42);
}
Зараз unique_ptr
є розумний вказівник, який моделює унікальне право власності, а це означає, що будь-коли у вашій програмі повинен бути лише один (власник) вказівник на вказаний об’єкт - ось чому unique_ptr
він не підлягає копіюванню.
Поки ви використовуєте розумні вказівники таким чином, щоб не порушувати неявного договору, який вони вимагають від вас дотримуватися, ви будете мати гарантію, що пам'ять не буде витікати, а відповідна політика власності на ваш об'єкт буде забезпечена. Сирі вказівники не дають вам цієї гарантії.
new int(3)
повертає покажчик на новеint
, якpd
і вказівник на новеdouble
.