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

871 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
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
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?