Назад к вопросам
Middle
81
questionbank

Когда в умных указателях не будет вызван оператор delete для объекта?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

  • При использовании unique_ptr или shared_ptr, если указатель обнулен (ptr = nullptr) до того, как он вышел из области видимости или счетчик ссылок обнулился.
  • При использовании shared_ptr, если есть циклические ссылки между объектами, владеющими shared_ptr, что предотвращает обнуление счетчика ссылок. В этом случае помогает использование weak_ptr для одной из сторон цикла.
  • При передаче shared_ptr в функцию или метод по неконстантной ссылке (shared_ptr&) и последующем изменении указателя внутри этой функции/метода (например, присвоение nullptr), владение может быть утрачено, но объект может не быть удален, если существуют другие shared_ptr на этот объект.
  • При использовании shared_ptr или unique_ptr, если деструктор объекта бросает исключение. В этом случае поведение неопределено.
  • При использовании пользовательского deleter, предоставленного unique_ptr или shared_ptr, который не выполняет операцию delete для объекта.

Пример циклической ссылки с shared_ptr:

#include <memory>

struct Node {
    std::shared_ptr<Node> next;
    ~Node() { /* Деструктор */ }
};

int main() {
    std::shared_ptr<Node> node1 = std::make_shared<Node>();
    std::shared_ptr<Node> node2 = std::make_shared<Node>();

    node1->next = node2;
    node2->next = node1; // Циклическая ссылка

    // Здесь node1 и node2 выходят из области видимости,
    // но счетчик ссылок не обнуляется из-за цикла,
    // и деструкторы не будут вызваны.
    return 0;
}

Решение с weak_ptr:

#include <memory>

struct Node {
    std::weak_ptr<Node> next; // Использование weak_ptr
    ~Node() { /* Деструктор */ }
};

int main() {
    std::shared_ptr<Node> node1 = std::make_shared<Node>();
    std::shared_ptr<Node> node2 = std::make_shared<Node>();

    node1->next = node2;
    node2->next = node1;

    // Здесь node1 и node2 выходят из области видимости.
    // shared_ptr на node1 и node2 удаляются,
    // счетчики ссылок обнуляются, деструкторы вызываются.
    return 0;
}