В С++ 11 вы можете использовать shared_ptr<>
, чтобы установить отношение собственности с объектом или переменной и weak_ptr<>
, чтобы безопасно ссылаться на этот объект не принадлежащим ему образом.
Вы также можете использовать unique_ptr<>
для установления отношения собственности с объектом или переменной. Но что, если другие, не связанные с владельцем объекты хотят также ссылаться на этот объект? weak_ptr<>
в этом случае не поможет. Необработанные указатели полезны, но приносят различные недостатки (например, они могут быть автоматически инициализированы на nullptr, но это достигается с помощью методов, которые не соответствуют типам std::*_ptr<>
).
Что эквивалентно weak_ptr<>
для не владеющих ссылками на объекты, принадлежащие unique_ptr<>
?
Вот поясняющий пример, который напоминает что-то в игре, над которой я работаю.
class World
{
public:
Trebuchet* trebuchet() const { return m_trebuchet.get(); }
private:
std::unique_ptr< Trebuchet > m_trebuchet;
};
class Victim
{
public:
Victim( Trebuchet* theTrebuchet ) : m_trebuchet( theTrebuchet ) {}
~Victim()
{
delete m_trebuchet; // Duh. Oops. Dumb error. Nice if the compiler helped prevent this.
}
private:
Trebuchet* m_trebuchet; // Non-owning.
};
shared_ptr< Victim > createVictim( World& world )
{
return make_shared< Victim >( world.trebuchet() );
}
Здесь мы используем необработанный указатель для поддержания отношения без владельца к объекту, принадлежащему unique_ptr<>
в другом месте. Но является ли это самым лучшим, что мы можем сделать?
Надежда - это тип указателя, который:
- Похоже на другие современные типы указателей. Например.
std::raw_ptr<T>
. - Заменяет исходные указатели так, чтобы база кода, которая использует современные типы указателей, может найти все указатели с помощью поиска
_ptr<
(грубо). - Автоматически инициализирует значение nullptr.
Таким образом:
int* p; // Unknown value.
std::raw_ptr< int > p; // null.
Этот тип уже существует в С++ сейчас, он предлагается для будущего или представляет собой еще одну реализацию, широко доступную, например, Повысьте?