Какая разница между 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 больше не существует, а не пытается получить доступ к уничтоженному объекту.