#include #include // для использования умных указателей #include using namespace std; // класс, чтобы понять работу конструкторов-деструкторов struct XX { int *px; XX(int v) { px = new int(v); cout << "XX("< p) // передача в функцию по значению { cout << "f(): "; if (p.get()) cout << p.get() << " " << *p; cout << endl; } void g(unique_ptr &p) // передача в функцию по ссылке { cout << "g(): "; if (p.get()) cout << p.get() << " " << *p; cout << endl; } void h(unique_ptr &&p) // передача в функцию по rvalue { cout << "h(): "; if (p.get()) cout << p.get() << " " << *p; cout << endl; } // макрос печати для сокращения записи #define print(s,p) cout << s << p.get() << " " << (p?*p:0) << endl #define printXX(s,p) cout << s << p.get() << " " << (p? *(p->px):0) << endl int main() { // создаем через конструктор unique_ptr p1(new int(10)); print("p1 ",p1); // создаем через make_unique //unique_ptr p2 = make_unique(20); // можно так auto p2 = make_unique(20); // а так проще print("p2 ",p2); //unique_ptr p1 = p2; - так запрещено // присваиваем через перемещение cout << "\n p1 = move(p2); -----------\n"; p1 = move(p2); print("p1 ",p1); print("p2 ",p2); // то же самое с классами unique_ptr x1(new XX(100)); unique_ptr x2(new XX(200)); printXX("x1 ",x1); printXX("x2 ",x2); cout << "\n p1 = move(p2); -----------\n"; x1 = move(x2); printXX("x1 ",x1); // обратите внимание на деструктор printXX("x2 ",x2); // еще создание по существующему указателю cout << "\n from ordinary ptr -----------\n"; int *q3 = new int(30); // обычный указатель unique_ptr p3 = make_unique(*q3); unique_ptr p4(q3); print("p3 ",p3); print("p4 ",p4); cout << "q3 " << q3 << " " << *q3 << endl; // передача в функцию cout << "\n function call -----------\n"; unique_ptr q1 = make_unique(123); //f(q1); - нельзя g(q1); print("q1 ",q1); f(move(q1)); print("q1 ",q1); h(move(p1)); print("p1 ",p1); // создание указателя на массив (delete []) unique_ptr p5 = make_unique(10); // auto p5 = ... return 0; }