повысить приведение shared_ptr к пустоте * - PullRequest
5 голосов
/ 29 марта 2012

Я использую libev, который требует преобразования моих данных в void *, чтобы соответствовать их предопределенным структурам. Мне нужно привести boost :: shared_ptr к void *, а затем привести void * обратно к boost :: shared_ptr. Вот мой код для этого

void foo(boost::shared_ptr<string>& a_string)
{
 void* data = (void*)a_string.get();
 boost::shared_ptr<string> myString((string*)data);
}

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

Есть ли способ увеличить / уменьшить значение use_count вручную? В идеале я увеличил бы значение use_count, когда произвел приведение к void *, передал бы свой void * другой функции, вернул void * обратно в shared_ptr и уменьшил бы use_count.

Или, если кто-то знает другое решение этой проблемы, я мог бы использовать любую помощь.

Ответы [ 3 ]

4 голосов
/ 29 марта 2012

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

1 голос
/ 29 марта 2012

Если вы приведете void* обратно к boost::shared_ptr, это будет новый общий указатель, не связанный с какими-либо другими общими указателями, которые также указывают на память, указанную переменной `void*.

Я думаю, вам нужно добавить поддержку enabled_shared_from_this к классам, которые вы собираетесь использовать с shared_ptrs с этим кодом.

Это позволит вам получить shared_ptr, который будет делиться правами владения с существующими shared_ptrs.через функцию-член (shared_from_this) в вашем классе.

См. boost enabled_shared_from_this docs для получения более подробной информации.

0 голосов
/ 29 марта 2012

Попробуйте weak_ptr:

shared_ptr<int> p(new int(5));
weak_ptr<int> q(p);

Редактировать: Извините, я не правильно прочитал вопрос; Вы можете попытаться сохранить его в области видимости, чтобы он не очищался

Обновление: Слабый указатель может фактически работать, если вы ссылаетесь на переменную после вашего вызова, потому что тогда компилятор не сможет оптимизировать уничтожение a_string shared_ptr (следовательно, предотвратить decr refcount to zero -> release) прежде чем использовать базовый указатель

чтобы вы могли сделать это:

void foo(boost::shared_ptr<string>& a_string)
{
 void* data = (void*)a_string.get();
 boost::shared_ptr<string> myString((string*)data);
 weak_ptr<string> temp(a_string); // prevent destruction before above line
 // or reference a_string in any meaningless way that CANT be optimised out 
 // pre-emptively by the compiler
}

a_string может потребоваться ссылка где-либо за пределами foo в зависимости от контекста и того, что вы делаете с указателем void (и если он создает новую копию или работает с данными void)

...