2009-06-19 45 views
3
Callback* p = new Callback; 
function(p); 

如果我想删除回调对象,何时以及如何删除它?何时让对象自己删除?

如果它被提前删除,则回调可能会因分段错误而失败。

+0

这将取决于你。 – 2009-06-19 15:22:16

回答

17

对此的最佳解决方案是使用智能指针。
您用回调函数初始化指针并将其传递给函数。当函数或任何过程完成时,回调将被智能指针自动删除。
一个好的智能指针实现是boost::shared_ptr<>

+0

如果你需要一个共享指针,然后使用你的编译器提供的tr1 :: shared_ptr implmentation(假设它是现代的),否则使用boost :: scoped_ptr用于RAII,几乎没有开销。 – Patrick 2009-06-19 18:42:28

+0

在这种情况下,std :: auto_ptr是一个更好的智能指针。然后您将回调对象的所有权传递给该函数。 – 2009-06-19 20:29:18

1

你可以有一个增量/减量计数的时候使用回调。当它被使用时,递增计数,当它不再使用时,递减计数。当它达到0或-1时释放它。

1

持有回调函数(执行回调函数的回调函数)的“调用者支持者”对象可能是正确的所有者(决定回调函数的生存期,特别是使用delete来取消回调对象,持有auto_ptr等),当且仅当它的语义是让它确定什么时候不需要进一步的回调 - 从问题中提供的这样少量的信息是不可能分辨出来的。

您可能还需要各种方式为创建回调(并传递它的所有权给调用者,支持者),明确提出了“来电者支持者”删除回调对象(并执行没有更多的回调代码)当所述代码是确定不再需要更多回调的代码时。

其他答案提到比auto_ptr更聪明的指针来解决“谁拥有这个”消失的问题(boost的shared_ptr,手动引用计数,...) - 如果你被迫使用C++出于其他原因,但真的很想用垃圾收集语言,但是,如果您专门选择C++是因为它可以完全控制内存使用情况,那么正确确定对象所有权和生命期问题不是可选的(并且它可以严格优化您的资源与任何种类的或多或少的自动化“垃圾收集”相比 - 只有当您需要严密控制您的资源使用情况时,才会重要;当您的时,这一点非常重要。

1

假设func()是使用该特定Callback对象的唯一函数,并且此代码总是按照创建Callback对象的顺序执行,我会在调用func()后将其放入。这样,如果你必须编辑func(),你不必担心回调对象被删除的地方。它还确保所有指针都被清空,因为函数完成时func()的指针应该已经停止存在,唯一要做的就是删除指向它的指针。

我很抱歉,如果我对C++中指针的理解是有缺陷的,并导致我给出一个不正确的答案,我总是对此有点困惑。

3

如果如你所说的那样,这意味着只有一个参考回调指针FUNC()之后被执行的代码是微不足道的,我相信一个auto_ptr就足够了:

std::auto_ptr<Callback> p(new Callback); 
func(p.get()); 

这也保证了应func()抛出异常,内存仍然会被释放。

1

如果你的代码是你所写的内容一样简单,而且func()直接调用在某些点回调,那么这应该是足够了:

Callback p; 
func(&p); 

但是,如果func()节省引用或指针回调其他地方,您需要跟踪该参考的生命周期。