Возвращение общего указателя из типа возврата слабого указателя - PullRequest
1 голос
/ 15 мая 2019

Это безопасно сделать?Почему моя среда IDE предупреждает меня об этом?

std::weak_ptr<SomeClass> getStatus() 
{
    return _mStatus;
}
private:
std::shared_ptr<SomeClass> _mStatus = std::make_shared<SomeClass>();

Моя среда IDE сообщает:

Возвращает std::shared_ptr<SomeClass> из функции, возвращающей std::weak_ptr<SomeClass>.Класс std::shared_ptr<SomeClass> не совместим с классом std::weak_ptr<SomeClass>

Это безопасно или нет?Должен ли я игнорировать это предупреждение?У меня где-то здесь авария, и я думаю, что это может быть причиной.

Ответы [ 2 ]

3 голосов
/ 15 мая 2019

Ваш IDE не так;код в порядке.Существует неявное преобразование из shared_ptr в weak_ptr;возвращение shared_ptr из функции с типом возврата weak_ptr вызовет преобразование.Я только что проверил ваш код с тремя разными компиляторами (gcc 8.3, msvc 2019, xcode 10), и все они выполнили преобразование без предупреждений.Возврат weak_ptr совершенно безопасен, потому что он автоматически станет нулевым, если исходный shared_ptr исчезнет, ​​здесь нет опасности висячего указателя.

Похоже, что сообщение об ошибке означает, что ваш компилятор считает преобразование недействительнымявляется недействительным;может быть, вы используете очень старую версию стандартной библиотеки?Я не помню, была ли когда-либо черновая версия weak_ptr, где преобразование из shared_ptr было явным или требовало вызова функции.

0 голосов
/ 15 мая 2019

Насколько я понимаю, в то время как shared_ptr выполняет подсчет ссылок, слабый_ptr - нет.Итак, насколько это безопасно, зависит от того, как вы его используете.Риск состоит в том, что вы возвращаете weak_ptr в _mStatus, а затем объект-владелец (который имеет ссылку на shared_ptr) исчезает, в результате чего ref-count становится равным нулю, и, следовательно, память освобождается, но ваша слабая ссылка на негоТеперь обращаясь к свободной памяти, вызывающей хаос.Теперь, weak_ptr имеет защиту, что, если вы получите значение из него, и оно уже было бесплатным, оно даст вам вновь инициализированный указатель (то есть нулевой указатель).Но, если ваш вызывающий получает слабый_птр и получает от него значение указателя (возможно, копирование в примитивный тип указателя), а затем объект-владелец исчезает, тогда это необработанное значение указателя теперь является поддельным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...