const hinter Funktion
-
ddd9876 schrieb:
...
Versuch mal in etwas größeren Code ( schon 20 Funktionen reichen aus ) ein viertel davon als const zu deklarieren - der Compiler macht dich fertig, ...Versuch mal, einen etwas größeren nicht-const-klaren Code (nach einem Jahr mit Wartungsmaßnahmen durch Andere) zu re-designen: Du wirst im Gestrüpp ungeklärter Abhängigkeiten wahnsinnig werden und mit Schaum vor dem Mund alles wegschmeissen, neu schreiben und (z.B. aufgrund zu eng geplanten Budgets) eine noch grottigere Version auf den Markt schmeissen.
Mal ehrlich: Wenn Dir die Invarianten klar sind, ist es auch kein Problem, sie per const zu deklarieren - und der Compiler schmeisst einem dabei auch keine Steine in den Weg.
Wenn sie dir nicht klar sind, wirst Du schlechten Code produzieren - das hat nichtmal was mit const zu tun.Gruß,
Simon2.
-
asc schrieb:
...lese ihn ...
-> "lies" ...
Ansonsten: 100%ig meine Meinung.Ich habe auch einen Kollegen, der mir "immer Du mit Deinem const-Zeug" vorwarf.
Jetzt überarbeiten wir gerade den Code eines anderen Kollegen, der es damit auch nicht so hatte (und - aus anderen Gründen - nicht mehr in der Firma ist).
Jetzt wird sein Protest deutlich leiser, wenn er auch immer noch nicht ganz überzeugt ist. Er hängt noch im "muss das eigentlich alles so kompliziert sein?" und wird auf meine Hinweise "Mit einem const hier und einem da wäre das absolut einfach" ein wenig mislaunig ....
Aber ich denke schon, dass er die Vorteile sieht.BTW: Eine der schlimmsten C-Traditionen finde ich ja, dass
char* c = "Hallo";
erlaubt ist.
Gruß,
Simon2.
-
Holla!
Gibt es eine Möglichkeit wie ich aus einer als const deklarierten Funktion den this pointer als return Wert verwenden kann? (Dadurch verändere ich ja das Objekt noch nicht?!)
Danke & Gruss
-
fred001 schrieb:
Holla!
Gibt es eine Möglichkeit wie ich aus einer als const deklarierten Funktion den this pointer als return Wert verwenden kann? (Dadurch verändere ich ja das Objekt noch nicht?!)
Danke & Gruss
Manchmal postet man doch etwas zu schnell...
const_cast<>() ist die Lösung.
Objekt* myfunction() const { *Berechne etwas* if(blabla) return const_cast<Objekt*>(this); }
Trotzdem: Ist das hässlich so?
Ich meine nicht, da die logische Idee hinter const (dass eben das Objekt nicht verändert wird) gewahrt bleibt. Meines Erachtens kommt man hier nur mit der Implementation von "const" in einen Konflikt, entsprechend würde ich dies so akzeptieren. Was meint ihr?
-
Ist das hässlich so?
Ja.
#include <iostream> class Foo { public: Foo() {} const Foo* bar() const { std::cout << "Foo::bar() const" << std::endl; return this; } Foo* bar() { std::cout << "Foo::bar()" << std::endl; return this; } }; int main() { Foo foo; Foo* f = foo.bar(); const Foo cfoo; const Foo* cf = cfoo.bar(); }
-
wx++ schrieb:
Ist das hässlich so?
Ja.
Begründung? Was willst du mit deinem Code aussagen? Der ist unnütz.
Es geht um eine Funktion, die nichts am Objekt ändert, aber keinen konstanten Pointer zurückgeben soll, da danach mit diesem gearbeitet wird.
-
fred001 schrieb:
wx++ schrieb:
Ist das hässlich so?
Ja.
Begründung? Was willst du mit deinem Code aussagen? Der ist unnütz.
Es geht um eine Funktion, die nichts am Objekt ändert, aber keinen konstanten Pointer zurückgeben soll, da danach mit diesem gearbeitet wird.
Eine
const
-Funktion gerantiert nicht nur, dass die Funktion selbst am Objekt nichts ändert, sondern auch, dass aufgrund des Aufrufs an anderer Stelle keine Änderungen erfolgen dürfen.
Deshalb darf man aus einerconst
-Funktion auch nur andereconst
-Funktionen aufrufen. Beinon-const
-Funktionen gibt es einen Fehler.
Dein Kram unterläuft diesen Mechanismus und führt im Falle eines tatsächlich alsconst
deklarierten Objekts zu undefiniertem Verhalten.wx++ macht es richtig.
-
Man sollte vielleicht noch erwähnen, dass man durch einen falschen Rückgabewert einer konstanten Funktion die Member trotzdem kompromitiert werden können. Bestes Beispiel für die falsche Verwendung ist die Rückgabe eines Zeigers auf einen Member.
-
HighLigerBiMBam schrieb:
Man sollte vielleicht noch erwähnen, dass man durch einen falschen Rückgabewert einer konstanten Funktion die Member trotzdem kompromitiert werden können. Bestes Beispiel für die falsche Verwendung ist die Rückgabe eines Zeigers auf einen Member.
Das geht auch nur mit const_cast. Man muss es also schon ziemlich mutwillig so weit treiben.
-
Soll vorkommen ^^
Compiler wirft Fehler, Fehler wird "behoben" und BOOM ^^
-
Klar, man kann auch
#define private public
machen, um "Fehler" zu beheben.
-
Das ist nicht mutwillig, sondern fahrlässig
Wenn man sicher gehen möchte, dass kein Unfug mit der Rückgabe getrieben wird hilft die Rückgabe einer Kopie.Um noch bei deinem #define private public zu bleiben. #define const ist auch top!
-
private und const sind Schl+sselwörter. Die Verwendung von Schlüsselwörter als "Makro-Namen" ist meines Wissens nach U.B.
-
U.B. ? Mein Compiler schluckt den sche.... kommentarlos.
-
krümelkacker schrieb:
private und const sind Schl+sselwörter. Die Verwendung von Schlüsselwörter als "Makro-Namen" ist meines Wissens nach U.B.
Der Beitrag war nicht so wirklich ernst gemeint und bezog sich auf das Wegcasten von
const
.
-
> Der Beitrag war nicht so wirklich ernst gemeint
War schon klar.
> U.B. ? Mein Compiler schluckt den sche.... kommentarlos.
Ich sehe hier keinen Widerspruch.
-
Ein blödes const-Problem, das ich in letzter Zeit hatte, war folgendes: In einer Library gab es einige typedefs:
typedef __mpfr_struct mpfr_t[1]; typedef __mpfr_struct *mpfr_ptr;
Nun hatte ich in meiner Klasse folgendes
class Number { mpfr_t mpfr_number; public: //.... mpfr_ptr get_mpfr_number() //es muss ein Pointer zurückgegeben werden, da ein Array nicht zurückgegeben werden darf { return mpfr_number; } const mpfr_ptr get_mpfr_number() const //Compiler meckert: warning: type qualifiers ignored on function return type { return const_cast<const mpfr_ptr>(mpfr_number); //ohne gings nicht } }
Was war das Problem? const mpfr_ptr ist ein konstanter Pointer, der auf variablen Inhalt zeigt. Ich brauche aber einen variablen Pointer, der auf konstanten Inhalt zeigt. Das geht AFAIK nur mit const __mpfr_struct *, da __mpfr_struct * const, const mpfr_ptr sowie mpfr_ptr const alles konstante Pointer sind. Wer garantiert mir jetzt, dass der struct-Name nicht in der nächsten Version der Library geändert wird? In der Dokumentation wurden, soweit ersichtlich, nur die typedef-Namen gebraucht.
-
Du gibst einen konstanten Zeiger zurück. Du willst aber einen Zeiger auf ein konstantes Objekt zurückgaben:
typedef __mpfr_struct *mpfr_ptr; typedef __mpfr_struct const * const_mpfr_ptr; const_mpfr_ptr get_mpfr_number() const
-
Tachyon schrieb:
Du gibst einen konstanten Zeiger zurück. Du willst aber einen Zeiger auf ein konstantes Objekt zurückgaben:
typedef __mpfr_struct *mpfr_ptr; typedef __mpfr_struct const * const_mpfr_ptr; const_mpfr_ptr get_mpfr_number() const
Das habe ich doch schon gesagt. Ich war mir bloß unsicher, ob von der Library garantiert wird, dass sich der Name von __mpfr_struct nicht ändert.
-
wxSkip schrieb:
[...]Das habe ich doch schon gesagt. Ich war mir bloß unsicher, ob von der Library garantiert wird, dass sich der Name von __mpfr_struct nicht ändert.
Ich habe nicht zu ende gelesen, sorry. Selbst wenn sich der Name der Struktur ändern sollte: Der Änderungsaufwand würde sich ja nur auf den
typedef
beschränken. So schlimm sollte das also eigentlich nicht sein.