std::unique_ptr — це розумний вказівник, представлений у C++11. Він автоматично керує динамічно розподіленими ресурсами в купі. Розумні вказівники — це лише обгортки навколо звичайних старих вказівників, які допомагають запобігти поширеним помилкам. А саме, забути видалити вказівник і спричинити витік пам’яті або випадкове видалення вказівника двічі чи неправильним способом. Їх можна використовувати подібно до стандартних покажчиків. Вони автоматизують деякі ручні процеси, які викликають типові помилки.
Передумови: Покажчик у C++ , Розумні покажчики в C++.
Синтаксис
unique_ptr< A>ptr1 (новий A )>
тут,
- унікальний_ptr : Він визначає тип std::unique_ptr. В даному випадку - об'єкт типу А.
- новий А : об’єкт типу A динамічно розподіляється в купі за допомогою оператора new.
- ptr1 : це ім’я змінної std::unique_ptr.
Що відбувається, коли використовується unique_ptr?
Коли ми пишемо unique_ptr ptr1 (новий A), пам’ять виділяється в купі для екземпляра типу даних A. ptr1 ініціалізується та вказує на щойно створений об’єкт A. Тут ptr1 є єдиним власником новоствореного об’єкта A, і він керує часом життя цього об’єкта. Це означає, що коли ptr1 скидається або виходить за межі, пам’ять автоматично звільняється, а об’єкт A знищується.
Коли використовувати unique_ptr?
Коли потрібна власність на ресурс. Коли ми хочемо єдиного або ексклюзивного володіння ресурсом, ми повинні вибрати унікальні вказівники. Тільки один унікальний покажчик може вказувати на один ресурс. Отже, один унікальний покажчик не можна скопіювати в інший. Крім того, це полегшує автоматичне очищення, коли динамічно виділені об’єкти виходять за межі, і допомагає запобігти витокам пам’яті.
Примітка: нам потрібно використовувати файл заголовка для використання цих розумних покажчиків.
Приклади Unique_ptr
приклад 1:
Давайте створимо структуру A, і вона матиме метод під назвою printA для відображення тексту. Тоді в основному розділі давайте створимо унікальний вказівник, який вказуватиме на структуру A. Отже, на цьому етапі у нас є екземпляр структури A, а p1 містить вказівник на нього.
C++
// C++ Program to implement unique_ptr> #include> #include> using> namespace> std;> > struct> A {> >void> printA() { cout <<>'A struct....'> << endl; }> };> > int> main()> {> >unique_ptr p1(> new> A);> >p1->printA();> > >// displays address of the containing pointer> >cout << p1.get() << endl;> >return> 0;> }> |
як знайти приховані програми на android
>
xor в java
>Вихід
A struct.... 0x18dac20>
Приклад 2
Тепер давайте створимо інший вказівник p2 і спробуємо скопіювати вказівник p1 за допомогою оператора присвоювання (=).
C++
// C++ Program to implement unique_ptr> #include> #include> using> namespace> std;> > struct> A {> >void> printA() { cout <<>'A struct....'> << endl; }> };> int> main()> {> >unique_ptr p1(> new> A);> >p1->printA();> > >// displays address of the containing pointer> >cout << p1.get() << endl;> > >// will give compile time error> >unique_ptr> p2 = p1;> >p2->printA();> >return> 0;> }> |
>
>
Вихід
main.cpp: In function ‘int main()’: main.cpp:18:24: error: use of deleted function ‘std::unique_ptr::unique_ptr(const std::unique_ptr&) [with _Tp = A; _Dp = std::default_delete]’ 18 | unique_ptr p2 = p1; | ^~ In file included from /usr/include/c++/11/memory:76, from main.cpp:3: /usr/include/c++/11/bits/unique_ptr.h:468:7: note: declared here 468 | unique_ptr(const unique_ptr&) = delete; | ^~~~~~~~~~>
Наведений вище код викличе помилку часу компіляції, оскільки ми не можемо призначити покажчик p2 до p1 у випадку унікальних покажчиків. Ми повинні використовувати семантику переміщення для такої мети, як показано нижче.
рівність рядків у java
Приклад 3
Управління об'єктом типу A за допомогою семантики переміщення.
C++
// C++ Program to implement unique_ptr> #include> #include> using> namespace> std;> > struct> A {> >void> printA() { cout <<>'A struct....'> << endl; }> };> int> main()> {> >unique_ptr p1(> new> A);> >p1->printA();> > >// displays address of the containing pointer> >cout << p1.get() << endl;> > >// now address stored in p1 shpould get copied to p2> >unique_ptr> p2 = move(p1);> > >p2->printA();> >cout << p1.get() << endl;> >cout << p2.get() << endl;> >return> 0;> }> |
>
>Вихід
A struct.... 0x2018c20 A struct.... 0 0x2018c20>
Зауважте, щойно адреса в покажчику p1 скопійована до вказівника p2, адреса вказівника p1 стає NULL(0), а адреса, збережена p2, тепер збігається з адресою, збереженою p1, показуючи, що адреса в p1 була передана вказівнику p2 з використанням семантики переміщення.