Mehrere Objekte erstellen in einem Array



  • @loolery sagte in Mehrere Objekte erstellen in einem Array:

    @SeppJ Andere Sprachen bekommen das ja sonst hin den Speicher beim laden der Array direkt zu reservieren für die spätere Belegung, davon bin ich bisher wohl einfach zu verwöhnt gewesen. Aber danke für deine doppelte und ausführliche Erklärung.

    Welche denn? Es geht hier ja nicht um Reservierung von Speicher, sondern um das Erzeugen von Objekten. Ein test foo[5] erzeugt 5 Test-Objekte, nicht 5 (möglicherweise auf nullptr gesetzte) Pointer auf Objekte. C++ arbeitet direkt mit Objekten, nicht implizit mit Pointern/Referenzen, außer du nutzt diese explizit.

    Wenn du nur Speicher reservieren willst: vector.reserve()


  • Mod

    @loolery sagte in Mehrere Objekte erstellen in einem Array:

    @SeppJ Andere Sprachen bekommen das ja sonst hin den Speicher beim laden der Array direkt zu reservieren für die spätere Belegung, davon bin ich bisher wohl einfach zu verwöhnt gewesen. Aber danke für deine doppelte und ausführliche Erklärung. 🙂

    Nein, solche Sprachen gibt es nicht. Du verstehst das Problem nicht, wenn du denkst, solche Sprachen könnte es geben. Es ist ein Logikfehler in deinem Programm (oder in deinem Verständnis). Das hat mit egal welcher Sprache nichts zu tun, denn Logik ist in jeder Sprache gleich, und somit auch Fehler in der Logik.

    Du kannst nicht Wahrhaft behaupten "Ich habe einen Korb mit 5 Äpfeln" ohne dass du 5 Äpfel in dem Korb hast. Egal ob auf Deutsch, C++, oder jeder anderen Sprache. "Ich habe einen Korb mit 5 Äpfeln" ist nicht das gleiche wie "Ich habe einen Korb mit Platz für 5 Äpfel". Letzteres kann auch wahr sein, ohne dass 5 Äpfel im Korb sind. Sowohl auf Deutsch, C++, oder jeder anderen Sprache. Ein statisches array<Apfel, 5> ist aber ein Korb in dem 5 Äpfel drin sind, nicht bloß ein Korb in dem Platz für 5 Äpfel ist. Wenn du so einen Korb mit 5 Äpfeln drin erstellst, dann müssen die 5 Äpfel irgendwo herkommen, ansonsten ist es kein Korb mit 5 Äpfeln drin.



  • Doch, Sprachen wie Java oder C#. Dort wird dann ein Array bei Referenztypen mit null bzw. in C# bei Wertetypen mit 0 Byte Werten belegt. Und dann kann man nachträglich den einzelnen Array-Werten mittels new(...) neue Werte zuordnen.
    In C++ muß man aber dafür dann explizit Zeiger (bzw. Shared-Pointer) verwenden.


  • Mod

    Wertetypen und Zeiger werden in C++ auch automatisch nullinitialisiert, wenn man nix sagt (was nicht einmal unbedingt null/0 heißt). Aber das test ist halt kein solcher Typ. Da ist in Java das Array[test] eben nur ein verkapptes Array[*test]. Auch Java könnte nicht zaubern, und würde genauso meckern, wenn man ein new(test) ohne Argumente macht.



  • @Th69 sagte in Mehrere Objekte erstellen in einem Array:

    Doch, Sprachen wie Java oder C#. Dort wird dann ein Array bei Referenztypen ...

    Ich habe das wichtige Wort mal markiert. Das ist aber doch hier genau der Unterschied! Es sind hier eben keine test *foo[5] oder std::unique_ptr<test> foo[5] deklariert (5 mögliche foos), sondern test foo[5]. Das sind 5 explizit verlangte foos. In C++ sind Klassen nicht automatisch Referenztypen. Wenn man dann sagt "aber mit Referenztypen geht das in Sprache XY", dann ist das eben nicht das gleiche.



  • Mal ganz einfaches Beispiel in vbsript, wie andere Sprachen das lösen, in C#, Java oder Basic überall so ähnlich auch möglich:

    Class testklasse
        private myid
        
        Public Default Function Init(i)
            myid = i
            Set Init = Me
        End Function
        Public Property Let ID(byVal value)
            myid = value
        End Property
        Public Property Get ID
            ID = myid
        End Property
    End Class
    
    Dim objTest(4), ausgabe
    For i=0 To 4
        'ReDim Preserve objTest(i) <- optional in der schleife auch erst reservierbar
        Set objTest(i) = (New testklasse)(i)
    Next
    For r=0 To UBound(objTest)
        ausgabe = ausgabe & " - " & r
    Next
    MsgBox(ausgabe)
    

    Für mich als nicht Kernel-Treiber Hardcore coder ist es so zumindest deutlich angenehmer zu schreiben.🤷



  • Das ist aber was anderes, als du in C++ programmiert hast. In deinem C++ Quelltext hast du explizit gesagt, dass du deine Objekte ausschließlich über einen Konstruktor mit 2 Parametern erzeugen möchtest. Dann darfst du dich also auch nicht beschweren, dass die Konstruktion sperrig ist, das hast du selbst so vorgegeben.

    Du kannst natürlich deine Objekte mit ungültigen Werten default-konstruieren:

    #include <string>
    
    class Test
    {
       int ID_ = -1; // Annahme: -1 ist eine ungültige ID
       std::string Name_;
    public:
       Test() = default; // Default Konstruktor erlauben
       Test( int id, std::string const& name ) :
          ID_( id ), Name_( name )
       {
       }
       ...
    }
    

    Damit kannst du auch "ungültige" Objekte erzeugen, aber dann stellt sich die Frage, warum du ungültige Objekte erzeugst und in einem Array/std::array ablegst, statt einen std::vector zu pflegen, der nur gültige Objekte enthält.



  • Das hat man doch schon versucht, Dir zu erklären ...
    Das kannst Du in C++ ähnlich machen, allerdings hast Du dann eben kein Array von Objekten, sondern ein Array von Zeigern/Referenzen auf Objekte.
    In Deinem Beispiel werden die Objekte erst in der Schleife erstellt (Zeile 19).

    Wenn Du in C++ ein Array mit:

    Klasse array[5];
    

    definierst, dann werden an der Stelle 5 Objekte vom Typ Klasse erstellt.
    Dein Beispiel sähe in C++ etwa so aus:

    Klasse * array[5];
    

    Dann hast Du ein Array, das nicht Objekte enthält, sondern Zeiger auf Objekte, und diese Zeiger kannst Du dann später auf Objekte zeigen lassen, die Du dann zB in einer Schleife erstellst ...



  • @DocShoe Das der Konstruktor nur 1 Parameter erfordert war gerade rein meiner Faulheit geschuldet, das gleiche mit 2 oder 20 Parametern zu machen ist kein großes Hexenwerk in vbs.



  • @loolery sagte in Mehrere Objekte erstellen in einem Array:

    @DocShoe Das der Konstruktor nur 1 Parameter erfordert war gerade rein meiner Faulheit geschuldet, das gleiche mit 2 oder 20 Parametern zu machen ist kein großes Hexenwerk in vbs.

    Das ist nicht das, was ich meinte. Du kannst in C++ steuern, wie Objekte erzeugt werden. Wenn du alle Konstruktoren bis auf einen deaktivierst, dann darfst du dich nicht beschweren, dass du Objekte nicht frei Schnauze konstruieren kannst, sondern auf diesen einen Konstruktor beschränkt bist.



  • @Belli sagte in Mehrere Objekte erstellen in einem Array:

    Das kannst Du in C++ ähnlich machen, allerdings hast Du dann eben kein Array von Objekten, sondern ein Array von Zeigern/Referenzen auf Objekte.

    Oder man nutzt std::optional.


Anmelden zum Antworten