shared_from_this抛出异常

时间:2010-07-09 09:11:11

标签: c++ qt boost

我正在编写基于Qt的应用程序,具有类似Blender的功能。

它包含一个“框架”,即GUI +插件系统和插件。插件是带有对象(例如Sphere,Box等)的Qt dll,它们基本上可以创建和显示。所有这些对象一旦被创建,就会以某种容器结构存储在框架中,该容器结构将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 个答案:

答案 0 :(得分:2)

也许就是这一行:

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 documentation表示实例将在销毁时由QPluginLoader自动释放。

但是,这会导致段错误(未定义的行为)而不是常规的boost::bad_weak_ptr异常。

如果您想阻止这种情况,您可以指定null_deleter,当参考计数器达到0时,该shared_from_this()将不执行任何操作。


您是从构造函数还是析构函数(直接或间接)调用shared_ptr

如果是,那就是你的问题。

当你在构造函数中时,该对象尚未完全创建,因此对其shared_ptr无效。

要避免此问题,您可以在成功构建对象时,以工厂方法(您已经拥有)获取{{1}}对象。