Search code examples
c++visual-c++cdatabase

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


After working with C# for the past decade or two, my C++ is getting a little rusty.

I'm writing a database class and have an issue with the following method:

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

The compiler complains on the line with the return statement:

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

Can someone help me understand exactly what is happening here?


Solution

  • CRecordset's copy constructor has been explicitly marked as deleted to prevent copying CRecordset objects from one to the other.

    So, the function will have to return a new object by pointer and require the caller to delete the object when finished using it:

    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;
    }
    

    Or better:

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