是一个非常基本的C++问题,但我根本找不到正确执行此操作的方法:
我需要在我的 GUI 类的方法中创建一些类"QPluginLoader"的实例,并希望将这些实例存储在 QList 中。QPluginLoader 实例必须在整个 GUI 类中可用。但是每当我尝试通过QList访问QPluginLoader时,程序都会崩溃。我认为这是因为一旦超出我实例化 QPluginLoader 类的范围,它就会被销毁,因此它在我创建 QPluginLoader 并将其存储到 QList 的方法之外不可用。
但是如何使实例在整个类中可用呢?
这是我尝试过的:
主窗口.h
class MainWindow : public QMainWindow
{
Q_OBJECT
public slots:
void onThreadTerminated();
private:
bool loadPlugins();
QList<QPluginLoader*> loaderList;
};
主窗口.cpp
bool MainWindow::loadPlugins()
{
QDir pluginsDir(qApp->applicationDirPath());
pluginsDir.cd("plugins");
foreach (QString fileName, pluginsDir.entryList(QDir::Files))
{
QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
QObject* plugin = pluginLoader.instance();
if (plugin)
{
loaderList.push_back(&pluginLoader);
pluginCount++;
}
}
return false;
}
最后但并非最不重要的一点是,使我的程序崩溃的插槽
// SLOT
void MainWindow::onThreadTerminated()
{
while (!loaderList.isEmpty()) {
if(loaderList.takeFirst()->isLoaded()) loaderList.takeFirst()->unload();
}
loaderList.clear();
}
问题是loadPlugins
函数中的这两行
QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
...
loaderList.push_back(&pluginLoader);
第一个定义本地对象pluginLoader
。第二个将指向该本地对象的指针推送到容器中。
问题是,当循环迭代(或结束(时,pluginLoader
的生命周期结束并且它被破坏,指向它的指针变得无效。
在我看来,您不应该拥有插件加载器的容器,而应该拥有实际插件本身的容器。
如果你真的想要容器中的插件加载器,你需要用 new
动态创建它们,或者至少使用它的智能指针。或者,如问题评论中所述,使用QPluginLoader
对象的容器。
foreach (QString fileName, pluginsDir.entryList(QDir::Files))
{
QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
pluginLoader
将在下一}
销毁,并且您在 loaderList
中保留此已销毁对象的引用。
使用 new
动态分配内存pluginLoader
,并将指向QPluginLoader
的指针保留在loaderList
当然,您必须记住释放分配的内存以进行QPluginLoader