shared_from_this выдает исключение - PullRequest
3 голосов
/ 09 июля 2010

Я пишу приложение на основе Qt с функциональностью, подобной Blender.

Он состоит из «фреймворка», который представляет собой систему плагинов GUI + и плагины.Плагины - это библиотеки Qt с объектами (например, Сферой, Ящиком и т. Д.), Которые могут быть в основном созданы и отображены.Все эти объекты, после их создания, хранятся в каркасе в некоторой структуре контейнера, которая хранит для них shared_ptr (так что на самом деле контейнер очень похож на vector<shared_ptr<INode>>)

То, что я хочу, этоиспользовать функцию shared_from_this () внутри одного из плагинов.Например, вот пример плагина (код изменен для ясности):

class Q_DECL_IMPORT SphereNode: public INode, public Sphere

Где INode - это:

class INode: public QObject, public boost::enable_shared_from_this<INode>

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

void SphereNode::update()
{
 foo(shared_from_this());
}

создает исключение boost::bad_weak_ptr.

Несколько замечаний о том, как создается этот SphereNode (класс Factory)

boost::shared_ptr<INode> NodeFactory::createNode(const QString& type, QString tag)
{
...
QPluginLoader loader(filesPlugin_[i]);
boost::shared_ptr<QObject> plugin(loader.instance());
boost::shared_ptr<INode> iNodePlugin = boost::shared_dynamic_cast<INode>(plugin);
return iNodePlugin;
}

Есть идеи?

1 Ответ

2 голосов
/ 09 июля 2010

Возможно, именно эта строка:

boost::shared_ptr<INode> iNodePlugin = boost::shared_dynamic_cast<INode>(plugin);

Что следует заменить на:

boost::shared_ptr<INode> iNodePlugin = dynamic_cast<INode*>(loader.instance())->shared_from_this();

Может быть, это как-то связано с:

boost::shared_ptr<QObject> plugin(loader.instance());

Здесь plugin становится владельцем возвращенного экземпляра. Однако в документации Qt говорится, что экземпляр будет автоматически освобожден QPluginLoader после уничтожения.

Тем не менее, это скорее вызовет ошибку (неопределенное поведение), чем обычное boost::bad_weak_ptr исключение.

Если вы хотите предотвратить это, вы можете указать null_deleter, который ничего не будет делать, когда счетчик ссылок достигнет 0.


Вы звоните shared_from_this() из конструктора или деструктора (прямо или косвенно)?

Если это так, то ваша проблема.

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

Чтобы избежать этой проблемы, вы можете получить shared_ptr к объекту в заводском методе (который у вас уже есть), когда объект был успешно построен.

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