Какая разница между raw pointer и weak_ptr?

Как в заголовке. На этот вопрос, вероятно, уже есть ответ, но я не смог его найти.

Ответы

Ответ 1

Основная концептуальная разница между голой указателем и weak_ptr заключается в том, что если объект, на который указывает, будет уничтожен, голый указатель не расскажет вам об этом. Это называется обвисший указатель: указатель на объект, который не существует. Обычно их трудно отследить.

weak_ptr будет. Чтобы использовать weak_ptr, вы должны сначала преобразовать его в shared_ptr. И если этот shared_ptr не указывает ни на что, объект был удален.

Например:

#include <iostream>
#include <memory>

std::weak_ptr<int> wp;

void test()
{
    auto spt = wp.lock(); // Has to be copied into a shared_ptr before usage
    if (spt) {
        std::cout << *spt << "\n";
    } else {
        std::cout << "wp is expired\n";
    }
}

int main()
{
    {
        auto sp = std::make_shared<int>(42);
        wp = sp;
        test();
    }
    test();
}

Выход

42
wp is expired

Ответ 2

Необработанный указатель (по крайней мере, обычно) - просто адрес. Вы не можете ничего рассказать о том, на что он указывает, от самого указателя.

A weak_ptr всегда ассоциируется с shared_ptr, поэтому нам, вероятно, нужно начать с shared_ptr, чтобы иметь смысл weak_ptr.

A shared_ptr подсчитывается ссылка, поэтому он отслеживает, сколько ссылок (указателей) на объект существует, и автоматически уничтожает объект, когда больше ссылок на этот объект не существует.

Как я уже говорил, a weak_ptr связано с shared_ptr. В отличие от shared_ptr, существование a weak_ptr не увеличивает счетчик ссылок для объекта pointee. Чтобы использовать weak_ptr, вы должны сначала преобразовать его в shared_ptr. Если текущий счетчик ссылок положительный, это будет успешным, и преобразование weak_ptr в shared_ptr увеличит счетчик ссылок, чтобы показать, что преобразованный указатель является "реальной" ссылкой на объект. Если, с другой стороны, счетчик ссылок уже равен нулю (это означает, что объект pointee уже был уничтожен) попытка конвертировать weak_ptr в shared_ptr просто завершится неудачей.

A shared_ptr означает совместное владение объектом pointee. Объект pointee будет существовать до тех пор, пока существует хотя бы один shared_ptr для этого объекта, но как только последний shared_ptr будет уничтожен, так и объект pointee.

A weak_ptr означает не имеющий доступа доступ к объекту pointee. Он разрешает доступ, если объект существует. Если объект был уничтожен, он сообщает вам, что объект pointee больше не существует, а не пытается получить доступ к уничтоженному объекту.