【发布时间】:2014-08-10 17:42:27
【问题描述】:
我记得有人说如果你通过库创建一个类,你应该通过库来销毁它。那么,这是否意味着我不应该调用删除?我应该打电话给myclass.deleteMe() 吗?重载delete能解决问题吗?
【问题讨论】:
标签: c++
我记得有人说如果你通过库创建一个类,你应该通过库来销毁它。那么,这是否意味着我不应该调用删除?我应该打电话给myclass.deleteMe() 吗?重载delete能解决问题吗?
【问题讨论】:
标签: c++
我记得有人说如果你通过 lib 创建一个类,你应该通过 lib 销毁它。
这意味着如果您调用库中的函数为您创建对象,您应该阅读该函数的文档,其中必须说明您如何再次释放该对象。通常,免费功能的名称类似于分配功能。例如,库pcre 有两个函数,分别称为pcre_malloc 和pcre_free。
原因是,因为库以对您不透明的方式分配(这就是您首先使用该函数的原因)。它可以从程序的数据部分获取内存,而您会(错误地)假设它在使用delete 时可能从堆中获取内存。
如果你是那个库作者,同样的规则适用。确保当您的某个函数返回一个动态分配的对象时,您说明调用者必须如何处理它
您几乎不应该为您的类重载 delete 运算符除非您还重载了 new 运算符。重载删除操作符不是字面意思:这意味着您只是重载对象关联内存的deallocation。仅当您拥有自己的内存池或想要记录对象的每个内存分配/释放时才有意义。
【讨论】:
您的应用程序删除在 lib 中创建的内容的一个问题是该 lib 可能使用不同的堆/内存管理器。
解决方案包括:
delete this;
operator delete,在库中实现...如果有自定义运算符 delete,那么当您的应用程序删除对象的一个实例时,它将调用它。【讨论】:
此规则适用于您设计的类。 经验法则(虽然并不总是使用)是,如果一个类创建了一个对象,它应该删除它。
但是如果你问的是别人设计的某个库,你无法知道他是否遵守这个规则,你必须通过他自己/文档/代码来检查。
【讨论】:
您应该查阅该库的文档以了解如何删除它创建的对象。除了其他人提到的之外,有时库对何时删除对象有一个期望。例如,在 wxWidgets 中,您不应该自己删除小部件,因为当它们的父小部件被销毁时,wxWidgets 会尝试为您删除它们——如果您已经删除了它们,那么您就有了双重释放(未定义的行为)。无法仅通过查看类型来确定这一点——即使库不返回智能指针,它们也可能以这种方式运行。此外,该库可能依赖于以特定顺序发生的释放(例如,它可能总是先释放所有一种类型的对象),而自己删除事物会破坏顺序。
【讨论】:
如果您的库在内存管理器等方面提供了构造对象的特定方法,那么您应该没有方法可以摆脱该对象,除非通过一种有意义的方式来处理对象的构造/分配方式类似。
换句话说,如果您的对象倾向于以某种方式分配,请确保所有摆脱它们的方法都遵循您的“某种方式”。
【讨论】: