Уникальный указатель - это объект, который владеет другим объектом и управляет этим другим объектом через указатель.
Точнее, уникальный указатель - это объект u, который хранит указатель на второй объект p и будет утилизировать p, когда u сам уничтожается (например, при выходе из области блока). В этом контексте говорят, что у вас есть p.
Механизм, с помощью которого u утилизирует p, известен как связанный с p-удалителем, функциональный объект, правильный вызов которого приводит к соответствующему расположению p (обычно его удалению).
Пусть обозначение u.p обозначает указатель, сохраненный u, и пусть u.d обозначает связанный с ним удалитель. По запросу u может сбросить (заменить) u.p и u.d с помощью другого указателя и удаляющего устройства, но должен надлежащим образом утилизировать принадлежащий ему объект с помощью соответствующего удаляющего устройства, прежде чем такая замена будет считаться завершенной.
Кроме того, вы можете по запросу передать право собственности на другой уникальный указатель u2. После завершения такой передачи выполняются следующие постусловия:
u2.p равно предпереносу u.p,
u.p равно нульптру и
Если состояние, предшествующее передаче u.d, сохраняется, то такое состояние передается u2.d.
Как и в случае сброса, u2 должен надлежащим образом утилизировать свой объект, находящийся в собственности до передачи, через ассоциированный с предварительной передачей удаленец до того, как передача права собственности будет считаться завершенной.
Каждый объект типа U, полученный из шаблонаunique_ptr, указанного в этом подпункте, имеет строгую семантику владения, указанную выше, уникальным указателем. В частичном удовлетворении этой семантики каждый такой U является MoveConstructible и MoveAssignable, но не является ни CopyConstructible, ни CopyAssignable. Параметр шаблона Tunique_ptrможет быть неполным типом.
Использованиеunique_ptrвключает обеспечение безопасности исключения для динамически выделенной памяти, передачу права собственности на динамически выделенную память функции и возврат динамически выделенной памяти из функции.
Если T является типом массива (например, unique_ptr), интерфейс слегка изменяется:
Указатели на типы, полученные из T, отвергаются конструкторами и сбрасываются.
Тип по умолчанию для параметра шаблона Ddefault_delete. Аргумент шаблона D, предоставленный клиентом, должен быть типом объекта функции, lvalue-ссылкой на функцию или lvalue-ссылкой на тип объекта функции, для которого, учитывая значение d типа D и значение ptr типа unique_ptr::pointer, выражение d(ptr) является действительным и имеет эффект удаления указателя в зависимости от того, что подходит для этого удаляющего.
Если тип D не является эталонным типом, D должен удовлетворять требованиям Destructible.
Если тип<remove_reference<D>::type::pointer>существует, он должен удовлетворять требованиям NullablePointer.
unique_ptr
public
types
typedefсм. документациюуказатель;
Еслиremove_reference<D>::type::pointerсуществует, то это должно быть синонимомremove_reference<D>::type::pointer. В противном случае это будет синонимом Т*.
typedefсм._documentationelement_type;
Если T является типом массива, то элемент_type равен T. В противном случае, если T является типом в форме U[], элемент_тип равен U
Requires: D shall satisfy the requirements of DefaultConstructible, and that construction shall not throw an exception.
Effects: Constructs a unique_ptr which owns p, initializing the stored pointer with p and value initializing the stored deleter.
Postconditions: get() == p. get_deleter() returns a reference to the stored deleter.
Remarks: If this constructor is instantiated with a pointer type or reference type for the template argument D, the program is ill-formed. This constructor shall not participate in overload resolution unless:
Если T не является типом массива и указатель неявно преобразуется в указатель.
Если T — это тип массива, то Pointer — это более квалифицированный указатель CV на элемент_тип.
Подпись этого конструктора зависит от того, является ли D эталонным типом.
Если D не относится к типу A, то подписьunique_ptr(pointer p, const A& d)
.
Если D является lvalue-референтным типом A&, то подпись<unique_ptr(pointer p, A& d)>
.
Если D — это lvalue-референтный тип const A&, то подпись<unique_ptr(pointer p, const A& d)>
.
Требуется: Либо
D не является lvalue-ссылочным типом и d является lvalue или const rvalue. D должен удовлетворять требованиям CopyConstructible, и конструктор D не должен делать исключения. Это<unique_ptr>будет содержать копию d.
D — это lvalue-референтный тип, а d — lvalue. Тип, на который ссылается D, не обязательно должен быть CopyConstructible или MoveConstructible. Это<unique_ptr>будет содержать D, который относится к lvalue d.
Эффекты: Конструирует объект<unique_ptr>, который владеет p, инициализируя сохраненный указатель с p и инициализируя удаляющее устройство, как описано выше.
Пост-условия:<get() == p>.<get_deleter()>возвращает ссылку на хранимый удалитель. Если D является эталонным типом, то<get_deleter()>возвращает ссылку на значение d.
Замечания: Этот конструктор не должен участвовать в разрешении перегрузки, если:
Если T не является типом массива и указатель неявно преобразуется в указатель.
Если T — это тип массива, то Pointer — это более квалифицированный указатель CV на элемент_тип.
Подпись этого конструктора зависит от того, является ли D эталонным типом.
Если D не относится к типу A, то подписьunique_ptr(pointer p, A&& d).
Если D является lvalue-референтным типом A&, то подпись<unique_ptr(pointer p, A&& d)>.
Если D — это lvalue-референтный тип const A&, то подпись<unique_ptr(pointer p, const A&& d)>
.
Требуется: Либо
D не является lvalue-ссылочным типом и d является non-const rvalue. D должен удовлетворять требованиям MoveConstructible, и конструктор движения D не должен делать исключения. Это<unique_ptr>будет содержать движение стоимости, построенное из d.
D — это lvalue-референтный тип, а d — rvalue, программа плохо сформирована.
Эффекты: Конструирует объект<unique_ptr>, который владеет p, инициализируя сохраненный указатель с p и инициализируя удаляющее устройство, как описано выше.
Пост-условия:<get() == p>.<get_deleter()>возвращает ссылку на хранимый удалитель. Если D является эталонным типом, то<get_deleter()>возвращает ссылку на значение d.
Замечания: Этот конструктор не должен участвовать в разрешении перегрузки, если:
Если T не является типом массива и указатель неявно преобразуется в указатель.
Если T — это тип массива, то Pointer — это более квалифицированный указатель CV на элемент_тип.
Требуется: Если D не является эталонным типом, D должен удовлетворять требованиям MoveConstructible. Конструкция очистителя из значения r типа D не должна приводить к исключению.
Эффекты: Построение<unique_ptr>путем передачи права собственности от u к *. Если D является эталонным типом, этот удалитель является копией, созданной из удалителя u; в противном случае этот удалитель перемещается из удалителя u.
Постусловия:<get()>дает значение u.get(), полученное до начала строительства.<get_deleter()>возвращает ссылку на сохраненный удалитель, который был построен из u.get_deleter(). Если D является эталонным типом, то<get_deleter()>и<u.get_deleter()>оба ссылаются на один и тот же очиститель lvalue.
Requires: If E is not a reference type, construction of the deleter from an rvalue of type E shall be well formed and shall not throw an exception. Otherwise, E is a reference type and construction of the deleter from an lvalue of type E shall be well formed and shall not throw an exception.
Замечания: Этот конструктор не должен участвовать в разрешении перегрузки, если:
unique_ptr<U, E>::pointer is implicitly convertible to pointer,
U не является типом массива, и
либо D является эталонным типом, а E - тем же типом, что и D, либо D не является эталонным типом, и E косвенно конвертируется в D.
Эффекты: Построение a<unique_ptr>путем передачи права собственности от u к *. Если E является эталонным типом, этот удалитель является копией, созданной из удалителя u; в противном случае этот удалитель перемещается из удалителя u.
Пост-условия:<get()>дает значение<u.get()>, полученное до строительства.<get_deleter()>возвращает ссылку на сохраненный удалитель, который был построен из<u.get_deleter()>.
Требуется: Если D не является эталонным типом, D должен удовлетворять требованиям MoveAssignable, и назначение удаляющего из значения r типа D не должно приводить к исключению. В противном случае D является эталонным типом;<remove_reference<D>::type>должен удовлетворять требованиям CopyAssignable, и назначение удаляющего из значения типа D не должно приводить к исключению.
Эффекты: Передача права собственности с u на *это, как если бы по телефону<reset(u.release())>, за которым следует<get_deleter() = std::forward<D>(u.get_deleter())>.
Требуется: Если Е не является эталонным типом, то назначение очистителя из r-значения типа Е должно быть хорошо сформировано и не должно приводить к исключению. В противном случае Е является эталонным типом, и назначение очистителя из значения l типа Е должно быть хорошо сформировано и не должно приводить к исключению.
Замечания: Этот оператор не должен участвовать в разрешении перегрузки, если:
<unique_ptr<U, E>::pointer>неявно не конвертируется в указатель и
U не является типом массива.
Эффекты: Переносит право собственности с u на * это, как если бы позвонив<reset(u.release())>, а затем<get_deleter() = std::forward<E>(u.get_deleter())>.
Requires: The expression get_deleter()(get()) shall be well formed, shall have well-defined behavior, and shall not throw exceptions.
Effects: assigns p to the stored pointer, and then if the old value of the stored pointer, old_p, was not equal to nullptr, calls get_deleter()(old_p). Note: The order of these operations is significant because the call to get_deleter() may destroy *this.
Postconditions: get() == p. Note: The postcondition does not hold if the call to get_deleter() destroys *this since this->get() is no longer a valid expression.
Замечания: Этот конструктор не должен участвовать в разрешении перегрузки, если:
Если T не является типом массива и указатель неявно преобразуется в указатель.
Если T — это тип массива, то Pointer — это более квалифицированный указатель CV на элемент_тип.
<
voidreset()noexcept;
>
Требуется: Выражение<get_deleter()(get())>должно быть хорошо сформировано, должно иметь четко определенное поведение и не должно содержать исключений.
Эффекты: присваивает nullptr хранимому указателю, а затем, если старое значение хранимого указателя, old_p, не было равно nullptr, вызывает<get_deleter()(old_p)>. Примечание: Порядок этих операций значителен, потому что призыв к<get_deleter()>может уничтожить * это.
Постусловия:<get() == p>. Примечание: Пост-условие не выполняется, если призыв к<get_deleter()>уничтожает * это, поскольку<this->get()>больше не является действительным выражением.
Требуется:<get_deleter()>должен быть сменным и не должен бросать исключение под свопом.
Эффекты: Вызывает своп на хранимых указателях и на хранимых удалителях *this и u.
Статья Class template unique_ptr раздела The Boost C++ Libraries BoostBook Documentation Subset Reference может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.