Скачиваний:
198
Добавлен:
05.07.2021
Размер:
16.53 Mб
Скачать

30. Передача в функцию и возврат из функции указателя типа unique_ptr. Примеры использования.

std::unique_ptr можно возвращать из функции по значению:

std::unique_ptr<Item> createItem()

{

     return std::make_unique<Item>();

}

int main()

{

    std::unique_ptr<Item> ptr = createItem();

    // Делаем что-либо

    return 0;

}

Передача std::unique_ptr в функцию

Если вы хотите, чтобы функция стала владельцем содержимого умного указателя, то передавать std::unique_ptr в функцию нужно по значению. Обратите внимание, поскольку семантика копирования отключена, то вам придётся использовать std::move() для фактической передачи ресурса в функцию:

class Item

{

public:

Item() { std::cout << "Item acquired\n"; }

~Item() { std::cout << "Item destroyed\n"; }

friend std::ostream& operator<<(std::ostream& out, const Item &item)

{

out << "I am an Item!\n";

return out;

}

};

void takeOwnership(std::unique_ptr<Item> item)

{

     if (item)

          std::cout << *item;

} // Item уничтожается здесь

int main()

{

    auto ptr = std::make_unique<Item>();

//    takeOwnership(ptr); // это не скомпилируется. Мы должны использовать семантику перемещения

    takeOwnership(std::move(ptr)); // используем семантику перемещения

    std::cout << "Ending program\n";

    return 0;

}

31. Использование класса auto_ptr. Особенности и пример использования.

Шаблон класса auto_ptr описывает смарт-указатель для выделенного объекта. Указатель должен быть либо null, либо обозначать объект, выделенный new. auto_ptr передает право владения, если сохраненное значение присваивается другому объекту (Он заменяет сохраненное значение после перемещения с пустым указателем.) Деструктор для auto_ptr<Type> удаляет выделенный объект. auto_ptr<Type> гарантирует, что выделенный объект автоматически удаляется при выходе точки управления за пределы блока даже с использованием созданного исключения. Не следует создавать два объекта auto_ptr<Type>, владеющих одним объектом.

Вы можете передать объект auto_ptr<Type> по значению в виде аргумента в вызове функции. auto_ptr не может быть элементом любого контейнера стандартной библиотеки. Вы не можете надежно управлять последовательностью объектов auto_ptr<Type> с помощью контейнера стандартной библиотеки C++.

#include <iostream>

#include <memory>

using namespace std;

int main(int argc, char **argv)

{

int *i = new int;

auto_ptr<int> x(i);

auto_ptr<int> y;

y = x;

cout << x.get() << endl; // Print NULL

cout << y.get() << endl; // Print non-NULL address i

return 0;

}

32. Передача функции удаления указателю unique_ptr. Примеры использования.

33. Класс интеллектуального указателя weak_ptr. Методы класса указателя weak_ptr. Особенности и пример использования.

Иногда объект должен хранить способ доступа к базовому объекту shared_ptr , не вызывая увеличения счетчика ссылок. Как правило, такая ситуация возникает при наличии циклических ссылок между экземплярами shared_ptr.

Оптимальное проектирование заключается в том, чтобы не допустить совместного владения указателями, когда это возможно. Однако, если требуется совместное владение экземплярами shared_ptr, следует избегать циклических ссылок между ними. Если циклические ссылки нецелесообразны или еще предпочтительнее по какой-либо причине, используйте weak_ptr , чтобы предоставить одному или нескольким владельцам слабую ссылку на другой shared_ptr. С помощью weak_ptrможно создать shared_ptr, который присоединяется к существующему набору связанных экземпляров, но только в том случае, если ресурс базовой памяти по-прежнему является допустимым. Сам weak_ptr не участвует в подсчете ссылок и, следовательно, не может препятствовать переходу на нулевое значение счетчика ссылок. Однако можно использовать weak_ptr, чтобы попытаться получить новую копию shared_ptr, с которой он был инициализирован. Если память уже удалена, оператор bool weak_ptrвозвращает false. Если память по-прежнему является допустимой, новый общий указатель увеличивает счетчик ссылок и гарантирует, что память будет действительной, пока переменная shared_ptr остается в области.

auto intPtr = make_shared<int>(42);

weak_ptr<int> weakPtr(intPtr);//weakPtr слабосвязан с intPtr; счетчик ссылок intPtr неизменен

---------------------------------------------------------------------------------------------------- auto intPtr = make_shared<int>(42);

weak_ptr<int>wp(intPtr);//wp слабосвязан с intPtr; счетчик ссылок intPtr неизменен

if (shared_ptr<int>np = wp.lock()) {//true, если np не нулевой, в условии if np совместно использует свой объект с указателем intPtr //... 

}