Zuweisungsoperator mit const Attributen



  • ich will ja nichts zuweisen, ich habe mir schon gut überlegt wieso ich da const verwende, die Werte müssen unabänderlich sein um die Konsistenz des Programms zu gewährleisten. Eine Zuweisung von meiner Seite aus findet eigtl. nie statt. Ich hatte aus dem Fehler mehr interpretiert das die Vectoren intern einen solchen Murks machen.

    aber schon mal danke für deine Hilfe



  • Jud4s schrieb:

    ich will ja nichts zuweisen, ich habe mir schon gut überlegt wieso ich da const verwende, die Werte müssen unabänderlich sein um die Konsistenz des Programms zu gewährleisten. Eine Zuweisung von meiner Seite aus findet eigtl. nie statt. Ich hatte aus dem Fehler mehr interpretiert das die Vectoren intern einen solchen Murks machen.

    aber schon mal danke für deine Hilfe

    Wenn du nichts zuweisen willst, wofür brauchst du dann den Zuweisungsoperator?

    Edit:
    Ah, du willst die Dinger in einem vector ablegen, dazu solltest du aber wissen, wie vector intern funktioniert. Alle Container der STL arbeiten intern mit Kopien, d.h. es werden Kopien der übergebenen Objekte im Container abgelegt. Wenn diese Objekte allerdings keine Kopien zulassen kannst du sie nicht ohne weiteres in einem Container ablegen. Du könntest sie auf dem Heap erzeugen, in einen smart_ptr verpacken und in einem Container ablegen, einen pointer_container aus den boost Bibliotheken benutzen oder dir überlegen, ob du dein Design nicht anpassen solltest. Wenn du Member Variablen const deklarierst passt irgendwas mit der Kapselung nicht, wer sollte die denn manipulieren wollen?

    Edit, die Zweite:
    Mach die member private und stell entsprechende Zugriffsmethoden zur Verfügung, sowas wie

    #include <string>
    
    class DingsBums
    {
    private:
      std::string DingensKirchen_;
    public:
      const std::string& DingensKirchen() const
      {
         return DingensKirchen_;
      }
    }
    

    dann klappt auch mit dem Nachbarn vector.



  • Weil der Vector, bzw der Compiler den verlangt:

    €:Das gehörte noch zu der obigen Fehlerliste, hatte anscheinend zu früh kopiert.

    /usr/include/c++/4.4/bits/vector.tcc:312: note: synthesized method ‘Order& Order::operator=(const Order&)’ first required here
    


  • Wenn du Member Variablen const deklarierst passt irgendwas mit der Kapselung nicht, wer sollte die denn manipulieren wollen?

    Ich hatte gelesen das die Verwendung von const es dem Compiler erleichtert Einsparungen zu machen.
    Des weiteren ich bin mit der Logik dran gegangen "was nicht geändert werden darf, darf auch später nicht geändert werden", da ich aber auch keine Lust hatte unlesbaren Code zu erzeugen, wollte ich auf Getter verzichten und mit dem Objekt umspringen wie mit einem Struct, direkter Attribute Zugriff , über das deklarieren als const schien mir das dann auch ausreichend abgesichert.

    €: Welchen genaueren Sinn soll denn const sonst erfüllen, ausser zu kennzeichnen, das ein Attribut/eine Variable unabänderlich ist?



  • Jud4s schrieb:

    €: Welchen genaueren Sinn soll denn const sonst erfüllen, ausser zu kennzeichnen, das ein Attribut/eine Variable unabänderlich ist?

    Keinen. Aber du solltest nicht den Umkehrschluss ziehen und denken, alles, was sich nicht ändert, müsse const sein. Damit machst du dir in deinem Fall die Wertsemantik kaputt.

    Nochmals: Entweder du verzichtest hier auf const und kapselst deine Klasse vernünftig, oder du verzichtest auf die Speicherung als Werte in STL-Containern.

    Jud4s schrieb:

    Ich hatte gelesen das die Verwendung von const es dem Compiler erleichtert Einsparungen zu machen.

    Vergiss das am besten. Wenn du const auf diese Weise verwendest, musst du dich über Fehler nicht wundern.



  • Danke, ich denke ich werde meine Datenkapselung einfach erneut überdenken müssen.



  • Zwar nicht ganz zum Thema passend, aber zur Frage "Wie implementiere ich den operator = korrekt":

    T& operator = (T other)
    {
        swap(other);
        return *this;
    }
    

    .) Exception-save
    .) Kann sowohl kopieren, als auch moven
    .) Einfach
    .) Performant



  • Edit:
    Narf, da hab ich doch tatsächlich übersehen, dass du den Parameter per value übergibst und damit schon ´ne Kopie erstellt hast. Hab den Rest meines Beitrags mal gelöscht 😃



  • Schau nochmal genau hin. T wird hier per Value genommen und dementsprechend kopiert oder gemoved und am Ende zerstört.



  • 314159265358979 schrieb:

    Schau nochmal genau hin. T wird hier per Value genommen und dementsprechend kopiert oder gemoved und am Ende zerstört.

    Jau, grad gesehen.



  • Bei einem grossen Datentyp ohne COW kann es aber nicht mehr so performant aussehen.



  • Zeig mir einen performanteren :p


  • Mod

    314159265358979 schrieb:

    .) Performant

    Das kommt darauf an. Nämlich darauf, ob nicht eventuell bereits verwendete Resourcen wiederverwendet werden können und somit evtl. etwas gespart werden kann.

    Betrachte z.B.

    vector<int> a(1000,0),b(100,0);
    a = b;
    

    Es ist mir nicht ganz klar, ob vector hier copy&swap durchführen darf (mit entsprechenden Folgen für capacity), jedenfalls wird es nicht vorgeschrieben und wäre u.U. ineffizient.
    copy&swap ist zwar exception-safe, andererseits tritt in diesem Beispiel garantiert keine Exception auf, wenn direkt zugewiesen wird.



  • Das hängt aber davon ab, was der Copy Ctor macht.


Anmelden zum Antworten