Return 实例导致 'attempting to reference a deleted function' 错误

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

在过去一两年使用 C# 之后,我的 C++ 有点生疏了。

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

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

编译器在带有 return 语句的行上抱怨:

Error C2280 'CRecordset::CRecordset(const CRecordset &)': attempting to reference a deleted function

有人可以帮助我准确了解这里发生的事情吗?

CRecordset 已经删除了它的复制构造函数,所以你不能 return 它的值。您可能 return std::unique_ptr<CRecordset> 或来自 ExecuteSqlQuery 的引用。

关于删除复制构造函数:

关于 return 从函数引用:Is the practice of returning a C++ reference variable, evil?

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

因此,该函数必须通过指针 return 一个新对象,并要求调用者在使用完对象后 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)
{
    ...
}