C 實現的委託機制(一)

2021-05-28 15:05:25 字數 4022 閱讀 7019

c++實現的委託機制(一)

1.引言

下面的委託實現使用的mygui裡面的委託實現,mygui是一款強大的gui庫,想理解更多的mygui資訊,猛擊這裡

我們的目標是要實現乙個跟.net幾乎完全一樣的委託,使用簡單,支援多播,可以新增刪除委託。同時支援c++的普通函式、模板函式、類成員函式,類的靜態成員函式,並且支援多型。使用方式如下:

// 普通函式

void normalfunc()

class base

};int main()

2.實現無參函式委託

要實現委託,首先要解決的是封裝c++中的函式指標。因為在c++中,普通函式指標和類成員函式指標是完全不一樣的。如下例子:

class cmyclass

;

定義乙個指向cmyclass型別,引數列表為(int),返回值為void的函式指標typedef void (cmyclass::*classmethod) (int); // 注意定義時使用了特殊的運算子::*。那麼此函式指標只能指向cmyclass型別的成員函式,不能指向其他類或者普通函式。類成員函式指標不能直接呼叫,要通過乙個類例項來呼叫,如下:

cmyclass *object = new cmyclass;

classmethod method = cmyclass::func;

(object->*method)(5); // 注意呼叫時使用了特殊運算子->*

那麼如何封裝呢?我們先來定義下介面吧。(為了簡單起見,下面的實現都是以無參函式為例,後續會講到如何支援任意引數)

class idelegate

virtual bool istype(const std::type_info& _type) = 0;

virtual void invoke() = 0;

virtual bool compare(idelegate *_delegate) const = 0;

};

idelegate類的介面很少,也很簡單,必要介面只有乙個,就是invoke,用於觸發函式,但為了可以方便管理,使用了istype和compare函式來進行相等判斷。下面是封裝的普通函式指標:

class cstaticdelegate : public idelegate

virtual bool istype(const std::type_info& _type)

virtual void invoke()

virtual bool compare(idelegate *_delegate) const

private:

func mfunc;

};

可以看到,cstaticdelegate只是簡單地封裝了普通函式指標,**也非常簡單,(類的某些成員函式,如istype和compare使用了rtti,對c++的動態型別判斷不熟的可以猛擊這裡

)好了,注意了,下面開始封裝類成員函式指標:

templateclass cmethoddelegate : public idelegate

virtual bool istype( const std::type_info& _type)

virtual void invoke()

virtual bool compare(idelegate *_delegate) const

private:

t * mobject;

method mmethod;

};

首先解釋一下:因為類成員函式指標與類的型別有關,不同類的成員函式指標是不一樣的。要解決型別不同,很簡單,使用模板就行。**跟cstaticdelegate基本一樣,下面稍微解釋一下:cmethoddelegate類主要封裝了乙個類例項指標以及類成員函式的指標,這樣在invoke時就不要額外的通過乙個類例項了。要注意一點,compare函式的實現中,相等判定是類例項以及類函式指標都一樣。也就是說就算是指標同乙個成員函式,但例項不同,委託就不同。為了方便使用,定義函式newdelegate來建立委託使用的函式:

inline idelegate* newdelegate( void (*_func)() )

templateinline idelegate* newdelegate( t * _object, void (t::*_method)() )

至此,對c++函式指標的封裝就完成了,不難吧。下面就是委託的實現了:

class cmultidelegate

~cmultidelegate ()

bool empty() const

return true;

}void clear()}}

cmultidelegate& operator+=(idelegate* _delegate)

}mlistdelegates.push_back(_delegate);

return *this;

}cmultidelegate& operator-=(idelegate* _delegate)

}delete _delegate;

return *this;

}void operator()( )

else}}

private:

cmultidelegate (const cmultidelegate& _event);

cmultidelegate& operator=(const cmultidelegate& _event);

private:

listdelegate mlistdelegates;

};

仔細理解下cmultidelegate類的實現,**都不深奧。

比較重要的是3個函式 :+=,-=,()運算子的過載函式

+= 用於新增乙個委託函式

-= 用於去掉乙個委託函式

()用於觸發委託函式

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

這裡要重點說明的一點是,大家仔細看 += 函式的實現中

if ((*iter) && (*iter)->compare(_delegate))

為什麼要delete掉外部的指標呢?因為c++的記憶體洩露一直是個麻煩事,所以myugi的委託裡,所有的委託函式統一由delegate本身管理,外部不要自己new或delete委託函式,也不要儲存乙個委託函式,delegate本身會管理好的。建議像如下使用:

cmultidelegate mydelegate;

mydelegate += newdelegate(normalfunc);

mydelegate -= newdelegate(normalfunc);

//而不建議像如下使用:

cmultidelegate mydelegate;

idelegate* delegatefunc = newdelegate(normalfunc);

mydelegate += delegatefunc;

mydelegate -= delegatefunc;

上面2種方法都沒錯,都不會造成記憶體洩露。你可能會覺得第2種方法減少new的次數,比第一種方法更好。其實不然,因為第2種方法有個很大的隱患,mydelegate -= delegatefunc;// 在這一步,delegatefunc所指向的空間已經被釋放掉了(在-=函式裡面),所以如果你後面又想將delegatefunc新增到mydelegate裡面時,你就不能再這樣用了。mydelegate += delegatefunc;// 錯誤,因為delegatefunc的空間已經被釋放了。你得重新new乙個:

delegatefunc = newdelegate(normalfunc);

mydelegate += delegatefunc;

C 實現的委託機制(二)

c 實現的委託機制 二 1.實現任意引數的函式委託 只能不同個數各實現乙個類,如 單參函式委託 templateclass cmultidelegate1 雙參函式委託 templateclass cmultidelegate2 注意類名是不一樣的,分別為cmultidelegate1和cmulti...

C 實現的委託機制 1

c 實現的委託機制 1 1.引言 下面的委託實現使用的mygui裡面的委託實現,mygui是一款強大的gui庫,想理解更多的mygui資訊,猛擊這裡 普通函式 void normalfunc class base int main 2.實現無參函式委託 要實現委託,首先要解決的是封裝c 中的函式指標...

C 中的委託機制 一)

c 中的委託機制那麼什麼是委託呢?其實呢生活中有很多委託的例子。比如你看中了二環的一套別墅對吧,你想要買 不是我,我連租都租不起 那就要去找中介,中介呢就會去找賣這個房子的人,和他進行溝通,那麼這裡的中介就相當於乙個委託人的角色,也可以說是一種 在c 中,程式想要呼叫方法進行引數的傳遞時會有相當大的...