返回实例导致尝试引用已删除的功能'错误

时间:2016-12-07 01:25:24

标签: c++ visual-c++ cdatabase

在过去的十年或二十年里使用C#之后,我的C ++变得有点生疏了。

我正在编写数据库类,并且遇到以下方法的问题:

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

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

  

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

有人可以帮我理解这里发生了什么吗?

2 个答案:

答案 0 :(得分:1)

CRecordset已删除其复制构造函数,因此您无法按值返回它。您可能会从std::unique_ptr<CRecordset>返回ExecuteSqlQuery或引用。

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

从函数返回引用:Is the practice of returning a C++ reference variable, evil?

答案 1 :(得分:1)

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)
{
    ...
}