2010-11-25 9 views
5

Ich habe zwei fast identische Klassen, in der Tat ist jede Member-Funktion identisch, jedes Mitglied ist identisch, jede Member-Funktion macht genau das gleiche. Der einzige Unterschied zwischen diesen Klassen ist die Art, wie ich Variable ihrer Art definieren:Refactoring einer Klasse

AllocFactorScientific<102,-2> scientific; 
AllocFactorLinear<1.2> linear; 

Hier sind Header für sie:

template<double&& Factor> 
struct AllocFactorLinear; 

template<short Mantissa, short Exponent, short Base = 10> 
struct AllocFactorScientific 

Meine Frage ist, wie kann ich diese Funktionen aus diesen Klassen Refactoring das würde mir erlauben, nur einen Satz von Funktionen und nicht zwei Sätze von identischen Funktionen zu haben.

Antwort

3

Extrahieren Sie die alle gängigen Verhalten in einer dritten Klasse (Ich bin aus Gründen der Klarheit die Vorlage Argumente in meiner Antwort Weglassen):

class CommonImpl 
{ 
public: 
    void doSomething() {/* ... */ } 
}; 

Ich sehe zwei Möglichkeiten dann (was von meinem Punkt sind zumindest aus Sicht, das entspricht ziemlich genau):

  • Make AllocFactorLinear und AllocFactorScientific vererben privat aus dieser Klasse, und bringen die Mitgliederfunktionen Sie mit einer 0 in Umfang aussetzen möchtenRichtlinien:

    class AllocFactorLinear : CommonImpl 
    { 
    public: 
        using CommonImpl::doSomething; 
    }; 
    
  • Aggregate die Implementierungsklasse in AllocFactorLinear und AllocFactorScientific und leitet alle Anrufe an die privaten Umsetzung:

    class AllocFactorLinear 
    { 
    public: 
        void doSomething() { impl_.doSomething(); } 
    private: 
        CommonImpl impl_; 
    }; 
    

ich persönlich für die erste Lösung gehen würde.

+0

Ja, ich dachte nur vor ein paar Minuten über etwas Ähnliches nach. Vielen Dank. Wird mit der ersten Option gehen. –

2

Vielleicht versuchen Sie mit der Erstellung einiger Basisklasse mit diesen Funktionen und tun dies 2 Klassen mit Vorlagen zur Vererbung dieser Basisklasse.

0

Warum verwenden Sie eine Vorlagenklasse? Könnten Sie nicht eine untemplated Klasse mit 2 verschiedenen Konstruktoren verwenden?

0

denke ich, es so etwas wie wäre:

template <typename Type> 
struct AllocFactor {...}; 

und dann können Sie Type zum Beispiel haben:

template <double&& Factor> 
struct LinearConfig 
{ 
    static double value() { return Factor;} 
}; 

und:

template <short Mantissa, short Exponent, short Base = 10> 
struct FactorScientificConfig 
{ 
    static double value() 
    { 
     return some_expression_to_get_factor; 
    } 
}; 

Sie können die AllocFactor erstellen mit AllocFactor<LinearConfig<1.2>> und die entsprechende mit der FactorScientificConfig. Anschließend können Sie die statische Elementfunktion verwenden, um den für beide Klassen berechneten Wert zurückzugeben, sodass AllocFactor<T>T::value() als den Wert verwenden kann, der von der Config-Klasse gemeldet wird.