class?IDownloadSink??
						
{??
					
public:??
						
????virtual?void?OnDownloadFinished(const?char*?pURL,?bool?bOK)?=?0;??
															
};??
					
??
?
??
?
class?CMyDownloader??
						
{??
					
public:??
						
????CMyDownloader(IDownloadSink*?pSink)??
					
????????:m_pSink(pSink)??
					
????{??
					
????}??
					
??
?
????void?DownloadFile(const?char*?pURL)??
											
????{??
					
????????cout?<<?"downloading:?"?<<?pURL?<<?""?<<?endl;??
									
????????if(m_pSink?!=?NULL)??
							
????????{??
					
????????????m_pSink->OnDownloadFinished(pURL,?true);??
							
????????}??
					
????}??
					
??
?
private:??
						
????IDownloadSink*?m_pSink;??
					
};??
					
??
?
class?CMyFile:?public?IDownloadSink??
								
{??
					
public:??
						
????void?download()??
							
????{??
					
????????CMyDownloader?downloader(this);??
							
????????downloader.DownloadFile("www.baidu.com");??
							
????}??
					
??
?
????virtual?void?OnDownloadFinished(const?char*?pURL,?bool?bOK)??
															
????{??
					
????????cout?<<?"OnDownloadFinished,?URL:"?<<?pURL?<<?"????status:"?<<?bOK?<<?endl;??
									
????}??
					
};??
					
class?CDownloadDelegateBase??
						
{??
					
public:??
						
????virtual?void?Fire(const?char*?pURL,?bool?bOK)?=?0;??
															
};??
					
??
?
template<typename?O,?typename?T>??
										
class?CDownloadDelegate:?public?CDownloadDelegateBase??
								
{??
					
????typedef?void?(T::*Fun)(const?char*,?bool);??
															
public:??
						
????CDownloadDelegate(O*?pObj?=?NULL,?Fun?pFun?=?NULL)??
					
????????:m_pFun(pFun),?m_pObj(pObj)??
					
????{??
					
????}??
					
?????
?
????virtual?void?Fire(const?char*?pURL,?bool?bOK)??
															
????{??
					
????????if(m_pFun?!=?NULL??
							
????????????&&?m_pObj?!=?NULL)??
					
????????{??
					
????????????(m_pObj->*m_pFun)(pURL,?bOK);??
					
????????}??
					
????}??
					
??
?
private:??
						
????Fun?m_pFun;??
					
????O*?m_pObj;??
					
};??
					
??
?
template<typename?O,?typename?T>??
										
CDownloadDelegate<O,T>*?MakeDelegate(O*?pObject,?void?(T::*pFun)(const?char*?pURL,?bool))??
													
{??
					
????return?new?CDownloadDelegate<O,?T>(pObject,?pFun);??
									
}??
					
??
?
class?CDownloadEvent??
						
{??
					
public:??
						
????~CDownloadEvent()??
					
????{??
					
????????vector<CDownloadDelegateBase*>::iterator?itr?=?m_arDelegates.begin();??
					
????????while?(itr?!=?m_arDelegates.end())??
							
????????{??
					
????????????delete?*itr;??
							
????????????++itr;??
					
????????}??
					
????????m_arDelegates.clear();??
					
????}??
					
??
?
????void?operator?+=?(CDownloadDelegateBase*?p)??
							
????{??
					
????????m_arDelegates.push_back(p);??
					
????}??
					
??
?
????void?operator?-=?(CDownloadDelegateBase*?p)??
							
????{??
					
????????ITR?itr?=?remove(m_arDelegates.begin(),?m_arDelegates.end(),?p);??
					
??
?
????????ITR?itrTemp?=?itr;??
					
????????while?(itrTemp?!=?m_arDelegates.end())??
							
????????{??
					
????????????delete?*itr;??
							
????????????++itr;??
					
????????}??
					
????????m_arDelegates.erase(itr,?m_arDelegates.end());??
					
????}??
					
??
?
????void?operator()(const?char*?pURL,?bool?bOK)??
													
????{??
					
????????ITR?itrTemp?=?m_arDelegates.begin();??
					
????????while?(itrTemp?!=?m_arDelegates.end())??
							
????????{??
					
????????????(*itrTemp)->Fire(pURL,?bOK);??
					
????????????++itrTemp;??
					
????????}??
					
????}??
					
??
?
private:??
						
????vector<CDownloadDelegateBase*>?m_arDelegates;??
					
????typedef?vector<CDownloadDelegateBase*>::iterator?ITR;??
							
};??
					
??
?
??
?
class?CMyDownloaderEx??
						
{??
					
public:??
						
????void?DownloadFile(const?char*?pURL)??
											
????{??
					
????????cout?<<?"downloading:?"?<<?pURL?<<?""?<<?endl;??
									
????????downloadEvent(pURL,?true);??
							
????}??
					
??
?
????CDownloadEvent?downloadEvent;??
					
};??
					
??
?
class?CMyFileEx??
						
{??
					
public:??
						
????void?download()??
							
????{??
					
????????CMyDownloaderEx?downloader;??
					
????????downloader.downloadEvent?+=?MakeDelegate(this,?&CMyFileEx::OnDownloadFinished);??
							
????????downloader.DownloadFile("www.baidu.com");??
							
????}??
					
??
?
????virtual?void?OnDownloadFinished(const?char*?pURL,?bool?bOK)??
															
????{??
					
????????cout?<<?"OnDownloadFinished,?URL:"?<<?pURL?<<?"????status:"?<<?bOK?<<?endl;??
									
????}??
					
};??