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;
相信你不会愿意这样做的,因为这种方法很容易造成内存泄露或者崩溃
现在你应该可以明白 -= 函数是怎么释放委托函数内存了吧。
按上面的方法,你已经可以使用无参数的函数委托了。下一篇文章将会介绍如何实现任意参数的函数委托