【发布时间】:2019-12-18 04:32:54
【问题描述】:
当我学习使用抽象接口将代码封装在动态库中时,似乎建议使用“Release()”函数来释放资源。现在我想知道为什么他们不只是使用析构函数来释放?使用析构函数释放资源是否有任何问题,或者它们只是意味着使用智能指针?
这是推荐的代码:
// Interface like that ..
struct IXyz
{
virtual int Foo(int n) = 0;
virtual void Release() = 0;
};
// Xyz class definition, derived from IXyz
// ...
// Using in client ..
IXyz* pXyz = GetXyz(); //Use Factory function to create an object
if(pXyz)
{
pXyz->Foo(42);
pXyz->Release();
pXyz = nullptr;
}
现在我想编写以下代码:
// Interface
struct IXyz
{
virtual int Foo(int n) = 0;
virtual ~IXyz() {}; // I have moved Release()'s content into Xyz's destructor
};
// Client
IXyz* pXyz = GetXyz(); //Use Factory function to create an object
if(pXyz)
{
pXyz->Foo(42);
pXyz->~IXyz();
pXyz = nullptr;
}
这些代码都可以正常工作。所以我想知道这两种释放资源的方式之间的区别。我可以同时使用它们吗?非常感谢!
【问题讨论】:
-
我认为这个链接会对你有所帮助 (stackoverflow.com/questions/16908650/…)
-
发布与删除不同。 release 是代理对象的工厂函数。 delete 将内存返回到内存池。
-
您的第二个代码块泄漏了
IXyz对象的内存。您需要正确释放它。如何做到这一点取决于GetXyz做了什么。如果你跳过Release,你也需要修改它。GetXyz在你的例子中做了什么? -
这就是麻烦的开始。它会泄漏内存吗?程序在使用删除时会爆炸吗?客户端代码无法知道工厂函数做了什么。返回指向全局变量的指针是完全有效的,new 运算符也是如此。当你使用 Release() 时没关系,实现总是知道如何正确地做到这一点。
-
@H3d9 正如上面的 cmets 中提到的,问题是您无法确定 如何 删除该对象,因为您不知道它是如何分配的.为避免此问题,
GetXyz应返回一个智能指针,如果您不想手动调用Release,该指针知道如何为您处理释放。
标签: c++