C++实现的委托机制(1)(三)

2014-11-24 12:43:46 · 作者: · 浏览: 2
legate& _event);
private:
ListDelegate mListDelegates;
};

仔细理解下CMultiDelegate类的实现,代码都不深奥。

比较重要的是3个函数 :+=,-=,()运算符的重载函数

+= 用于添加一个委托函数

-= 用于去掉一个委托函数

() 用于触发委托函数

差不多就是普通的stl容器使用了。

这里要重点说明的一点是,大家仔细看 += 函数的实现中

copy to clipboardprint if ((*iter) && (*iter)->compare(_delegate))
{
delete _delegate; // 如果该委托函数已经被添加了,则delete掉外部的_delegate
return *this;
}
if ((*iter) && (*iter)->compare(_delegate))
{
delete _delegate; // 如果该委托函数已经被添加了,则delete掉外部的_delegate
return *this;
}

为什么要delete掉外部的指针呢?

因为C++的内存泄露一直是个麻烦事,所以MyUGI的委托里,所有的委托函数统一由Delegate本身管理

外部不要自己new或delete委托函数,也不要保存一个委托函数,Delegate本身会管理好的。

建议像如下使用:

copy to clipboardprint CMultiDelegate myDelegate;
myDelegate += newDelegate(normalFunc);
myDelegate -= newDelegate(normalFunc);
CMultiDelegate myDelegate;
myDelegate += newDelegate(normalFunc);
myDelegate -= newDelegate(normalFunc);

而不建议像如下使用:

copy to clipboardprint CMultiDelegate myDelegate;
IDelegate* delegateFunc = newDelegate(normalFunc);
myDelegate += delegateFunc;
myDelegate -= delegateFunc;
CMultiDelegate myDelegate;
IDelegate* delegateFunc = newDelegate(normalFunc);
myDelegate += delegateFunc;
myDelegate -= delegateFunc;

上面2种方法都没错,都不会造成内存泄露

你可能会觉得第2种方法减少new的次数,比第一种方法更好。其实不然,因为第2种方法有个很大的隐患

copy to clipboardprint myDelegate -= delegateFunc; // 在这一步,delegateFunc所指向的空间已经被释放掉了(在-=函数里面)
myDelegate -= delegateFunc; // 在这一步,delegateFunc所指向的空间已经被释放掉了(在-=函数里面)

所以如果你后面又想将delegateFunc添加到myDelegate里面时,你就不能再这样用了

copy to clipboardprint myDelegate += delegateFunc; // 错误,因为delegateFunc的空间已经被释放了
myDelegate += delegateFunc; // 错误,因为delegateFunc的空间已经被释放了

你得重新new一个

delegateFunc = newDelegate(normalFunc);

myDelegate += delegateFunc;

相信你不会愿意这样做的,因为这种方法很容易造成内存泄露或者崩溃

现在你应该可以明白 -= 函数是怎么释放委托函数内存了吧。

按上面的方法,你已经可以使用无参数的函数委托了。下一篇文章将会介绍如何实现任意参数的函数委托