Lambda 捕获 QFile 对象
Lambda capture QFile object
我想在 lambda 函数中维护一个文件。我可以在 lambda 之外处理它,但是一旦我将它作为参考传递并想在下载后检查它是否存在,我的应用程序就会在这一行崩溃:if (workFile.exists() && !workFile.remove()) {
.
QFile workFile("path/to/file.bat");
[..]
if (!workFile.exists()) {
[..] download file & such
QObject::connect(&mng, &FileManager::onDownload, this, [=, &workFile] (const QString& name) {
if (workFile.exists() && !workFile.remove()) {
qDebug() << "File was not downloaded correctly.";
}
});
}
回溯:
为什么不起作用?我应该如何正确捕获 QFile?
通过引用捕获对象时,如果在对象的生命周期结束后调用 lambda,您将获得悬空引用。您应该始终确保在调用 lambda 时通过引用传递的对象仍然有效。
在您的示例中,QFile
对象在实际调用 lambda 之前超出范围,这是因为您的 FileManager
在您的函数完成后发出 onDownload
,lambda获取对无效对象的引用,然后发生崩溃。
您可以通过在 lambda 中实例化另一个具有相同文件名的 QFile
实例来解决这个问题(而不是捕获旧的实例),或者使用静态替代方案(如果您只想检查是否存在并删除): QFile::exists()
, QFile::remove()
。
如果你真的需要捕获旧的 QFile
实例,你必须确保它的生命周期在调用 lambda 时有效(你可以通过使用 [=17= 在堆上分配它来做到这一点] 并 delete
完成后自行处理)。
我想在 lambda 函数中维护一个文件。我可以在 lambda 之外处理它,但是一旦我将它作为参考传递并想在下载后检查它是否存在,我的应用程序就会在这一行崩溃:if (workFile.exists() && !workFile.remove()) {
.
QFile workFile("path/to/file.bat");
[..]
if (!workFile.exists()) {
[..] download file & such
QObject::connect(&mng, &FileManager::onDownload, this, [=, &workFile] (const QString& name) {
if (workFile.exists() && !workFile.remove()) {
qDebug() << "File was not downloaded correctly.";
}
});
}
回溯:
为什么不起作用?我应该如何正确捕获 QFile?
通过引用捕获对象时,如果在对象的生命周期结束后调用 lambda,您将获得悬空引用。您应该始终确保在调用 lambda 时通过引用传递的对象仍然有效。
在您的示例中,QFile
对象在实际调用 lambda 之前超出范围,这是因为您的 FileManager
在您的函数完成后发出 onDownload
,lambda获取对无效对象的引用,然后发生崩溃。
您可以通过在 lambda 中实例化另一个具有相同文件名的 QFile
实例来解决这个问题(而不是捕获旧的实例),或者使用静态替代方案(如果您只想检查是否存在并删除): QFile::exists()
, QFile::remove()
。
如果你真的需要捕获旧的 QFile
实例,你必须确保它的生命周期在调用 lambda 时有效(你可以通过使用 [=17= 在堆上分配它来做到这一点] 并 delete
完成后自行处理)。