2012-03-13 57 views
2

我有調用的回調函數作爲避免重複的代碼中的公共類

MyCallBack(int type) 

和我有3類B,C和d由具有共同的方法得到的命名 目前我的代碼是這樣

MyCallBack(int type){ 
if(type == 1){ 
B b; 
b.perform(); 
}else if(type==2) { 
C c; 
c.perform(); 
}else if(type ==3){ 
D d; 
d.perform(); 
} 

有沒有辦法可以減少這種代碼類似

MyCallBack(int type){ 
Common object(type); 
object.perform(); 
} 

回答

3

基本上,你需要的是多態性。

所有的類BCD應該從一個抽象類派生說SuperBase用純虛方法perform()
您的代碼應該只使用指向SuperBase的指針,其中包含實際的具體類對象的地址。
一旦你有了這個,取決於被指向的對象的實際類型,將調用適當類的方法。

該方法的優點是沒有硬編碼類型檢查&也使用Open Closed principle鬆散耦合設計的靈活性。

1

如何關於interface

class A 
{ 
    public: 

     virtual void perform() = 0; 
}; 

class B : public A 
{ 
    public: 

     void perform() { ... } 
}; 

// Same for C, and D 

所以你的回調會再看看這樣的:

MyCallBack(A& performer) 
{ 
    performer.perform(); 
} 

如果你不能改變回調的簽名,又有怎樣的abstract factory pattern

function A* AFactory(int type) 
{ 
    switch(type) 
    { 
     case 1: return new B(); // Assuming B, C, D all derive from A 
     case 2: return new C(); 
     case 3: return new D(); 
     default: return nullptr; // nullptr is a c++11 thing. Use NULL, if you're still on C++03 
    } 
} 

,然後回調...

MyCallBack(int type) 
{ 
    std::unique_ptr<A> obj(AFactory(type)); // this will automatically release the memory once it falls out of scope 
    obj->perform(); 
} 
+0

不應該通過指針(即MyCallBack(A * performer))指向'MyCallBack(A&performer)',然後用'performer-> perform()'調用它? – 2012-03-13 18:56:43

+0

通過引用基類來引用派生類是合法的。當然,如果一個A *被傳入,那麼A *就是他必須使用的。在可能的情況下,應該更喜歡引用指針。 – luke 2012-03-13 19:01:10

-1

您應該創建Object Factory或靜態(全局)方法返回指針(或引用,也許)到基類型,但包含派生類型的對象。

CBase* CreateObjectBasedOnType(int type) 
{ 
    // check for type and return appriopriate derived object 
} 

MyCallBack(int type) 
{ 
    CreateObjectBasedOnType(type)->perform(); 
} 

請注意,您要調用的方法應該是虛擬的。

更好的方法可以使用模板

template<typename T> 
MyCallBack() 
{ 
    T Obj; 
    Obj.perform(); 
} 
2

@Als'使用多態的想法是一個很好的(IMO),但只有真正的作品後,你從輸入整數轉換成實際類型。要做到這一點的方法之一將是索引指針數組對象:

MyCallback(int type) { 
    static A *ptrs[] = { new B, new C, new D}; 

    ptrs[type-1]->perform(); 
} 

編輯:萬一你不知道,這才能正常工作,perform需要一個虛函數聲明(大概是純的)在A中虛擬,並在B,CD中的每一箇中定義。您需要確保函數的整個簽名(不僅僅是名稱)在類之間是相同的。