返回实例导致"尝试引用已删除的函数"错误

Return instance causes 'attempting to reference a deleted function' error

本文关键字:删除 错误 函数 引用 实例 返回      更新时间:2023-10-16

在过去的一二十年里,我C++变得有点生疏了。

我正在编写一个数据库类,但以下方法有问题:

CRecordset CAccessDatabaseReader::ExecuteSqlQuery(LPCTSTR pszSqlQuery)
{
CRecordset recordSet(&m_Database);
recordSet.Open(CRecordset::forwardOnly, pszSqlQuery);
return CRecordset(recordSet);
}

编译器在return语句中抱怨:

错误 C2280 "CRecordset::CRecordset(const CRecordset &)":尝试引用已删除的函数

有人可以帮助我确切地了解这里发生了什么吗?

CRecordset的复制构造函数已被显式标记为deleted,以防止将CRecordset对象从一个对象复制到另一个对象。

因此,该函数必须通过指针返回一个新对象,并要求调用方在使用完对象后delete该对象:

CRecordset* CAccessDatabaseReader::ExecuteSqlQuery(LPCTSTR pszSqlQuery)
{
CRecordset *recordSet = new CRecordset(&m_Database);
if (!recordSet->Open(CRecordset::forwardOnly, pszSqlQuery))
{
delete recordSet;
return NULL; // or raise an exception
}
return recordSet;
}
CRecordset *rs = reader.ExecuteSqlQuery(TEXT("..."));
if (rs)
{
...
delete rs;
}

或更好:

std::unique_ptr<CRecordset> CAccessDatabaseReader::ExecuteSqlQuery(LPCTSTR pszSqlQuery)
{
std::unique_ptr<CRecordset> recordSet(new CRecordset(&m_Database));
if (!recordSet->Open(CRecordset::forwardOnly, pszSqlQuery))
recordSet.reset(); // or raise an exception
return recordSet;
}
std::unique_ptr<CRecordset> rs = reader.ExecuteSqlQuery(TEXT("..."));
if (rs)
{
...
}

CRecordset删除了它的复制构造函数,因此您无法按值返回它。您可以改为从ExecuteSqlQuery返回std::unique_ptr<CRecordset>或引用。

删除复制构造函数时:https://stackoverflow.com/a/6077164/2449857

关于从函数返回引用:返回C++引用变量的做法是邪恶的吗?