Arges Design Problem.



  • --- schrieb:

    1. das IManager kein foo kennt ist mir auch klar.
    2. Weils ein Manager ist?
    3. Es ist ein Testprogramm, da geht man auf sowas nicht ein, erst später.
    4. soll ich ihn public machen oder was?
    5. Wie soll ich denn sonst die manager unterscheiden? Mit RTTI? ne komm hau ab damit

    2. aber ein ziemlich spezieller Manager, ein ManagerManager eben, dafuer kann man schonmal eine eigenes Klassendesign auffahren

    4. schon mal an private gedacht?



  • --- schrieb:

    2. Weils ein Manager ist?

    Wahrscheinlich macht das bei dir Sinn. Ich bin dagegen etwas allergisch. Bei uns hat jemand entschieden, dass ein Logger, der Output Streams verwaltet, auch selbst ein Output Stream ist. Das war im Endeffekt nicht besonders nützlich, hat aber viele Probleme verursacht.

    --- schrieb:

    4. soll ich ihn public machen oder was?

    Private natürlich.

    --- schrieb:

    5. Wie soll ich denn sonst die manager unterscheiden? Mit RTTI? ne komm hau ab damit

    In der besagten Zeile benötigst du zwangsläufig, einen Bitmapmanager. Auf Anhieb fallen mir folgende Möglichkeiten ein:

    • dynamic_cast
    • Abfrage nach type_ und dann static_cast
    • Eine Methode getBitmapManager(), die den static_cast macht.


  • Ponto schrieb:

    • Eine Methode getBitmapManager(), die den static_cast macht.

    und wie soll er das machen? etwa eine template funktion virtual machen?



  • otze schrieb:

    Ponto schrieb:

    • Eine Methode getBitmapManager(), die den static_cast macht.

    und wie soll er das machen? etwa eine template funktion virtual machen?

    Enumeration:

    BitmapManager & ManagerManager::getBitmapManager() const
    {   
       return (BitmapManager) managers_[BITMAP_TYPE];
    }
    


  • Oder doch per Template wenn type in jedem Manager ein static int ist:

    template <typename T> T & ManagerManager::get_manager()
    {
        return managers_[T::type];
    }
    


  • Dann wäre der Manager nicht mehr so flexibel, denn ich glaube er will einfach Manager reinstopfen und nicht für jeden neuen Manager eine Getter-Funktion coden.



  • ey, das war ich nicht-.-

    template <typename T> T & ManagerManager::get_manager()
    {
        return managers_[T::type];
    }
    

    und das klappt niemals.



  • wieso wird das nicht funktionieren?



  • otze schrieb:

    ey, das war ich nicht-.-

    template <typename T> T & ManagerManager::get_manager()
    {
        return managers_[T::type];
    }
    

    und das klappt niemals.

    Ok, der cast fehlt noch.

    template <typename T> T & get_manager()
    {
       return (T&) *managers_[T::typ];
    }
    


  • ponto, das klappt net 😞



  • --- schrieb:

    ponto, das klappt net 😞

    Was klappt net?



  • #include <iostream>
    #include <string>
    #include <vector>
    
    class IManager
    {
    public:
        IManager    (void)
        { setType(0); std::cout << "C'tor IManager" << std::endl; }
        ~IManager   (void)
        { std::cout << "D'tor IManager" << std::endl; }
    
        void setType (int type)
        { type_ = type; }
        int getType (void) 
        { return (type_); }
    
        virtual void    restore (void) = 0;
        virtual void    load    (void) = 0;
    
    protected:
        static int     type_;
    };
    
    class BitmapManager : public IManager
    {
    public:
        BitmapManager    (void) 
        { setType( 1); std::cout << "C'tor BitmapManager" << std::endl; }
        ~BitmapManager   (void)
        { std::cout << "D'tor BitmapManager" << std::endl; }
    
        void restore (void)
        { std::cout << "BitmapManager: restore" << std::endl; }
        void load (void)
        { std::cout << "BitmapManager: load" << std::endl; }
    
        void bar (int i) {x=i;}
        void foo (void)
        { std::cout << "BitmapManager: foo "  << x << std::endl; }
    
    int x;
    };
    
    class WaveManager : public IManager
    {
    public:
        WaveManager    (void) 
        { setType( 2); std::cout << "C'tor WaveManager" << std::endl; }
        ~WaveManager   (void)
        { std::cout << "D'tor WaveManager" << std::endl; }
    
        void restore (void)
        { std::cout << "WaveManager: restore" << std::endl; }
        void load (void)
        { std::cout << "WaveManager: load" << std::endl; }
    
        void bar (void)
        { std::cout << "WaveManager: bar" << std::endl; }
    };
    
    class ManagerManager : public IManager
    {
    public:
        ManagerManager    (void)
        { std::cout << "C'tor ManagerManager" << std::endl; }
        ~ManagerManager   (void)
        { std::cout << "D'tor ManagerManager" << std::endl; }
    
        void restore (void)
        { std::cout << "ManagerManager: restore" << std::endl; 
            for (int i=0; i<managers_.size(); ++i)
                managers_[i]->restore();
        }
        void load (void)
        { std::cout << "ManagerManager: load" << std::endl; 
            for (int i=0; i<managers_.size(); ++i)
                managers_[i]->load();    
        }
    
    template <typename T> T & get_manager() 
    { 
       return (T&) *managers_[T::typ]; 
    }
    
        void addManager (IManager* manager)
        {
            managers_.push_back (manager);
        }
    
    private:
        std::vector <IManager*> managers_;
    };
    
    int main (void)
    {
        ManagerManager MM;
        BitmapManager *BM = new BitmapManager;
        WaveManager *WM = new WaveManager;
    
        BM->bar (9451);
    
        MM.addManager (BM);
        MM.addManager (WM);
    
        MM.restore ();
    
        BitmapManager BM2 = MM.get_Manager ();  // "get_Manager is not a member of ManagerManager"
    
        BM2.foo ();
    
        std::cin.get();
    }
    

    sorry wegen wieder soviel code 😞



  • #include <iostream>
     #include <string>
     #include <vector>
    
     class IManager
     {
     public:
         IManager    (void) : type_ (0)
         { std::cout << "C'tor IManager" << std::endl; }
         virtual ~IManager   (void)
         { std::cout << "D'tor IManager" << std::endl; }
    
         void setType (int type)
         { type_ = type; }
         int getType (void)
         { return (type_); }
    
         virtual void    restore (void) = 0;
         virtual void    load    (void) = 0;
    
         static int const typ = 0;
    
     protected:
         int     type_;
     };
    
     class BitmapManager : public IManager
     {
     public:
         BitmapManager    (void)
         { setType( 1); std::cout << "C'tor BitmapManager" << std::endl; }
         ~BitmapManager   (void)
         { std::cout << "D'tor BitmapManager" << std::endl; }
    
         void restore (void)
         { std::cout << "BitmapManager: restore" << std::endl; }
         void load (void)
         { std::cout << "BitmapManager: load" << std::endl; }
    
         void foo (void)
         { std::cout << "BitmapManager: foo" << std::endl; }
    
         static int const typ = 1;
     };
    
     class WaveManager : public IManager
     {
     public:
         WaveManager    (void)
         { setType( 2); std::cout << "C'tor WaveManager" << std::endl; }
         ~WaveManager   (void)
         { std::cout << "D'tor WaveManager" << std::endl; }
    
         void restore (void)
         { std::cout << "WaveManager: restore" << std::endl; }
         void load (void)
         { std::cout << "WaveManager: load" << std::endl; }
    
         void bar (void)
         { std::cout << "WaveManager: bar" << std::endl; }
    
         static int const typ = 2;
     };
    
     class ManagerManager : public IManager
     {
     public:
         ManagerManager    (void) : managers_(3)
         { std::cout << "C'tor ManagerManager" << std::endl; }
         ~ManagerManager   (void)
         { std::cout << "D'tor ManagerManager" << std::endl; }
    
         void restore (void)
         { std::cout << "ManagerManager: restore" << std::endl;
             for (unsigned int i=1; i<managers_.size(); ++i)
                 managers_[i]->restore();
         }
         void load (void)
         { std::cout << "ManagerManager: load" << std::endl;
             for (unsigned int i=0; i<managers_.size(); ++i)
                 managers_[i]->load();
         }
    
         IManager* getManager (int type)
         {
             for (unsigned i=0; i<managers_.size(); ++i)
                 if (managers_[i]->getType() == type)
                     return (managers_[i]);
         }
    
         template <typename T>
         T & get_manager()
         {
          return (T&) *managers_[T::typ];
         }
    
         void addManager (IManager* manager, int typ)
         {
             managers_[typ] = manager;
         }
    
     private:
         std::vector <IManager*> managers_;
     };
    
     int main (void)
     {
    
         ManagerManager MM;
         BitmapManager BM;
         WaveManager WM;
    
         MM.addManager (&BM, 1);
         MM.addManager (&WM, 2);
    
         MM.restore ();
    
         MM.get_manager<BitmapManager>().foo ();  // "fo is not a member of IManager"
    
         std::cin.get();
     }
    


  • MANN BIST DU GUT!!! BIST ECHT DA KING :D:D:D vielen dank 🙂



  • achja, frage:

    Verstoße ich damit nicht gegen irgendein OOP Privileg oder Gesetz?

    static int const typ = 0;

    nebenbei: wie ändere ich typ, wenn jetzt z.B. BitmapManager als typ die 2 hat aber an Position 4 im vector von ManagerManager steht?



  • --- schrieb:

    MANN BIST DU GUT!!! BIST ECHT DA KING :D:D:D vielen dank 🙂

    Lass mal, das entspricht bei weitem nicht der Realität.

    Der Code, den ich gepostet habe, ist deiner so erweitert, dass das Template funktioniert. Mehr als das Template zum Laufen bringen wollte ich nicht. Dazu habe ich zum Beispiel einfach jede Position des Array mit dem Managertyp festgelegt und den alten typ nicht entfernt. Weiterhin heisst es nicht, dass ich es so machen würde.

    Ein paar Fragen solltest du dir noch beantworten:

    - Soll es von jedem Managertyp genau einen geben, höchstens einen, oder beliebig viele?
    - Soll es möglich sein, durch Ineinanderschachtelung von ManagerManagern Ketten aufzubauen?
    - Wann werden die Manager ins Leben gerufen und wann verschwinden sie wieder?



  • --- schrieb:

    achja, frage:

    Verstoße ich damit nicht gegen irgendein OOP Privileg oder Gesetz?

    OOP ist nur ein Werkzeug, das man anwendet, und keine Religion, der man hörig folgen muss.

    --- schrieb:

    static int const typ = 0;

    nebenbei: wie ändere ich typ, wenn jetzt z.B. BitmapManager als typ die 2 hat aber an Position 4 im vector von ManagerManager steht?

    Dann gehst du wieder mit einer for Schleife über alle Elemente und vergleichst den Typ, den eine virtuelle get_type() Methode liefert. Oder je nach Kardinalität der Manager benutzt du einen assoziativen Container, wo es solche Probleme nicht gibt.



  • -ManagerManager soll nur 1x existieren, den rest kanns so oft geben wie will.
    -Ineinanderverschachtelungen? niemals.
    -Im laufe des programms



  • Ineinanderverschachtelungen? niemals.

    dann hats erst recht keinen sinn, ManagerManger von IManager abzuleiten, denn da er nicht selber in einem ManagerManager enthalten sein kann, kann er auch kein manager sein.

    dann würde ich auch pontos version ohne vorbehalt benutzen, ansonsten würde ich mir nen umweg suchen^^



  • okay lassen wir innenverschachtelungen doch zu, okay?


Anmelden zum Antworten