push_back() vereinfacht



  • Guten Tag,
    da ich aus Lust und Laune eben zu einem Programm eine selbst geschriebene Verkettete Liste, die Vector ähnelt, geschrieben hab, ist mir wieder was eingefallen zu der Methode push_back. Als ich letztens mal wieder durch das Forum gegeistert bin, meine ich, habe ich einen Post von volkard, draverere oder einem anderen der Superkanidaten gesehen, indem derjenige die Methode push_back() nur mit einer Zeile gelöst hat. Mein push_back sieht jetzt so aus:

    void push_back(int value)
    {
        _knot *node = new _knot;
        node->data = value;
        node->next = anchor;
        anchor = node;
    }
    

    So sieht man sie oft, doch die andere Lösung gefällt mir besser und war auch wirklich nur eine Zeile lang. Würde mich freuen wenn ihr mir diese schreiben könntet 🙂

    mfg



  • mit einem konstruktor



  • knot() schrieb:

    mit einem konstruktor

    Kann ich mir nicht vorstellen und ich bin mir 100% sicher, dass es eine push_back() Methode war.



  • anchor = new _knot(value, anchor);
    


  • Achso, so meintest du es. _knot ist hierbei ein Struct, sicher das ich ein Konstruktor hinzufügen soll ? Structs sind ja immerhin zur Datenverwaltung finde ich.



  • Mein push_back hat auch nur eine Zeile (und das ist glaube ich auch der schönste Weg, weil 0 Code-duplizierung):
    Ich musste ma noch bissl was mit reinpacken, damit es evtl verständlicher wird...

    template <typename T>
    class list
    {
    	struct node_base //der erste und letzte knoten ist ein dummy-knoten - also braucht er auch keinen wert
    	{
    		node_base *next;
    		node_base *prev;
    
    		node_base() {}
    		node_base(node_base* _next, node_base* _prev) : next(_next), prev(_prev) {}
    	};
    
    	struct node : node_base //der normale knoten
    	{
    		T val;
    
    		node(const T& _val, node_base *_prev, node_base *_next) : val(_val), node_base(_next, _prev) {}
    	};
    
    	struct _m
    	{
    		node_base anchor_begin;
    		node_base anchor_end;
    
    		_m() : anchor_begin(&anchor_end, nullptr), anchor_end(nullptr, &anchor_begin) {}
    	};
    
    	void _insert(const T& val, node_base *before, node_base *after)
    	{
    		before->next = after->prev = new node(val, before, after);
    	}
    public:
    	void push_back(const T& to_push)
    	{
    		_insert(to_push, m.anchor_end.prev, &m.anchor_end);
    	}
    

    vll hilfts ja, obwohl es ein anderes system ist (doppelt verkettet, du hast wahrscheinlich einfach, wie es aussieht)...

    bb



  • Alles klar danke, sieht ganz gut aus, aber ich bin mir immer noch nicht sicher, ob derjenige das über einen Konstruktor gelöst hatte. Egal, so ists auch gut.
    Danke! 👍



  • unskilled schrieb:

    Mein push_back hat auch nur eine Zeile (und das ist glaube ich auch der schönste Weg, weil 0 Code-duplizierung):

    es ist auch der notwendige weg in sachen speed, um initialisiererliste im konstruktor des knotens nehmen zu können.

    ich zitiere aus 3D-Spiele-Programmierung mit DirectX | ISBN: 3980673871 Seite 198:

    Ein nicht dem Standard entsprechender Konstruktor ermöglicht uns die Initialisierung von Listen. Klassen, die mit C++ erstellt wurden, sollten diese Konstruktoren nach Möglichkeit nutzen. Der Compiler hat dadurch die Möglichkeit, wesentlich effizienteren Code zu erzeugen.



  • Das es mit Konstruktor schneller geht wollte ich ja nie bestreiten - ich meinte nur, dass push_back an sich nichts macht, außer _insert aufzurufen, was ich bei den meisten Listen-Implementationen eigtl nich so gesehen habe - allerdings ist die MSVC-Std-Lib-Liste auch so implementiert. Das war für mich dann Grund genug, es auch so zu machen ^^

    bb



  • Da fundamental types (und Zeiger) nicht default konstruiert werden, ist es potentiell egal, ob man sie über eine initialiser-list initialisiert, oder erst nachdem der ctor gelaufen ist. Soll heissen: es kann einen Unterschied machen, kann aber genausogut auch keinen Unterschied machen.



  • es ging mir hier einzig und allein ums T. da das ein schwergewicht sein kann, muß.


Anmelden zum Antworten