Design Pattern - Strategy



  • Was mache ich falsch bei dem Strategy design Pattern?
    ich bekomme beim erstellen eines Objektes der Klasse diese meldung:

    error C2259: 'Strategy': Instanz von abstrakter Klasse kann nicht erstellt werden
    1>          aufgrund folgender Member:
    1>          "void Strategy::strat(void)": ist abstrakt
    
    class Strategy
    {
    	public:
    
    		virtual void	strat() = 0;
    
    };
    
    class a : public Strategy
    {
    	public:
    		void strat()
    		{
    			cout << "aaaa";
    		};
    };
    
    int main(void)
    {
    	Strategy choose = a();
    
    	choose.strat();
    	system("Pause");
    	return 1;
    }
    


  • du instanziierst eine abstrakte klasse.



  • und was tue ich dagegen?
    Ich möchte später ja einen Vector mit Strategien füllen und mir dann die richtige aussuchen. Ich brauche eine gemeinsame Schnitstelle.



  • Dann nimmst du Zeiger, bzw. Smarte Zeiger:

    int main(void)
    {
        //Strategy * choose = new a;
        std::unique_ptr<Strategy> choose(new a());
        // std::shared_ptr<Strategy> choose(new a()); // wenn du mehrere Zeiger auf ein Objekt brauchst
    
        choose->strat();
    
        return 0;
    }
    


  • Was mache ich falsch bei dem Strategy design Pattern?

    Eigentlich alles!

    Zunächst solltest du dir angewöhnen den Destruktor bei Klassen mit virtuellen Funktionen als virtual zu deklarieren

    class IStrategie {
    public:
     virtual ~IStrategie() { } // <-- Virtueller Destruktor
     virtual void doSth() = 0;
    };
    

    2. Geht es bei dem Strategie-Muster darum, dass eine Klasse seine Eigenschaften zur Laufzeit ändert.
    Wenn du das unbedingt über new / delete machen willst, solltest du dir angewöhnen alle Speicherblöcke, die du mit new angefordert hast wieder freizugeben.

    class MyClass {
    public:
    
      MyClass() 
        :m_s(new Strategie1()) { }   // <-- Anfangsstrategie
    
      ~MyClass() {
        delete m_s;     // <-- delete
      }
    
      void set(IStrategie *st) {
        delete m_s;    // <-- delete
        m_s = st;
      }
    
      void doSth() {
        assert(m_s != nullptr);
        m_s->doSth();
      }
    
    private:
      IStrategie *m_s;
    
    };
    

    Nun kann deine Klasse zur Laufzeit seine Eigenschaften ändern.

    MyClass c;
    c.doSth();
    c.set(new Strategie2());
    c.doSth();
    // ...
    


  • Letzten beiden Antworten kombiniert = fein



  • Danke euch!
    Ich hab es jetzt wie hier übernommen und es Funktioniert wie gewünscht.
    Aber Funktion alleine war nicht der Plan, ich wollte eine schönere komfortable lösung für meine Konsole finden, wofür ich schon eine funktionale Lösung habe.
    Daher wärs schön wenn ihr mir noch ein,zwei tipps geben könntet.

    Kohle und Stahl schrieb:

    Wenn du das unbedingt über new / delete machen willst,...

    Wie sähe denn eine bessere Lösung aus?

    Gruß,
    Chris



  • cl90 schrieb:

    Aber Funktion alleine war nicht der Plan, ich wollte eine schönere komfortable lösung für meine Konsole finden, wofür ich schon eine funktionale Lösung habe.

    Hä? Was wofür?



  • Ich nutze das Strategy pattern jetzt dafür, um einen Vector aus Kommandos zu machen die alle eine unterschiedliche version von method() haben.



  • cl90 schrieb:

    Kohle und Stahl schrieb:

    Wenn du das unbedingt über new / delete machen willst,...

    Wie sähe denn eine bessere Lösung aus?

    Smartpointer

    unique_ptr z.B.

    http://en.cppreference.com/w/cpp/memory/unique_ptr



  • cl90 schrieb:

    Ich nutze das Strategy pattern jetzt dafür, um einen Vector aus Kommandos zu machen die alle eine unterschiedliche version von method() haben.

    ja und? soweit waren wir schon...
    Und dafür ist das Strategy-Pattern auch da. Aber dafür ist auch Verberung mit Polymorphie da...



  • Skym0sh0 schrieb:

    cl90 schrieb:

    Ich nutze das Strategy pattern jetzt dafür, um einen Vector aus Kommandos zu machen die alle eine unterschiedliche version von method() haben.

    ja und? soweit waren wir schon...
    Und dafür ist das Strategy-Pattern auch da. Aber dafür ist auch Verberung mit Polymorphie da...

    Und was ist dir jetzt unklar?

    @Kohle und Stahl
    Danke! versteh ich das richtig das unique_ptr selbständig meine Klassen wieder löscht, und verhindert das ich ungewollt mehrere Instanzen von einem Objekt erstelle?



  • cl90 schrieb:

    Skym0sh0 schrieb:

    cl90 schrieb:

    Ich nutze das Strategy pattern jetzt dafür, um einen Vector aus Kommandos zu machen die alle eine unterschiedliche version von method() haben.

    ja und? soweit waren wir schon...
    Und dafür ist das Strategy-Pattern auch da. Aber dafür ist auch Verberung mit Polymorphie da...

    Und was ist dir jetzt unklar?

    Was du mit Console und Funktion meinst...

    cl90 schrieb:

    @Kohle und Stahl
    Danke! versteh ich das richtig das unique_ptr selbständig meine Klassen wieder löscht, und verhindert das ich ungewollt mehrere Instanzen von einem Objekt erstelle?

    Nein, er löscht die dynamisch erzeugten Instanzen automatisch, das ist richtig. Aber er verhindert nicht, dass du mehrere Instanzen einer Klasse erstellst.



  • Mit Console meine ich etwas wie CMD bei windows. Wobei es in meiner Consolen Klasse nicht um darstellung sondern nur um verwaltung und ausführen meiner Befehle geht.


Anmelden zum Antworten