我正在编写基于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;
}
有什么想法吗?
答案 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}}对象。