QSettings应传递引用给主窗口还是可安全复制?
问题
我不确定QSettings是否存在智能指针相关机制,当前我的使用方式如下:
int main(int argc, char *argv[]) { // This is a windows only application, so I hardcoded saving to %APPDATA%/MyApp/settings.ini QString appDataPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); QString projectAppDataDir = QDir::cleanPath(appDataPath + "/" + APPLICATION_NAME); QString iniFilePath = QDir::cleanPath(projectAppDataDir + "/" + "settings.ini"); // Prepare folder for the settings { QDir createDir{appDataPath}; if(!createDir.mkpath(APPLICATION_NAME)) { qDebug() << "Failed to create app data directory."; } } QSettings mainSettings(iniFilePath, QSettings::Format::IniFormat); // test value to ensure sync() works mainSettings.setValue("test", 22); qDebug() << "Saving settings into: " << iniFilePath; QApplication a(argc, argv); // pass by ref to main window MainWindow w{mainSettings}; w.show(); int res = a.exec(); // sync only of app did not crash mainSettings.sync(); return res; }
主窗口的构造函数定义如下:
MainWindow(QSettings& globalSettings, QWidget *parent = nullptr);
我在主窗口类中存储的是该引用而非副本。由于QSettings的生命周期基本与应用程序一致,理论上不会有问题,但我并不喜欢存储引用,因此想询问这样做是否有必要,或是直接复制QSettings是安全的。
回答
直接复制QSettings完全安全
QSettings本身支持轻量级拷贝,内部采用Qt的隐式共享机制——拷贝操作不会复制整个配置数据,只是共享底层的数据源指针。所有拷贝出来的QSettings实例操作的都是同一个配置文件,修改会同步生效,销毁副本也不会影响原对象的生命周期。存储引用完全没必要
既然QSettings的拷贝开销极低,完全可以直接传递副本给MainWindow,在窗口类中存储QSettings对象而非引用。这样既避免了引用生命周期管理的潜在风险(比如意外提前销毁原对象导致悬空引用),代码逻辑也更直观易懂。智能指针的可行方案
如果你偏好使用指针方式管理资源,也可以用std::shared_ptr<QSettings>或者Qt自带的QSharedPointer<QSettings>来封装。这种方式下,所有需要访问设置的模块都共享同一个指针,无需担心生命周期问题,还能明确体现出这是共享资源的语义。比如在main函数中创建智能指针,传递给MainWindow后,窗口类存储该智能指针即可。
内容的提问来源于stack exchange,提问作者Tomáš Zato
相关产品推荐
相关产品推荐

