Je nach Eingabe unterschiedliche Objekte erstellen



  • Hallo,

    ich habe folgende Struktur:

    class Base
    {...};
    
    class Derived1 : public Base
    {...};
    
    ...
    
    class DerivedN : public Base
    {...};
    

    Angenommen ich möchte nach Eingabe einer Zahl i die Klasse Derivedi instanziieren. * Geht das elegant ohne sowas wie ein switch-statement?

    Bye.

    ----
    * Das Beispiel ist natürlich stark vereinfacht



  • std::map<int, factoryMethod>
    

    Nun brauchst du nur noch
    😉 deine Factory-Methoden erstellen
    😉 diese (Methodenzeiger) in der map zum passenden "i" einfügen

    // edit:
    Hier ein kleines Beispiel:

    #include <iostream>
    #include <map>
    using namespace std;
    
    struct Base {
        virtual void print() const {
            cout << "Base" << endl;
        }
    };
    Base* createBase() {
        return new Base;
    }
    
    struct Der1 : public Base {
        void print() const {
            cout << "Derived 1" << endl;
        }
    };
    Base* createDer1() {
        return new Der1;
    }
    
    struct Der2 : public Base {
        void print() const {
            cout << "Derived 2" << endl;
        }
    };
    Base* createDer2() {
        return new Der2;
    }
    
    typedef Base* (*factory)();
    typedef std::map<int, factory> FactoryMap;
    
    int main() {
        FactoryMap map;
        map[0]=createBase;
        map[1]=createDer1;
        map[2]=createDer2;
    
        Base* b = map[0]();
        b->print();
        delete b;
        b = map[1]();
        b->print();
        delete b;
        b = map[2]();
        b->print();
        delete b;
    }
    

    Sollte am Ende kein Integer, sondern ein string als key verwendet werden (ist ja auch was schönes), dann nimm etwas, das einen vernünftigen operator== hat. std::string ist gut, const char* weniger 😉



  • Wege gibt es da viele. Zum Beispiel Funktionszeiger.
    Aber da viele sich vor Base*(*tabelle[])() fürchten, werden auch gerne Hilfsklassen gebastelt, wobei jede Hilfsklasse ein Hauptklassenobjekt erzeugen kann mit ihrer virtuellen Funktion und in der Tabelle stehen Hilfsbasisklassenzeiger.

    #include <iostream>
    using namespace std;
    
    struct Base{
    	virtual void test()=0;
    };
    struct Derived1:public Base{
    	void test(){
    		cout<<"Derived1\n";
    	}
    };
    struct Derived2:public Base{
    	void test(){
    		cout<<"Derived2\n";
    	}
    };
    struct Derived3:public Base{
    	void test(){
    		cout<<"Derived3\n";
    	}
    };
    
    Base* make1(){
      return new Derived1;
    }
    Base* make2(){
      return new Derived2;
    }
    Base* make3(){
      return new Derived3;
    }
    Base*(*tabelle[])()={0,make1,make2,make3};
    
    int main(){
    	cout<<"Gibstu Zahl ein uzwischen 1 und 3: ";
    	int i;
    	cin>>i;
    	if(i>=1 && i<=3){
    		Base* b=tabelle[i]();
    		b->test();
    	}
    }
    


  • Hallo,

    danke an euch beide. Ich sehe nun dass ich die C++-Beschränkung, keine Typen in einer Variablen speichern zu können in diesem Fall durch das Speichern von Funktionszeigern umgehen kann.


Anmelden zum Antworten