[gelöst] Inhalt eines Vectors tauschen



  • Hallo,

    ich bräuchte mal ein bisschen denkhilfe:

    class MyClass;
    typedef std::vector<MyClass*> MyVector;
    
    MyVector Veci;
    
    Veci.push_back(new MyClass(0));
    
    MyClass* M1 = new MyClass(1);
    Veci.push_back(M1);
    
    Veci.push_back(new MyClass(2));
    
    MyClass* M3 = new MyClass(3);
    Veci.push_back(M3);
    
    Veci.push_back(new MyClass(4));
    

    Ich müsste nun die Position 1 mit Position 3 tauschen OHNE einen Copy-CTor anzuwerfen.

    Bisher mache ich das so:

    MyVector::iterator iteins = std::find(Veci.begin(),Veci.end(),M1);
    MyVector::iterator itdrei = std::find(Veci.begin(),Veci.end(),M3);
    Veci.insert(iteins, *itdrei);
    Veci.insert(itdrei , *iteins);
    Veci.erase(iteins);
    Veci.erase(itdrei);
    

    Sprich, ich suche die Iteratoren, füge jeweils vor den Treffern eine Kopie des anderen als Zeiger ein und lösche die Ursprünglichen.
    Klappt, wirkt mir aber etwas sehr kompliziert.

    Gibt es da einen leichteren Weg?

    Ich hab das gleiche Problem auch noch bei Listen, bei denen ich fürs Tauschen NUR die Iteratoren habe. Daher wäre mir eine Lösung die anhand von Iteratoren für Liste und für Vector funktioniert am Liebsten.

    Kennt jemand ein paar Befehle für mich und aus diesen 4 Befehlen (sehr rechenaufwändig) evtl. 1-2 (rechenleichte) Befehle zu machen und trotzdem keinen Copy-Constructor zu verwenden?

    Danke,
    Stefan



  • ...und wie ich gerade festgestellt habe bekomme ich auch Speicherschutzverletzungen, weil nach dem ersten einfügen meine Iteratoren nicht mehr gültig sind. *fluch*


  • Mod

    Greif doch über die Iteratoren auf die Elemente zu, dafür sind sie doch da. Dann tauscht du den Inhalt der Elemente. Dazu ist ein Copykonstruktor/Zuweisungsoperator quasi unvermeidlich. Da bloß zwei Zeiger getauscht werden verstehe ich nicht, warum du dich dagegen sperrst. Was meinst du wie oft diese Funktionen wohl bei deiner insert-erase-Orgie benutzt werden?

    P.S.: Und ich hoffe doch, dass dies nur zu Übungszwecken ist und du nicht wirklich so mit Zeigern hantierst wie hier gezeigt.



  • Ich meine bei CopyConstructor nicht einen für Zeiger. Sondern einen, der mein ganzes Element kopiert, denn ich nutze Fremdklassen und die sind ...sagen wir mal... nicht sehr zuverlässig bei CopyConsrtuctoren in Sachen Zeigerelemente innerhalb der verwendeten Klasse. Gegen Zeiger-Copy-Constructoren hab ich nix, weil die hab ich ja im Griff.

    Zu übungszewcken ist es nicht, sondern eher der erste Entwurf eines Klassen-Templates für eine gefilterte Sortierung verscheidener Midi-Befehle (Beispiel: Berechnung von Obertönen für Mixturen bei Orgelmusik).

    Mit Klassen-Templates hab ich noch nicht wirklich viel erfahrung gemacht und momentan stehe ich jetzt an dem folgenden Punkt:

    template <typename Arg_Type, typename Inlay_Type>
    bool ListSort<Arg_Type, Inlay_Type>::ListMoveSwitchPos(typename Arg_Type::iterator& theItToMove, typename Arg_Type::iterator& theItToSwitch)
    {
      return false;
    }
    
    // Anwendung
    typedef MyClass* ListInnen;
    typedef std::list<ListInnen> ListAusen;
    
    ListAusen MyListe;
    // Daten in die Liste
    ListSort<ListAusen, ListInnen> Sortierer(&MyListe);
    Sortierer.OrderNachObertonreihe(); // Hier werden jetzt viele viele Sortierungen vorgenommen und doppelte Töne nach Laufstärke sortiert und die leisesten fallen raus.
    

    Ein Template wird es deswegen, weil meine Midi-Schnittstelle von meinem Freund hier teilweise mit vector und teilweise mit list arbeitet.



  • stefanjann schrieb:

    ...

    class MyClass;
    typedef std::vector<MyClass*> MyVector;
    // ...
    

    Ich müsste nun die Position 1 mit Position 3 tauschen OHNE einen Copy-CTor anzuwerfen.

    Also entweder verstehe ich dein Problem nicht wirklich, oder du verstehst dein eigenes Problem nicht. Solange du in dem Vector nur Zeiger hältst, und nur diese tauschst, wird niemals ein Kopierkonstruktor aufgerufen.



  • Äh...

    std::swap(Veci[1], Veci[3]);
    

    ?



  • asc schrieb:

    Also entweder verstehe ich dein Problem nicht wirklich, oder du verstehst dein eigenes Problem nicht. Solange du in dem Vector nur Zeiger hältst, und nur diese tauschst, wird niemals ein Kopierkonstruktor aufgerufen.

    Hallo,
    also ich glaube "ich verstehe mein Problem nicht."

    Ich hab gestern noch ein bisschen "gespielt" und mir die Sache mit den Copy-Constructor nochmal zu herzen geführt. Und auch nochmal (zum tausendsten Mal) das Prinzip Zeiger, Referenzen und operator= durchgelesen.

    Tja, also PHP und JavaScript programmierer muss man sich da halt keine Gedanken machen. Aber jetzt unter C++ ist das halt wichtig. Ich will halt eine stabile und schnelle Klasse schreiben.

    Aber du hast recht, da ich ja "nur" Zeiger habe ist das kein Problem. Und wenn ich nicht will, dass ein Copy-Constructor innerhalb einer Klasse definiert werden muss, dann lege ich halt "nur" Zeiger in der Liste ab und beachte beim d'tor, den Vector mit "delete"s aufzuräumen und plötzlich: Kein Problem mehr.

    Sorry, da bin ich gestern wohl etwas "auf der Leitung" gesessen. Tja ich hab halt "erst" ein Jahr Praxis mit C++.
    Danke für euch.

    Achja:

    seldon schrieb:

    std::swap(Veci[1], Veci[3]);
    

    machts richtig.

    Grüße,
    Stefan


Anmelden zum Antworten