在两个 class 上协调析构函数,其中一个 class 需要先清理

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

假设我创建了一个 CDatabase 和一个 CStatement class。 CStatement class 的某些句柄依赖于 CDatabase class。

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

重要的是 CStatementCDatabase 之前释放它的句柄。

问题是,如果两个对象都在一个方法中声明为局部对象(正如它们将要声明的那样),那么关于哪个对象将首先调用它的析构函数存在一些问题。

我的一个想法是让 CStatementCDatabase 中调用一个 RegisterStatement 方法。这样,如果 CDatabase 析构函数首先被调用,它可以在任何 CStatement 对象中调用一个方法,这取决于它,然后再释放自己的句柄。我还可以添加一个 UnregisterStatementCStatement 可以从它的析构函数中调用它,这样 CDatabase 就知道如果它先被销毁就不会调用它。

但是调用 UnregisterStatement 方法是不确定的,因为可能 CDatabase class 已经被销毁了。

有人知道解决这个问题的可靠方法吗?

如果两者都在函数中声明为局部函数,则 CDatabase 必须首先声明,因为 CStatement 在构造函数中接受它。因此,它会最后被摧毁。具有自动持续时间的对象总是以相反的构造顺序销毁。