suche design pattern für mein problem



  • also ich habe eine klasse welche irgendwelche warscheinlichkeiten aufgrund
    eingabedaten berechnet, z.B.

    class ProbCalc
    {
     virtual double calcProbs(const Vector<float>& input) = 0;
    };
    

    ich möchte nun sowas wie einen prob-calculator, bei dem man
    aber dynamisch die Art der Berechnung setzen kann, also in etwa so

    class Calc
    {
    
    void setCalculator(const ProbCalc& calc);
    
    };
    

    kann mir mal jemand eine link geben, wie man sowas implementiert?
    Ich kann zwar stupide rangehen und sowas machen :

    class Calc
    {
    
    void setCalculator(ProbCalc& calc)
    {
    m_calc = &calc;
    }
    
    double calc(const Vector<float>& input)
    {
    return m_calc->calc(input);
    }
    
    private :
    
    ProbCalc * m_calc;
    };
    

    aber das ist mehr als unschön (lebenszeit von beidem usw),
    der calc in setCalculator(ProbCalc& calc) soll übrigens kopiert werden,
    damit niemand später an den parametern rumspielt, deshalb bringt mich
    shared_ptr irgendwie auch nicht weiter, ich hab mir das so gedacht

    void setCalculator(const ProbCalc& calc)
    {
    if(m_calc) { delete m_calc; }
    m_calc = new ProbCalc(calc);
    }
    

    würde mich über vorschläge freuen



  • Funktionspointer kommen nicht in Frage?



  • ich denke was du suchst, heißt STrategy-Pattern. Ist aber eigentlich so implementiert wie dus hier schon zeigst.

    im magazin steht zB was dazu (artikel über design patterns)



  • Das Problem ist, dass du ProbCalc als abstrakte Klasse weder direkt instanziieren noch kopieren kannst. Mir fallen jetzt zwei Alternativen ein:

    class ProbCalc {
    private:
      virtual ProbCalc* clone() const = 0;
    };
    
    class Calc
    {
    void setCalculator(ProbCalc const& calc)
    { p_calc.reset(calc.clone()); }
    
    double calc(const Vector<float>& input)
    { return p_calc->calc(input); }
    
    private :
    auto_ptr<ProbCalc> p_calc;
    };
    

    Damit hättest du allerdings ein Objekt außerhalb von Calc, für das du zuständig bist und vermutlich garnicht brauchst, und müsstest außerdem noch für alle PobCalc-Abkömmlinge eine clone-Funktion schreiben. Alternative daher:

    class Calc
    {
    void setCalculator(ProbCalc* pcalc)
    { p_calc.reset(pcalc); }
    
    double calc(const Vector<float>& input)
    { return p_calc->calc(input); }
    
    private :
    auto_ptr<ProbCalc> p_calc;
    };
    
    int main() 
    {
      Calc myCalc;
      myCalc.setCalculator(new FunnyProbCalc("haha"));
      myCalc.setCalculator(new OtherProbCalc(2.4, 3));
    }
    

    hier übernimmt Calc die Kontrolle über einen dynamisch erzeugten ProbCalc-Abkömmling, kümmert sich um dessen Zerstörung usw.



  • Das Problem mit Funktionspointern wäre wieder,
    das der Calculator das Benutzende Object überleben müsste,

    aber ich denke ich hab nun alles soweit verinnerlicht, das ich es implementieren
    kann, danke



  • Das Problem würde nicht bestehen, wenn die unterschiedlichen Berechnungsarten statisch wären.


Anmelden zum Antworten