Какие знаешь виды умных указателей · C/C++ Backend — JobPilot

Какие знаешь виды умных указателей

C/C++ Backend · 22%
Вопрос 4127 / #
Пример ответа

Коротко: Я знаю и активно использовал в C++ следующие виды умных указателей: std::unique_ptr, std::shared_ptr, std::weak_ptr, а также, в рамках стандартной библиотеки, std::auto_ptr (устаревший).

  • std::unique_ptr
  • std::shared_ptr
  • std::weak_ptr
  • std::auto_ptr (устаревший)
Ключевые идеи:
  • std::unique_ptr обеспечивает эксклюзивное владение ресурсом и перемещаемую семантику, идеален для управления единственным владельцем.
  • std::shared_ptr реализует подсчёт ссылок для совместного владения, но требует осторожности из-за накладных расходов и риска циклических ссылок.
  • std::weak_ptr используется вместе с shared_ptr для разрыва циклических зависимостей, не увеличивая счётчик ссылок.
Пример: В моём проекте для управления кэшем в памяти я использовал std::unique_ptr для эксклюзивного владения буферами данных и std::shared_ptr для разделяемых конфигурационных объектов между несколькими модулями, с weak_ptr для наблюдателей, чтобы избежать утечек памяти.
Пример использования std::unique_ptr и std::shared_ptr для управления ресурсами в C++
cpp
#include <memory>
#include <iostream>

class Resource {
public:
    Resource() { std::cout << "Resource acquired\n"; }
    ~Resource() { std::cout << "Resource destroyed\n"; }
    void use() { std::cout << "Resource in use\n"; }
};

int main() {
    // std::unique_ptr: эксклюзивное владение
    std::unique_ptr<Resource> uniquePtr = std::make_unique<Resource>();
    uniquePtr->use();
    // Перемещение владения
    std::unique_ptr<Resource> movedPtr = std::move(uniquePtr);
    if (!uniquePtr) {
        std::cout << "uniquePtr is now null after move\n";
    }

    // std::shared_ptr: совместное владение
    std::shared_ptr<Resource> sharedPtr1 = std::make_shared<Resource>();
    {
        std::shared_ptr<Resource> sharedPtr2 = sharedPtr1; // Счётчик ссылок увеличивается до 2
        std::cout << "Use count inside scope: " << sharedPtr1.use_count() << '\n';
    } // sharedPtr2 выходит из области видимости, счётчик уменьшается до 1
    std::cout << "Use count outside scope: " << sharedPtr1.use_count() << '\n';

    // std::weak_ptr: для наблюдения без владения
    std::weak_ptr<Resource> weakPtr = sharedPtr1;
    if (auto locked = weakPtr.lock()) {
        locked->use();
        std::cout << "Weak pointer successfully locked, use count: " << sharedPtr1.use_count() << '\n';
    } else {
        std::cout << "Resource no longer available\n";
    }

    return 0; // Ресурсы автоматически освобождаются
}
Вопросы для интервьюера:
  • В каких сценариях вы предпочитаете std::unique_ptr над std::shared_ptr?Я выбираю unique_ptr для ресурсов с единственным владельцем, таких как фабричные объекты или кэши, чтобы избежать накладных расходов на подсчёт ссылок и обеспечить чёткую семантику владения.
  • Как вы избегаете циклических ссылок при использовании std::shared_ptr?Я использую std::weak_ptr для ссылок, которые не должны увеличивать счётчик, например, в паттернах наблюдатель или кэшах, чтобы разорвать циклы и позволить корректное освобождение памяти.
Практический совет (на неделю):
  1. Начните с std::unique_ptr по умолчанию для управления ресурсами и переходите к shared_ptr только при необходимости совместного владения.
  2. Регулярно проверяйте код на наличие циклических ссылок с помощью инструментов вроде Valgrind или AddressSanitizer, особенно при интенсивном использовании shared_ptr.
C/C++ Backend
Общий
22%
Навигация
Работаешь ли на данный момент
Следующий: Есть ли военный билет
Предыдущий: Работаешь ли на данный момент

Мы используем cookie для улучшения сайта. Продолжая пользоваться сайтом, вы соглашаетесь с политикой cookie и политикой конфиденциальности.