Jonathan Wood
Jonathan Wood

Reputation: 67295

Coordinating destructors on two classes, where one class needs to clean up first

Let's say I create a CDatabase and a CStatement class. The CStatement class relies on the CDatabase class for some of its handles.

class CDatabase
{
public:
    SQLHENV m_hEnv;
    SQLHDBC m_hDBC;

    CDatabase()
    {
    }

    ~CDatabase()
    {
        FreeHandles();
    }

    void FreeHandles()
    {
        // ...
    }
}

class CStatement
{
public:
    SQLHSTMT m_hStmt;
    CDatabase* m_pDatabase;

    CStatement(CDatabase* pDatabase)
    {
        m_pDatabase = pDatabase;
    }

    ~CStatement()
    {
        FreeHandles();
    }

    void FreeHandles()
    {
        // ...
    }
}

It's important that CStatement frees its handles before CDatabase does.

The issue is if both objects are declared local in a method, as they will be, there is some question about which object will get it's destructor called first.

One idea I had is to have CStatement call a RegisterStatement method in CDatabase. This way, if the CDatabase destructor gets called first, it can call a method in any CStatement objects depending on it to before free its own handles. I could also add an UnregisterStatement that CStatement could call from it's destructor so CDatabase would know not to call that one if it was destroyed first.

But calling the UnregisterStatement method is iffy because maybe the CDatabase class has already been destroyed.

Does anyone know of a solid way to approach this issue?

Upvotes: 0

Views: 100

Answers (1)

Igor Tandetnik
Igor Tandetnik

Reputation: 52611

If both are declared local in a function, then CDatabase would necessarily be declared first, since CStatement takes it in constructor. Therefore, it'll be destroyed last. Objects with automatic duration are always destroyed in reverse order of construction.

Upvotes: 2

Related Questions