Referenzen von Objecten auf dem Stack



  • Ich habe eine Klasse Manager, die im wesentlichen das Elelement data von Typ priority_queue<Entry, vector<Entry>, CompareEntry> enthält. Entry ist eine recht einfach Klasse, die 2 Eigenschaften hat.
    Ich will nun eine Methode in der Manager Klasse, die die beiden Eigenschaften von Entry als parameter nimmt und das Entry-object erstellt.
    Dieses soll nun in die priority_queue. Die hat eine push Methode, die nur eine Referenz annimmt.
    Aber das von mir erstellte Entry-object (da auf dem Stack abgelegt) direkt wieder gelöscht.
    Wie kann ich es also auf dem heap ablegen und auch wieder löschen, da ich den Speicher einer referenz ja nicht löschen kann?

    Vielen Dank schon mal


  • Mod

    Ist das nicht die priority_queue aus der Standardbibliothek? Macht die Queue denn keine Kopie? Das klingt merkwürdig. Ansonsten hat sie vielleicht auch eine emplace-Methode.



  • Also das ist die Dokumentation von push: http://en.cppreference.com/w/cpp/container/priority_queue/push

    und das die der queue: http://en.cppreference.com/w/cpp/container/priority_queue

    Gut das mit der Kopie wäre natürlich sinnvoll, und würde mein problem lösen. Kann ich das rausfinden?
    Und dann noch eine Frage: Was soll (T&& value) als parameter heißen?



  • Wie du ja auf der von dir verlinkten Seite siehst gibt es zwei Versionen von der push Funktion. Eine hat als Parameter eine konstante Referenz und eine mit R-Value Reference (das mit den zwei &&). Die konstante Referenz dient nur dazu um ein Objekt effizient an die Funktion zu übergeben. Intern wird dann aber eine Kopie in der priority_queue gespeichert. Und die Variante mit R-Value Reference nutzt ein move um das Objekt hinzuzufügen. Näheres dazu gibts bei google unter dem Stichwort "move semantics". Ist für deine Klasse aber wohl egal oder was sind deine zwei Eigenschaften?



  • Die Klasse hat nur eine integer eigenschaft (timestamp) und einen string (bash-Befehl).

    ok danke das hat mir sehr geholfen 🙂

    Bin noch nicht so erfahren in C++, kann ich bei einer konstanten referenz immer davon ausgehen, dass es egal ist, was mit dem Object später passiert, oder wenn nicht, wie genau ist das dann dokumentiert?
    Und wie wird das Object kopiert? Muss ich eine kopier-oberation definieren, (bei dem Object wahrscheinlich nicht, aber wenn es komplexer wird?).



  • Hab mich jetzt in die RValues eingelesen.
    So ein RValue wird dann ja auch dem Stack erstellt, oder?
    Bei einem move statement wird das Object dann einfach in den Heap verschoben?



  • Bengo schrieb:

    kann ich bei einer konstanten referenz immer davon ausgehen, dass es egal ist, was mit dem Object später passiert, oder wenn nicht, wie genau ist das dann dokumentiert?

    Um festzustellen was genau in der Funktion mit der Referenz passiert, muss man wohl in die Dokumentation gucken. Es könnte auch sein, dass die Referenz gespeichert wird (beim Konstruktor) oder ein Pointer auf das Objekt gespeichert wird. Bei den ganzen Standardcontainern wird aber grundsätzlich das gespeichert was man als Template Parameter angibt. Also ein std::vector<int> speichert ints und keine Referenzen auf ints.

    Bengo schrieb:

    Und wie wird das Object kopiert? Muss ich eine kopier-oberation definieren, (bei dem Object wahrscheinlich nicht, aber wenn es komplexer wird?).

    Wenn du selbst keinen Copy Constructor und Copy Assignment Operator definierst wird dieser meist automatisch erstellt. Dabei wird dann jedes Element separat kopiert falls dies möglich ist, sonst gibts eben keine automatisch generierten Funktionen. Meistens ist man auch gut damit beraten die automatisch generierten Funktionen zu belassen.

    Bengo schrieb:

    Hab mich jetzt in die RValues eingelesen.
    So ein RValue wird dann ja auch dem Stack erstellt, oder?
    Bei einem move statement wird das Object dann einfach in den Heap verschoben?

    RValues haben erstmal nichts mit Stack und Heap zu tun. Moves sind sinnvoll für Datentypen auf andere Speicherbereiche verweisen. Zum Beispiel die std::string Klasse, welche die Größe des Strings und einen Pointer auf den Buffer mit dem String speichert. Würde man einen solchen String kopieren wollen, dann muss man den möglicherweise sehr großen Buffer kopieren. Bei einem Move dagegen reicht es den Pointer und die Größe auf ein anderes Objekt zu übertragen. Das Quellobjekt wird dann natürlich ungültig.

    Bengo schrieb:

    Die Klasse hat nur eine integer eigenschaft (timestamp) und einen string (bash-Befehl).

    Aufgrund des Strings könnte dir ein Move etwas bringen aber wenn du nicht die absolut schnellste Variante brauchst würde ich dir das als Anfänger nicht empfehlen, weil man viel falsch machen kann.



  • Noch eine letzte Frage.
    Kopiert mir der = Operator das Object vollständig, sodass beide Objecte vollständig unabhängig sind.

    Kann ich also einfach kopie = original; machen?



  • Naja was heißt vollständig unabhängig? Wenn dein Objekt Pointer enthält dann wird nur der Pointer kopiert und nicht die Daten wohin es zeigt. Beide Objekte haben dann also einen Pointer auf den gleichen Speicher und das ist meistens nicht das was man möchte. Das wäre dann normal ein Fall dafür die Kopieroperationen selbst zu definieren, aber besser und einfacher ist es auf einen der STL Container auszuweichen, sodass man keine Pointer in seinen Objekten hat.



  • sebi707 schrieb:

    Das wäre dann normal ein Fall dafür die Kopieroperationen selbst zu definieren, aber besser und einfacher ist es auf einen der STL Container auszuweichen, sodass man keine Pointer in seinen Objekten hat.

    Nur nochmal für Bengo damit er diesen Abschnitt von dir nicht falsch versteht Sebi.

    Auch STL Container haben intern natürlich Pointer aber dort wurde der Kopierkonstruktor schon von den Autoren der STL definiert.



  • Da die queue ja auf den STL Container aufbaut, kann ich das in dem Fall einfach machen. = Operator ist ja auch in der Doku beschrieben, es steht aber nicht so genau da, ob die Pointer einfach kopiert werden.



  • Also bei cppreference steht doch: Replaces the contents with a copy of the contents of other.
    Daraus sollte eigentlich klar werden das man eine Kopie der enthaltenen Daten kriegt. Eigentlich verhalten sich die STL Container schon so wie man es erwartet.


Log in to reply