2009-05-08 113 views
2

我有麻煩設計類似當此如何減少具有相同名稱但類型不同的數據成員的類的代碼重複?

class C1 { 
public: 
    void foo(); 
} 

class C2 { 
public: 
    void foo(); 
} 

C1和C2具有兩個派生類的相同方法foo(),

class Derived1 : public Base { 
public: 
    void Update() { 
    member.foo(); 
    } 
private:  
    C1 member; 
} 

class Derived2 : public Base { 
public: 
    void Update() { 
    member.foo(); 
    } 
private:  
    C2 member; 
} 

更新()是完全相同的,但類型的成員是不同的。 所以我必須複製每個新派生類的更新工具。

這是一種減少這種代碼重複的方法嗎?我只用宏解決問題。 我覺得這是有模板來解決這個更優雅的方式,但我不出來..

編輯: 感謝了很多人,但我想我錯過了什麼..

1。我正在使用C++

2.實際上,每個Derived類都有大約5個成員,它們都提供了foo()方法並從相同的基類派生。我的情況是,我已經編寫了一個(非常長的)Update()方法,它可以在沒有任何修改的情況下適用於每個派生類。所以我只是將這個Update()複製並粘貼到每個新類的Update()中,這會導致可怕的代碼重複。我想知道是否有一種方法可以避免重寫Update(),並且可以減少重複。

THX再次

回答

6

這正是類模板的設計目的。它們允許類中的函數對不同的數據類型進行操作,而不需要複製算法和邏輯。

This Wikipedia page會給你一個很好的編程模板的概述。

這裏是基本的想法,讓你開始:

template <class T> 
class CTemplateBase 
{ 
public: 
    void Update() 
    { 
     member.foo(); 
    } 
private: 
    T member; // Generic type 
} 

class CDerived1 : public CTemplateBase<C1> 
{ 
    // No common algorithms required here 
} 

class CDerived2 : public CTemplateBase<C2> 
{ 
    // No common algorithms required here 
} 
+2

而不是那些派生的,爲什麼不只是:「typedef Dervied1 CTemplateBase ;」和「typedef Dervied2 CTemplateBase ;」 (顯然派生不再是一個好名字,但你明白了)。 – user83255 2009-05-08 06:13:53

+0

@ilproxil - 是的,我想這是可以接受的。但我會留下它,因爲它是爲了清晰起見。 – LeopardSkinPillBoxHat 2009-05-11 06:26:35

0

如果有超過C1和C2的控制下,你可以定義一個基類或一個抽象基類,並在基類或第三輔助類處理它。

0

移動方法父類:

class IFooable { 
public: 
    virtual void foo() = 0; 
} 

class C1 : IFooable { 
public: 
    void foo(); 
} 

class C2 : IFooable { 
public: 
    void foo(); 
} 

class Base { 
public: 
    void Update() { 
    member->foo(); 
    } 
private:  
    IFooable* member 
} 

class Derived1 : public Base { 
    Derived1() : member(new C1()) {} 
    ~Derived1() { delete member; } 
} 

class Derived2 : public Base { 
    Derived2() : member(new C2()) {} 
    ~Derived2() { delete member; } 
} 
+0

這是C++,而不是C#。成員將需要成爲一個指針,而不是一個實例。多態性不僅不起作用,而且不會編譯。我認爲你在正確的軌道上,我更喜歡這個模板解決方案(雖然我有麻煩提出一個非主觀原因)。 – 2009-05-08 05:37:33

+0

謝謝,它在我的C++上已經有一段時間了。成員已被更改爲指針。 – 2009-05-08 06:11:55

+0

如果您要刪除IFooable *類型的指針,IFooable也需要一個虛擬析構函數。 – 2009-05-08 12:14:51

0

如果您Drived1和Derived2的是除了式(C1和C2相同)的成員,那麼你可以考慮使用一個Derived類和一個模板。 (請原諒我語法如果不正確,我M C#dev的:d)

template <class T> 
class Derived : public Base { 
public: 
    void Update() { 
    member.foo(); 
    } 
private:  
    T member; 
} 

東西上述線。

相關問題