Создание уязвимого места & lt; & gt; из необработанного указателя

Я хотел бы обернуть элемент необработанного указателя в некоторый умный указатель, чтобы предотвратить удаление внутри развивающегося класса. Владелец объекта под указателем находится вне класса. Итак, похоже 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 из необработанного указателя (если есть)?

9

Решение

Вы не можете этого сделать, вы можете создать слабый_птр только из shared_ptr или другого слабого_птр.
Таким образом, идея заключается в том, чтобы владелец указателя содержал shared_ptr вместо необработанного указателя, и все должно быть в порядке.

11

Другие решения

Единственный способ сделать это, заполучив shared_ptr или же weak_ptr который владеет указателем, в противном случае weak_ptr не может найти существующего владельца, чтобы разделить с ним право собственности.

Единственный способ получить shared_ptr из необработанного указателя, который уже принадлежит другому shared_ptr если Bar происходит от enable_shared_from_this<Bar>тогда вы можете сделать

m_bar = bar->shared_from_this();
7

Цель слабого указателя — не использовать необработанный указатель, если он был удален. Однако, если у вас есть необработанный указатель, слабый указатель не сможет узнать, что он был удален. Вместо этого у вас должен быть файл shared_ptr, который «владеет» необработанным указателем. Затем вы можете создать weak_ptr, который ссылается на shared_ptr.

Когда shared_ptr выходит из области видимости и является последним «сильным» умным указателем, он автоматически удаляет необработанный указатель. Затем, когда вы попытаетесь заблокировать weak_ptr, он увидит, что не осталось «сильного» указателя и, следовательно, объект не существует.

4

Все, что вы сказали, кажется вполне разумным, за исключением одного:

void setBar(const Bar *bar)

Это не должно принимать необработанный указатель. Это должно занять weak_ptr в идеале или, возможно, shared_ptr если у вас есть веские аргументы.

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

2

Передайте общий указатель вместо необработанного указателя и создайте свой слабый указатель из этого общего указателя. Это действительно единственный способ, если владелец указателя находится вне класса.

1
По вопросам рекламы [email protected]