map + Defaultkonstuktor/Destruktor



  • Ich habe folgendes Problem beim Benutzen einer map:
    Sagen wir es sei folgende map gegeben:

    class MyClass{
      MyClass(){}
      ...
    };
    
    void f(void)
    {
      map<int,MyClass> m;
    }
    

    So wird beim Zugriff auf noch nicht besetzte Schlüssel

    MyClass x = m[10];
    

    ja bekanntlich der Defaultkonstruktor, also MyClass::MyClass() aufgerufen.

    Was aber geschieht nun, wenn ich diesem Wert etwas zuweise nachdem dies geschehen ist, bzw. wie kann ich auf das Geschehen Einflusss nehmen:

    m[10] = *new MyClass();
    

    Wird in diesem Fall erst der Destruktor des Objekts in m[10] aufgerufen und dann einfach der Verweis auf das neue Objekt verlegt oder wird hier der Zuweisungsoperator von MyClass aufgerufen?

    Vor allem: Wie kann ich's ändern wenn's mir so nich passt?



  • m[10] = *new MyClass();
    

    Hier wird ein Objekt des Typs MyClass auf dem Heap erzeugt und der Copy-operator aufgerufen, um das Objekt zu kopieren. Der Zeiger auf das erzeugte MyClass wird verworfen. Damit hast Du ein Speicherleck. Was Du wohl meinst ist:

    m[10] = MyClass();
    

    Hier wird ein Objekt des Typs MyClass auf dem Stack erzeugt (was sogar schneller geht) und mit dem Copy-Konstruktor kopiert. Das ursprüngliche Objet wird vom Stack entfernt und dabei der Destruktor aufgerufen.

    Tommi



  • Was Du wohl meinst ist:

    Ne, genau das(Loch) meine ich.

    Ich möchte aber nicht "by value" die Objekte speichern. Insofern kommen wohl nur Zeiger in Frage, da die map ja wohl Probleme mit Referenzen hat, nicht wahr?!?

    class MyClass{
      MyClass(){}
      ...
    };
    
    void f(void)
    {
      map<int,MyClass*> m;
    }
    

    Werden hier dann die Zeiger mit NULL initialisiert wenn ich auf unbesetzte Felder zugreife?



  • Ich denke ja. Und du mußt daran denken, die Zeiger am Ende der Arbeit wieder freizugeben:

    map<int,MyClass*> m
    m[10] = new MyClass();
    m[20] = new MyClass(4711);
    ...
    
    //Freigabe - muß passieren, bevor m aus dem Scope fällt:
    for(map<int,MyClass*>::iterator pos=m.begin();pos!=m.end();++pos)
      delete pos->second;
    

Anmelden zum Antworten