Wird bei der Arrayinitialisierung der Konstruktor des Arraytyps aufgerufen?



  • Nathan schrieb:

    Deshalb holt sich der echte std::vector ja auch einen unitialisierten Speicherbereich via ::operator new (indirekt, durhc Alloc) und ruft erst bei Bedarf den CTor auf.

    Wann sieht der echte Vector den Bedarf den CTor nicht aufzurufen?
    Im folgenden Code wird er 5x aufgerufen. Ich bin der Meinung das er immer aufgerufen wird, sobald Speicher neu-allokiert wird.

    class MyClass {
    public:
      MyClass() {
        std::cout << "C'tor called" << std::endl;
      }
    
      ~MyClass() {
      }
    };
    
    int main() {
      std::vector<MyClass> v(5);
    }
    


  • jb2603 schrieb:

    Wann sieht der echte Vector den Bedarf den CTor nicht aufzurufen?

    Wenn man nur reserve'd und nicht resize'd.



  • Vielen Dank Leute. Hat mir sehr geholfen.

    Die Idee vector<Transition*> zu benutzen ist genial - da hätte ich mal selber drauf kommen können 😃 - danke dafür.

    Kann mir vielleicht noch einer den Nutzen dahinter erklären, also warum der Ctor aufgerufen wird? Dient das nur dem Zweck den Speicher nicht undefiniert zu lassen falls man das Objekt abfragt bevor überhaupt eins erzeugt wurde?


  • Mod

    Code4Fun schrieb:

    Dient das nur dem Zweck den Speicher nicht undefiniert zu lassen falls man das Objekt abfragt bevor überhaupt eins erzeugt wurde?

    Du beschreibst das, als wäre das nur eine kleine Unannehmlichkeit, wenn das passieren würde.



  • Code4Fun schrieb:

    Kann mir vielleicht noch einer den Nutzen dahinter erklären, also warum der Ctor aufgerufen wird? Dient das nur dem Zweck den Speicher nicht undefiniert zu lassen falls man das Objekt abfragt bevor überhaupt eins erzeugt wurde?

    Wenn kein Ctor aufgerufen wird dann gibt es das Objekt schlicht und ergreifend nicht. Ob der Speicher reserviert wurde spielt dabei keine Rolle -- ein Stückchen Speicher wird halt nicht einfach dadurch zu einem Objekt einer bestimmten Klasse indem man es sich wünscht. Oder einen Zeiger diesen Typs auf den Anfang dieses Speichers erzeugt.

    Und wenn man auf ein Objekt zugreift das nicht existiert, dann ist das ein ganz grober Fehler.

    Und das gilt auch wenn der erste Zugriff etwas wie z.B. der operator = ist.

    Also...
    ANGENOMMEN dass vector::resize KEINEN Konstruktor aufrufen würde, dann wären BEIDE Verwendungen im Beispiel unten FALSCH:

    void Foo()
    {
        vector<string> v1;
        v1.resize(123);
        size_t s1 = v1[0].size(); // Fehler
    
        vector<string> v2;
        v2.resize(123);
        v2[0] = std::string("foo"); // AUCH ein Fehler
    }
    


  • Code4Fun schrieb:

    Ist das soweit korrekt? Ich dachte nämlich bisher dass einfach nur der nötige Speicher reserviert wird und sonst nichts passiert.

    Selber testen wäre höchst angebracht gewesen.
    https://ideone.com/vxAPu9

    #include <iostream>
    using namespace std;
    
    struct Tester{
    	Tester(){
    		cout<<"hello, world!\n";
    	}
    };
    
    int main(){
    	Tester array[10];
    }
    


  • sebi707 schrieb:

    Ja der Konstruktor wird immer aufgerufen.

    Kann man jetzt so auch nicht sagen 🙂

    A* pa = (A*)::operator new(sizeof(A));
    

  • Mod

    Mr.Long schrieb:

    sebi707 schrieb:

    Ja der Konstruktor wird immer aufgerufen.

    Kann man jetzt so auch nicht sagen 🙂

    A* pa = (A*)::operator new(sizeof(A));
    

    Und was hast du hier, außer einem Zeiger auf rohen Speicher?



  • A* pa = cast<A*>(4711);
    

    aber das Zeigern auf toten Speicher hat wenig mit der Frage zu tun.



  • Arcoth schrieb:

    Mr.Long schrieb:

    A* pa = (A*)::operator new(sizeof(A));
    

    Und was hast du hier, außer einem Zeiger auf rohen Speicher?

    Ich bin mir immer noch nicht sicher was der TO überhaupt möchte. Geht es um die Programmierung eines eigenen vector der nicht automatisch den Konstruktor aufruft oder geht es um die internen Strukturen des vectors? Also wenn der vector seinen Speicherbereich vergrößert und einige Elemente am Ende noch nicht belegt sind? Im letzteren Fall wäre Speicher mit ::operator new reservieren und dann nur die benötigten Objekte mit placement new erzeugen, das was man meiner Meinung nach tun sollte.



  • Arcoth schrieb:

    Mr.Long schrieb:

    sebi707 schrieb:

    Ja der Konstruktor wird immer aufgerufen.

    Kann man jetzt so auch nicht sagen 🙂

    A* pa = (A*)::operator new(sizeof(A));
    

    Und was hast du hier, außer einem Zeiger auf rohen Speicher?

    Hängt von der Implementierung des operators new ab 😃


Anmelden zum Antworten