我记得有人说如果你通过lib创建一个类,你应该通过库来销毁它。那么,这是否意味着我不应该叫删除?我应该致电myclass.deleteMe()
而不是?重载删除会解决问题吗?
答案 0 :(得分:6)
我记得有人说如果你通过lib创建一个类,你应该通过lib来销毁它。
这意味着如果你在lib中调用一个函数为你创建一个对象,你应该阅读该函数的文档,它必须说明你如何再次释放该对象。通常,免费内容的函数被命名为类似于分配函数。例如,库pcre
有两个名为pcre_malloc
和pcre_free
的函数。
原因是,因为库以一种对你不透明的方式分配(这是你首先使用该函数的原因)。它可以从程序的数据部分获取内存,而您(错误地)假设它在使用delete
时可能从堆中获取内存。
如果你是该库编写者,则适用相同的规则。确保当你的一个函数返回一个动态分配的对象时,你会说出调用者如何处理它
除非您还重载了新运算符,否则您几乎不会为类重载删除运算符。重载delete运算符不是字面意思:它意味着你只是重载对象的相关内存的 deallocation 。只有在您拥有自己的内存池或想要记录对象的每个内存分配/释放时才有意义。
答案 1 :(得分:2)
您的应用程序删除在lib中创建的内容的问题是lib可能使用不同的堆/内存管理器。
解决方案包括:
delete this;
operator delete
,在库中实现...如果有自定义运算符删除,那么当应用程序删除对象的istance时,它将被调用。答案 2 :(得分:0)
此规则适用于您设计的类。 经验法则(虽然并不总是使用)是,如果一个类创建一个对象,它应该删除它。
但如果你问其他人设计的某个图书馆,你不知道他是否遵守这条规则,你必须通过himselef / documentation / code检查它。
答案 3 :(得分:0)
您应该查阅库的文档,了解如何删除它创建的对象。除了其他人提到的内容之外,有时候图书馆会期望何时删除对象。例如,在wxWidgets中,你不应该自己删除小部件,因为wxWidgets会在他们的父小部件被销毁时尝试删除它们 - 如果你已经删除了它们,那么你有一个双重自由(未定义的行为)。通过查看类型无法确定这一点 - 即使库不返回智能指针,库也可以这种方式运行。此外,库可能依赖于以特定顺序发生的解除分配(例如,它可能总是在另一个类型之前释放所有类型的对象),并且删除事物本身会破坏订单。
答案 4 :(得分:0)
如果你的库提供了一个特定的方法来构造对象,就内存管理器等而言,你应该有没有的方法来摆脱那个对象,除非通过一种有意义的方式来处理对象的形式与它的构造/分配方式类似。
换句话说,如果您的对象倾向于以某种方式分配,请确保所有摆脱它们的方法都遵循“特定方式”。