Wie weit geht const-correctness?
-
Hallo hallo,
ich habe begonnen eine kleine private Bibliothek zu schreiben und bin momentan bei Netzwerk-Sockets. Schon des öfteren habe ich mich gefragt, wie radikal ich/man const-correctness (bei Methoden) durchziehen sollte.
Folgendes Beispiel:
Man glaubt es kaum - meiner Socket-Klasse liegt ein privater int m_fd zugrunde
Für Sockets gibt es die wertvolle Möglichkeit mittels recv und MSG_PEEK ankommende Daten zwar zu lesen, jedoch nicht aus der Warteschlange zu entfernen.
Also habe ich mir eine praktische Methode peek geschrieben:int Socket::recv(void* buf,int len,int flags) { return ::recv(m_fd,buf,len,flags); } int Socket::peek(void* buf,int len) const { return recv(buf,len,MSG_PEEK); }Der Compiler mag diese leider nicht, weil Socket::recv nicht const ist. Socket::recv habe ich instinktiv nicht als const deklariert, da ich ja weiß, dass zwar keine Membervariablen verändert, jedoch der eingehende Datenstrom verkürzt wird.
Vielleicht ist meine Frage nun schon klar geworden. Wenn nicht - jetzt genau:
Sollte man const-correctness immer beinhart auf die Veränderung von Membervariablen beziehen (also Socket::recv als const deklarieren) oder ist die im Beispiel genannte Semantik ebenfalls zu beachten?Ich hoffe meine Frage ist klar geworden und Ihr habt einen guten Rat für mich

Danke und herzliche Grüße,
Max
-
Ich würde es so lassen und peek halt ::recv aufrufen lassen. Wie du schon richtig gemerkt hast, verändert ::recv() ohne MSG_PEEK halt den Zustand des Objekts, unabhängig davon, ob jetzt Membervariablen verändert werden oder nicht.
-
MaDsTyLe schrieb:
Sollte man const-correctness immer beinhart auf die Veränderung von Membervariablen beziehen (also Socket::recv als const deklarieren) oder ist die im Beispiel genannte Semantik ebenfalls zu beachten?
sehr schöne Frage! ganz klar auf die semantik fokussieren, inwieweit membervariablen betroffen sind, ist nur ein implementierungsdetail

-
Normalerweise implementiert man das "logischer const".
@Klara Fall: Magst du Kinderbücher? Meine Schwester hat dieses Buch

-
Sicher dass der Compiler sich beschwert? Der Socket-Aufruf nimmt den Deskriptor doch per Value, also eigentlich keine Änderung am Objekt die für den Compiler erkenntlich wäre.
-
Ethon schrieb:
Sicher dass der Compiler sich beschwert? Der Socket-Aufruf nimmt den Deskriptor doch per Value, also eigentlich keine Änderung am Objekt die für den Compiler erkenntlich wäre.
recv ist nicht const, deswegen beschwert sich der Compiler. Du kannst aus einer const Methode keine non-const Methode aufrufen.
-
Sollte man vielleicht
Socket::recv constmachen?
-
evilissimo schrieb:
Ethon schrieb:
Sicher dass der Compiler sich beschwert? Der Socket-Aufruf nimmt den Deskriptor doch per Value, also eigentlich keine Änderung am Objekt die für den Compiler erkenntlich wäre.
recv ist nicht const, deswegen beschwert sich der Compiler. Du kannst aus einer const Methode keine non-const Methode aufrufen.
Wenn das Objekt dabei nicht geändert wird schon? Sonst könnte man da ja sowieso nur Memerfunktionen aufrufen, da freie Funktionen ja nicht const sein können.
Unter anderem würde doch zb die ganze C-Library unter den Tisch fallen und ich könnte schwören, teile aus cmath in konstanten Gettern verwendet zu haben.
-
Ethon schrieb:
evilissimo schrieb:
recv ist nicht const, deswegen beschwert sich der Compiler. Du kannst aus einer const Methode keine non-const Methode aufrufen.
Wenn das Objekt dabei nicht geändert wird schon? Sonst könnte man da ja sowieso nur Memerfunktionen aufrufen, da freie Funktionen ja nicht const sein können.
Unter anderem würde doch zb die ganze C-Library unter den Tisch fallen und ich könnte schwören, teile aus cmath in konstanten Gettern verwendet zu haben.
Genauer: Du kannst aus einer const Methode keine non-const Methode der gleichen Klasse aufrufen.
Noch genauer: Wenn this const ist, kannst Du keine non-const Methode auf this aufrufen.
Wenn Du in einer const-Methode ein beliebiges anderes non-const Objekt hast, kannst Du auf diesem Objekt natürlich auch non-const Methoden aufrufen. Und da freie und statische Funktionen garkeinem Objekt zugeordnet sind, kannst Du diese selbstverständlich auch aufrufen.
-
Klara Fall schrieb:
sehr schöne Frage! ganz klar auf die semantik fokussieren, inwieweit membervariablen betroffen sind, ist nur ein implementierungsdetail

Ganz genau.
Und um dem Compiler beizubringen, was in einer const Methode verändert werde darf gibt esmutable.
-
Ah lol, ich check jetzt erst, dass er in peek ja nicht das freie recv sondern die Memberfunktion aufruft.
Habt mich gerade echt verwirrt.^^
-
Ganz genau

Hätte ich in peek auch ::recv verwendet, wäre das Beispiel nicht ganz so schön geworden

Ich freue mich, dass mich mein Instinkt auch schon immer zur Beurteilung der Semantik getrieben hat

Habt vielen Dank!
Herzliche Grüße,
Max