Я хотел бы обернуть элемент необработанного указателя в некоторый умный указатель, чтобы предотвратить удаление внутри развивающегося класса. Владелец объекта под указателем находится вне класса. Итак, похоже boost::shared_ptr
а также std::auto_ptr
не подходит. Ниже приведен сокращенный пример:
class Foo {
boost::weak_ptr<Bar> m_bar;
public:
void setBar(const Bar *bar) { // bar created on heap
m_bar = bar; // naturally compilation error
}
};
Конечно, это вызывает ошибку компиляции. Как правильно инициализировать weak_ptr
из необработанного указателя (если есть)?
Вы не можете этого сделать, вы можете создать слабый_птр только из shared_ptr или другого слабого_птр.
Таким образом, идея заключается в том, чтобы владелец указателя содержал shared_ptr вместо необработанного указателя, и все должно быть в порядке.
Единственный способ сделать это, заполучив shared_ptr
или же weak_ptr
который владеет указателем, в противном случае weak_ptr
не может найти существующего владельца, чтобы разделить с ним право собственности.
Единственный способ получить shared_ptr
из необработанного указателя, который уже принадлежит другому shared_ptr
если Bar
происходит от enable_shared_from_this<Bar>
тогда вы можете сделать
m_bar = bar->shared_from_this();
Цель слабого указателя — не использовать необработанный указатель, если он был удален. Однако, если у вас есть необработанный указатель, слабый указатель не сможет узнать, что он был удален. Вместо этого у вас должен быть файл shared_ptr, который «владеет» необработанным указателем. Затем вы можете создать weak_ptr, который ссылается на shared_ptr.
Когда shared_ptr выходит из области видимости и является последним «сильным» умным указателем, он автоматически удаляет необработанный указатель. Затем, когда вы попытаетесь заблокировать weak_ptr, он увидит, что не осталось «сильного» указателя и, следовательно, объект не существует.
Все, что вы сказали, кажется вполне разумным, за исключением одного:
void setBar(const Bar *bar)
Это не должно принимать необработанный указатель. Это должно занять weak_ptr
в идеале или, возможно, shared_ptr
если у вас есть веские аргументы.
Фактический владелец рассматриваемого объекта должен построить weak_ptr
и чем позвонить setBar
с этим. Это сохраняет семантику владения. Похоже, что то, что вы делаете, заставляет владеющий объект взять необработанный указатель и передать его setBar
, Это создает семантический разрыв в владении объектом.
Передайте общий указатель вместо необработанного указателя и создайте свой слабый указатель из этого общего указателя. Это действительно единственный способ, если владелец указателя находится вне класса.