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

887 Views Asked by At

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?

2

There are 2 best solutions below

2
Remy Lebeau On BEST ANSWER

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)
{
    ...
}
3
Jack Deeth On

CRecordset has deleted its copy constructor, so you cannot return it by value. You could possibly return a std::unique_ptr<CRecordset> or a reference from ExecuteSqlQuery instead.

On deleting copy constructors: https://stackoverflow.com/a/6077164/2449857

On returning references from functions: Is the practice of returning a C++ reference variable, evil?