Standardkonstruktor für eigene Klassen in Klassen.



  • Hi,

    Ich würde gerne eine eigene Klasse erstellen, welche wiederum eigene Klassen enthält. Siehe Code unten.

    Nun soll ein leeres Objekt der übergeordneten Klasse Fahrzeug erstellt werden, das ich später nach Bedarf füllen kann.

    Ich habe keine Ahnung wie ich das mit dem Standardkonstruktor mache.
    Kann ich nicht einfach der Fahrzeugklasse sagen, dass der Standardkonstruktor für alle unterklassen und der Oberklasse "leere" Elemente erzeugt ?

    also in etwa:

    class Fahrzeug
    {
    public:
    	Fahrzeug() :
    		Auto(NULL), Fahrrad(NULL), Schiff(NULL){};
    	Fahrzeug_PKW Auto;
    	Fahrzeug_Fahrrad Fahrrad;
    	Fahrzeug_Schiff Schiff;
    }
    
    class Fahrzeug_PKW
    {
    public:
    	string Farbe;
    	int PS;
    };
    
    class Fahrzeug_Fahrrad
    {
    public:
    	string Werkstoff;
    	int Anzahl_reifen;
    };
    
    class Fahrzeug_Schiff
    {
    public:
    	string Hersteller;
    	int Laenge;
    };
    
    class Fahrzeug
    {
    public:
    	Fahrzeug() :
    		Auto(NULL), Fahrrad(NULL), Schiff(NULL){};
    	Fahrzeug_PKW Auto;
    	Fahrzeug_Fahrrad Fahrrad;
    	Fahrzeug_Schiff Schiff;
    }
    
    int main()
    {
    	Fahrzeug meinfahrzeuge; <<---- hier erzeugen eines "leeren" Objektes
    	meinfahrzeuge.Auto.Farbe = "Rot";
    	cout << meinfahrzeuge.Auto.Farbe << endl;
    	return 0;
    }
    


  • Das würde man eher mit Vererbung lösen anstatt mit diesem Konstrukt.

    Die Initialisierungsliste kannst du auch einfach weglassen die Objekte in deiner Klasse sind richtige Objekte und keine Pointer NULL macht da keinen Sinn.



  • Ok, das Beispiel war bisschen schlecht, gehen wir aber davon aus, dass die drei "Unterklassen" sich überhaupt nicht ähnlich sind und es keinen Sinn macht, das diese Klassen voneinander erben.



  • maniche schrieb:

    Ok, das Beispiel war bisschen schlecht, gehen wir aber davon aus, dass die drei "Unterklassen" sich überhaupt nicht ähnlich sind und es keinen Sinn macht, das diese Klassen voneinander erben.

    Ok, Unterklasse klingt unter Umständen ein wenig irreführend du möchtest, dass ein Objekt andere eigenständige Objekte als Member hat?

    Das kannst du einfach machen, dass ist kein Problem.

    Wenn es sein kann, dass einige Objekte gar nicht in dem Lebenszyklus des Objektes geladen werden oder du willst, dass die Objekte auf dem Heap liegen machst Du (falls die Klasse resource owner ist) ein unique_ptr oder ein shared_ptr daraus, ansonsten kannst du auch einen nativen Pointer benutzen.

    Ansonsten kannst du auch set und get Funktionen implementieren und es darüber machen.

    Ansonsten kannst du auch einfach, dass Objekt auf dem Stack lassen so definieren, dafür brauchst du nur einen leeren Standard Konstruktor und rufst vielleicht eine initialize Funktion im Konstruktor der Klasse auf.

    Edit: sorry undrücklich ausgedrückt.

    class Alpha{};
    
    class Omega
    {
    public: 
    Omega(Alpha * al) : my_res(nullptr), ptr(al)
    {
    my_res = std::make_unique<Alpha>();
    
    }
    private:
    std::unique_ptr<Alpha> my_res;
    Alpha * ptr;
    Alpha al;
    
    };
    


  • Du verwendest Begriffe sehr ungünstig (Unterklasse die keine Unterkalsse sein soll oder leere Klasse).
    Wie auch immerLeere Klasse soll wohl default-constructed sein und da hat Ruvi die Antwort doch schon gegeben:

    Wenn die Member nicht in der Initialisierungsliste auftauchen, werden sie mit dem default-Ctor erzeugt.
    Oder expliziet in der Liste mit z.B.: Auto{}

    Edit: zu spät.
    @Ruvi: Memeber einer Klasse landen nicht einfach auf dem Stack. Weiss nicht ob du das meintest, aber liest sich so.



  • Vielleicht suchst du boost::variant .



  • Ok Danke.

    also wenn ich das richtig verstehe:

    class Fahrzeug 
    { 
    public: 
        unique_ptr<Fahrzeug_PKW> Auto; 
        unique_ptr<Fahrzeug_Fahrrad> Fahrrad; 
        unique_ptr<Fahrzeug_Schiff> Schiff; 
    }
    

    und wenn ich dann später einen Wert zuordnen will ?

    Fahrzeug meinFahrzeug;
    
    meinFahrzeug.Fahrzeug_PKW->Farbe = "rot";
    

    leider funktioniert "meinFahrzeug.Fahrzeug_PKW->Farbe = "rot";" nicht ?



  • Du hast das Objekt auch mit make_unique erzeugt und hast nicht nur einen leeren Pointer?

    Edit: du musst natürlich den Namen des Pointers und nicht der Klasse verwenden.



  • sorry war ein Tippfehler:

    meinFahrzeug.Auto->Farbe = "rot"; geht leider auch nicht 😞



  • ich glaube ich schreibe jetzt einfach nen Standardkonstruktor für meine "Oberklasse".



  • Du hast meine Frage nicht beantwortet.

    Du hast in deinem Code auch irgendwo make_unique<>() stehen wie in dem Beispiel, dass ich gepostet hatte?



  • Wozu denn hier die ganzen Pointer? Bis jetzt sehe ich keinen Bedarf dafür.

    class Fahrzeug 
    { 
    public: 
        Fahrzeug_PKW Auto; 
        Fahrzeug_Fahrrad Fahrrad; 
        Fahrzeug_Schiff Schiff; 
    };
    

    Das reicht doch.


Anmelden zum Antworten