1

我正在研究如何创建一个简单的 Direct2D 应用程序的示例SafeRelease,作者定义了一个类模板和一个方法,调用如下:

    template<class Interface>
inline void SafeRelease(
    Interface **ppInterfaceToRelease
    )
{
    if (*ppInterfaceToRelease != NULL)
    {
        (*ppInterfaceToRelease)->Release();

        (*ppInterfaceToRelease) = NULL;
    }
}

上面的代码来自头文件。但是,该类的析构函数会进行以下调用:

DemoApp::~DemoApp()
{
    SafeRelease(&m_pDirect2dFactory);
    SafeRelease(&m_pRenderTarget);
    SafeRelease(&m_pLightSlateGrayBrush);
    SafeRelease(&m_pCornflowerBlueBrush);

}

我刚开始学习 c++,我想知道这些调用是合法的。显然我对指针作为过程参数的理解是有缺陷的,所以请纠正我。接受指针类型的过程如何接受地址?另外,当我按 F12 时,Visual Studio 找不到该Release方法的声明,但我怀疑它与 COM 释放方法有关,因此解释它内部发生的事情会非常有帮助,因为我不能“调试时进入”它。所以 - 代码工作得很好,我只是想知道为什么。完整的源代码可以在这里找到。

4

1 回答 1

3

它有助于简化事情,基本上只是将内存视为一个巨大的数组,其中您拥有地址(您可以将其视为数组的索引),然后您实际上拥有内容本身(可以是任何东西)。

所以 Interface ** 可以被认为是指向内存的地址,该地址包含另一个包含 Interface 对象的内存地址。

想象以下

 Name               Type               Memory Address           Contents

 interfacePtrPtr    Interface**        0x1                      The address 0x2
 interfacePtr       Interface*         0x2                      The address 0x3
 interface          Interface          0x3 - 0xFF?              An interface object

在这个虚构的示例中,假设我们从interface开始,然后使用&interface获取interfacePtr,然后使用&interfacePtr获取 interfacePtrPtr。

您也可以向后使用 *interfacePtrPtr 获取 interfacePtr,然后使用 *interfacePtr 最终返回到接口本身。

所以在你的例子中,当

  SafeRelease(&m_pDirect2dFactory);

被调用时,函数被赋予接口指针的地址——如果你愿意的话,一个接口指针指针。

  (*ppInterfaceToRelease)->Release();

然后 this 用 * 解引用 this 指针,将指针指针转换回常规指针,然后使用 -> 简写将指针解引用到 Interface 对象本身,并调用其释放方法。

希望这是有道理的。

于 2013-06-15T13:18:14.297 回答