Class Factory___static member



  • erstmal der code, fragen stehen als kommentar drin:

    class GBase
    {
     public:
      virtual void Draw()=0;
      virtual int GetCounter()=0;
    };
    class GRectangle:public GBase
    {
     public:
      GRectangle(){rcounter++;}
      void Draw(){cout<<"Rechteck zeichnen"<<endl;}
      int GetCounter(){return rcounter;}
     private:
      static int rcounter;
    
    };
    class GCircle:public GBase
    {
     public:
      GCircle(){ccounter++;}
      void Draw(){cout<<"Kreis zeichnen"<<endl;}
      int GetCounter(){return ccounter;}
     private:
      static int ccounter;
    };
    class GPolygon:public GBase
    {
     public:
      GPolygon(){pcounter++;)
      void Draw(){cout<<"Polygon zeichnen"<<endl;}
      int GetCounter(){return pcounter;}
     private:
      static int pcounter;
    };
    
    int GRectangle::rcounter=0;
    int GCircle::ccounter=0;
    int GPolygon::pcounter=0;
    
    GBase* CreateIt()         //das ist class factory, ist die so io?
    {
      int i = rand()%50;
      if((i!=0)||(i!=1)||(i!=2))   //sollen zufaellige objekte erstellt werden
      {
       i = rand()%3;
      }
      GBase* G;
      switch(i)
      {
      case 0:  G = new GCircle;break;
      case 1:  G = new GPolygon;break;
      case 2:  G = new GRectangle;break;
      }
      return G;
    }
    
    int main(int argc, char* argv[])
    {
     GBase *G;
     for(int i=0;i<10;i++)
     {
      G = CreateIt();
     G->Draw();
     }
     cout<<G->GetCounter()<<" Objekte vom Typ "<<typeid(GCircle).name()<<endl;    //anzeige, wieviel objecte von jedem erstellt, wollte dazu static member in //jeder klasse nehmen, geht aber nicht richtig, denn er gibt immer 3 von jedem //aus...was bei 10 ja nicht geht....!
     cout<<G->GetCounter()<<" Objekte vom Typ "<<typeid(GRectangle).name()<<endl;
     cout<<G->GetCounter()<<" Objekte vom Typ "<<typeid(GPolygon).name()<<endl;
    
     getch();
            return 0;
    }
    

    hoffentlich kann einer helfen



  • und wie geb ich den speicher wieder richtig frei?? (Also G löschen!)



  • Was ist das überhaupt; ich versteh den Sinn dahinter nicht! 🙄 😕
    Speicher gibt man immer mit delete frei, wenn man ihn denn mit new anfordert...



  • ich will eben per zufall 10 verschiedene objekte erstellen, und ausgeben, wieviel von jedem erstellt wurden, das mit dem speicher hab ich hinbekommen!



  • komische art

    ich würde es so machen

    class CFactory  
    {
    
    public:
    	CFactory();
    	virtual ~CFactory();
    
      enum ObjectStrategy {
    
        iosFile,  // bestimme welcher adapter, sprich die fkt xyz soll wie bei file reagieren
        iosDb  // oder der adatper mit den fkt für db
    
      };
    
      static void SetStrategy( ObjectStrategy strategy);
      static CItf* GetInstance();
    private:
      static ObjectStrategy strategy_;
    };
    
    // cpp
    CFactory::ObjectStrategy CFactory::strategy_ = CFactory::iosFile;
    
    void CFactory::SetStrategy( ObjectStrategy strategy)  // bestimme welcher adapter
    {
      if(strategy == iosFile|| strategy == iosDb) {
        strategy_ = strategy;
      }
    }
    
    CItf* CFactory::GetIniTableInstance()  // erzeuge das object
    {
      CItf* result = 0;
      if( strategy_ == iosFile) {
    
        result = new CASystem;   // erster adapter
      }
      else if(strategy_ == iosDb) {
    
        result = new CBSystem;   // zweiter adapter
      }
    
      return result;   // gege object zurück
    }
    
    // gui.h
      CItf* my_Itf_;
      CBltf* my_BItf_;
    
    // in der anwendug z.b. Gui.cpp
    bool CGuiDlg::CreateObjects(int InternalStyle)  // kommt con comboboy auswahö oder menue oder wie auch immer
    {
    
    // hier "switche" ich zw 2 factories du brauchst nur eine
      bool bResult = false;   // benötige ich zum überprüfen
    
      if(my_Itf_) {
        delete my_Itf_;   // nur die braucsht du
      }
    
      if(my_uBItf_){
        delete my_BItf_;  // meine 2te factory, du hast nur eine
      }
    
      if( InternalStyle == 0 ){
        CFactory::SetStrategy( CFactory::iosFile );  // hui nur die
        CBFactory::SetStrategy( CBFactory::iosFile);  // 2te bei dir nicht vorhandene factory klasse
        bResult = true;
      }
      else {
        CFactory::SetStrategy( CFactory::iosDb);  // nur die
        CBFactory::SetStrategy( CBFactory::iosDb);  // 2te factory klasse
        bResult = true;
    
      }
      my_Itf_ = CFactory::GetIniTableInstance();  // hier gibts du das object zurpck
      my_BItf_ = CBFactory::GetIniTableInstance();
    
      return bResult;
    }
    
    // in konsturktor gleich am programmstart
    
      my_Itf_ = 0;   // ich hab das objekt hier nur einmal im gesamten programm
      my_BItf_ = 0;  // du kannst die dinger auch in einem vector legen oder wie auch immer
    
    // in "destruktor" von gui.cpp bei mfc ist dies was eigenes, bei dir am programmschluss halt
    
    void CUGuiDlg::OnDestroy() 
    {
      CDialog::OnDestroy();
    
      if( my_Itf_) {
        delete my_Itf_;
        my_Itf_ = 0;
      }
    
      if( my_BItf_) {
        delete my_BItf_;
        my_Itf_ = 0;
      }
    
    }
    

    ich hab die erzeugung in eine extra fkt gepackt namens CreateObjects

    du kannst da einen vector anlegen für deine 10 stück oder wie auch immer

    mein prinzip ist hatl ich erzeuge und kümmere mich nicht viel für das drumherum, da am schluss alles schoen terminiert. ist jetzt ein bsp code und ein codeschnipsel von mir nur, wenn ich was wichtiges vergessen habe, dann muesst ihr es selbst schreiben 🙂

    PS: was halten die anderen factory adapter bauer von meiner methode? wie würdet ihr das machen? ich benötigte für meine gui 2 versch. factories und benutze von der jeweiligen immer nur eine instanz ( je nachdem ob ich file oder db brauchte )



  • hm...so richtig versteh ich den ganzen code noch net, gibt es nicht auch einfachere methoden?

    Oder nochmal mit C++ Tags posten..??



  • Hallo,

    das hat einen ganz anderen Grund.

    for(int i=0;i<10;i++)
    {
        G = CreateIt(); // <<<<<
        G->Draw();
    }
    
    cout<<G->GetCounter()<<" Objekte vom Typ "<<typeid(GCircle).name()<<endl;    // <<
    cout<<G->GetCounter()<<" Objekte vom Typ "<<typeid(GRectangle).name()<<endl; // <<
    cout<<G->GetCounter()<<" Objekte vom Typ "<<typeid(GPolygon).name()<<endl;   // <<
    

    Du verwirfst in der Zeile ja das vorige Objekt. Wie soll 'G' also außerhalb der Schleife auf 3 versch.
    Objekte verweisen? Es wird eben nur auf das letzte welches erstellt wurde verwiesen. Du hast hier also
    3 Aufrufe von G->GetCounter(), warum sollte dieser Aufruf beim nächsten Mal etwas anderes zurückliefern?.

    Ich schätze mal die Ausgabe des Typs hat dich jetzt davon abgelenkt. Weil hier 3 versch. Typennamen
    ausgegeben werden wirst du wohl angenommen haben, dass 3 versch. Objekte mit im Spiel sind.



  • ja, also er erstellt nur GBase* Objecte!

    Wie kann ich das problem aber lösen jetzt?

    Und gibt es auch einfachere factoring methoden als die obere??



  • naja du erstellst die objekte in einer for schleife, d.h. die objecte gibt es NUR in der for schleife.

    nach der for schleife gibt es die objekte nicht mehr

    stichwort "Gültigkeitsberreiche"

    mach doch vor der for schleife

    #include <vector>
    ...
    std::vector<GBase> meine_Objekte_Vektor;
    

    in der forschleife

    meine_Objekte_Vektor.push_back(G);
    


  • hm...hab grad gemerkt, das wenn ich in der for schleife den typ anzeige, sind auch da alle objecte nur GBase*!

    Er gibt also garnich die "rictigen" objekteigenschaften mit!

    Hm...liegt wohl an meiner funktion, die GBase* zurückgibt?
    Wenn ja, wie muss der rückgabewert aussehn damit richtige infos mit übergeben werden??

    PS: Die Aufgabe ist aus einem Tutorial, und vectoren sind noch nicht behandelt wurden...



  • schau mal die werte von deinen int i an, ob es wirklich 0,1,2 sind. normalwerweise nimmt man auch srand funktion und da dann den bereich von [0,1,2] anzugeben

    nimm am besten debugger, oder lass dir notfalls dir den wert anzeigen


Anmelden zum Antworten