Windows COM C++ - 使用删除或释放

Posted

技术标签:

【中文标题】Windows COM C++ - 使用删除或释放【英文标题】:Windows COM C++ - Using delete or Release 【发布时间】:2017-01-24 22:39:40 【问题描述】:

我想问一个简单的问题,我有一个 Direct2D 工厂,当我准备清理时,我会调用 delete 还是使用 release member?我看到一些教程只是显式调用 delete,所以我很好奇哪个更安全,除非发布成员所做的只是在后台调用 delete 等。`

Graphics::~Graphics() 

    if (Factory) //Factory->Release(); or  delete Factory;
    if (Render) //Render->Release();  or delete Render;

【问题讨论】:

【参考方案1】:

释放COM接口的正确方法是在接口指针上调用Release方法。

delete 用于在堆上分配有new 的 C++ 对象,而不用于 COM 接口指针。

请注意,您还可以使用智能指针类(如 ATL 的 CComPtr)安全地包装原始 COM 接口指针。在这种情况下,当智能指针超出范围时,Release 方法会被自动调用

例如,如果您在示例中为 FactoryRender 数据成员使用智能指针包装器,则无需在 Graphics 析构函数中显式调用 Release:C++ 编译器将 自动在每个数据成员上调用析构函数,这将导致 Release 被包装的 COM 接口调用。

【讨论】:

【参考方案2】:

当然是Release();,而且只有这个在接口方法上。并且您只能调用 delete 来获取您之前由自己的 new 分配的内存。对于从外部DLL 分配的内存,总是错误调用delete,因为它们的新/删除不能匹配您的新/删除

【讨论】:

" 对于从外部 DLL 分配的内存总是错误调用删除,因为它们的新/删除不能匹配您的新/删除" 并不完全正确。两个或多个 Windows 模块可以使用同一个运行时库的同一个实例,即将运行时库作为 DLL。还可以定义特定类的分配和释放,以使用适当的特定于实例的内存管理器。 @Cheersandhth.-Alf - 当然很可能 2 个不同的 pe 模块具有相同的 new/delete 实现 - 所以这个形式会起作用,但在这种情况下,这将是逻辑错误。 不,当您执行对您控制的代码完全没问题的操作时,不会出现逻辑错误。 @Cheersandhth.-Alf - 如果一个模块分配内存并将此内存传递给另一个模块,当不再需要它时必须释放它 - 必须明确说明 - 哪个 api 免费使用(@例如 987654328@)。 delete - 这只是占位符,不是具体功能(可以是不同的实现) - 结果delete 永远不能用于从另一个模块分配的空闲内存。说分配给LocalAlloc的内存,我们为此调用delete?这会是崩溃还是内存泄漏?不是强制性的。如果我们的删除实现使用了LocalFree - 一切都会正常工作。 @Cheersandhth.-Alf - 但无论如何,这种逻辑错误使用delete 用于外部和未知方式分配的内存

以上是关于Windows COM C++ - 使用删除或释放的主要内容,如果未能解决你的问题,请参考以下文章

如何从 c++ 的方面(方面 c++)释放或删除函数中的分配对象?

在 C 或 C++ 中释放内存 [重复]

如何删除或更改已经释放的TR

在 Windows 环境中从 C 或 C++ 访问 COM 接口

C++链表删除节点

在 C++ 中的 2D 动态内存分配数组中释放分配的内存