[solved]Warum können statische Elementfunktionen nicht konstant sein?
-
Warum können statische Elementfunktionen nicht konstant sein?
-
Was würdest du von einer solchen Funktion erwarten?
-
Weil das alles keinen Sinn ergeben würde.
Eine Funktion deklariert man ja nur als const damit die keine member verändern darf.
Eine statische Funktion bezieht sich ja aber nicht auf ein Objekt einer Klasse und kennt somit keine Member.
-
Weil eine statische Elementfunktion kein Teil eines Objektes ist.
Und das konstant bezieht sich ja auf das Objekt, es verspricht quasi, dass die Elementfunktion das Objekt von dem sie eine Elementfunktion ist, nicht zu ändern.Aber mal ne andere Frage, das hier kennst du schon oder:
Da findet man das in einer Minute, gleich der 2. Link.
Lg freeG
-
Na konstante Elementfunktionen mache ich doch konstant wenn darin kein Element verändert werden soll. Nun habe ich eine statische Funktion die ein statischen Wert zurückgibt und ich will auch sichergehen das diese Funktion nicht den statischen Wert verändert. Also es soll genau denselben Grund dienen wie bei den üblichen Funktionen.
-
Das
constbei den nicht statischen Methoden macht man eigentlich, damit man sie auch für konstante Instanzen aufrufen kann und weniger, um Programmierfehlern vorzubeugen (wäre auch unlogisch).
Es gibt aber keine konstanten Klassen, also ergeben konstante statische Funktionen in diesem Kontext keinen Sinn.
-
Dann mach den Rückgabetypen eben konstant.
struct foo { static const int* bar (); };
-
ipsec schrieb:
Das
constbei den nicht statischen Methoden macht man eigentlich, damit man sie auch für konstante Instanzen aufrufen kann und weniger, um Programmierfehlern vorzubeugen (wäre auch unlogisch).Ach?
Du vielleicht
Ich finde es *sehr* praktisch dass mir der Compiler gleich nen Error um die Ohren schmeisst wenn ich versuche in einer const-Funktion was zu ändern.Ist vor allem auch sehr praktisch wenn man fremden Code liest, bzw. halt einfach durchkramt um ihn zu verstehen. Implizite Doku FTW!
-
ipsec schrieb:
Das
constbei den nicht statischen Methoden macht man eigentlich, damit man sie auch für konstante Instanzen aufrufen kann und weniger, um Programmierfehlern vorzubeugen (wäre auch unlogisch).
Es gibt aber keine konstanten Klassen, also ergeben konstante statische Funktionen in diesem Kontext keinen Sinn.Das ist laut meinem Buch(Stroustrup) nicht unlogisch, sondern sogar ein Hauptgrund für konstante Elementfunktionen, diese sollen verhindern das sich Datenelemente verändern. Mache ich dies warnt mich der Compiler.
Irgendwie ist mir immer noch nicht klar warum ich diesen Schutz nicht auch bei statischen Elementfunktionen, die statische Datenelemente verändern könnten, nutzen kann(ohne Tricks)?
-
Hallo cppfrager,
class Test { public: static void DoStaticTest() { _val = 0; } private: int _val; };kompiliert ja eh nicht. Wozu willst du DoStaticTest jetzt auch noch const machen?
Das hier hingegen
class Test { public: static void DoStaticTest() { _sVal = 0; } private: static int _sVal; };kompiliert.
Meinst du diesen Fall, dass du hier DoStaticTest gerne const machen würdest, damit es _sVal nicht verändern kann?
Falls ja: Soweit ich weiss, sieht der Standard das nicht vor.
Statische Memberfunktionen und Membervariablen kannst du dir eigentlich eher wie globale Funktionen und Variablen vorstellen, die nur einfach innerhalb des namespace der Klasse liegen.Aus
int val; void DoGlobalTest() { val = 0; }(also global) kannst du ja auch nicht
int val; void DoGlobalTest() const { val = 0; }machen, weil man Modifizierer nur an Memberfunktionen hängen kann.
Deine Idee an sich finde ich aber gar nicht so uninterresant.

-
Dankeschön für die Erklärung. Ja, ich meinte den zweiten Fall wo eine statische Elementfunktion ein statisches Datenelement nicht ändern dürfen soll(was fürn deutsch
) So dass mir der Compiler eine schöne Fehlermeldung liefert.Dann ist also die Datenkapselung bei statischen Elemente nicht wirklich vorhanden sondern nur hinter dem Klassennamen versteckt worden?
Wenn ich zuviel nerve einfach sagen ich fange erst an C++ zu lernen.
-
hustbaer schrieb:
ipsec schrieb:
Das
constbei den nicht statischen Methoden macht man eigentlich, damit man sie auch für konstante Instanzen aufrufen kann und weniger, um Programmierfehlern vorzubeugen (wäre auch unlogisch).Ach?
Du vielleicht
Ich finde es *sehr* praktisch dass mir der Compiler gleich nen Error um die Ohren schmeisst wenn ich versuche in einer const-Funktion was zu ändern.Sicher ist das praktisch, davor sollte man sich aber erstmal die Frage stellen, warum man denn keine Member ändern darf.
Simples Beispiel:struct S { private: int x; public: void foo() const { // tue was mit x, x kann nicht verändert werden, sonst Error } }Welche Aussage hat jetzt das
const? Dasxin der Funktion nicht verändert wird. Das hilft mir aber erstmal nicht viel, denn jede andere Funktion könntexverändern. Wennxirgendwann falsche Werte hat, hilft mir die Information "barkannxändern,foonicht" eventuell bei der Fehlersuche, nicht aber bei der Fehlervermeidung. Sollte ichxvor Veränderungen schützen wollen, muss ich das konstant machen und nicht die Memberfunktionen.
Die implizierte Aussage vonconstist, dass das Objekt nach dem Aufruf vonfooden gleichen Zustand hat wie vorher. Das interessiert mich aber nur, wenn ich es vor Veränderungen schützen will, also wenn das Objekt selbstconstist.
Also dient dasconstnur als Indikator, dass die Funktion den Objektzustand nicht ändert und deswegen auf konstante Instanzen angewendet werden kann. Und folgerichtig darf die Funktion deswegen auch keine Member ändern, womit die ursprüngliche Frage geklärt wäre.Beim Übertragen der Thematik auf Klassen stellen wir aber fest, dass es keine konstanten Klasseninstanzen gibt, dass man eine Klasse also nicht daran hindern kann, ihren Zustand zu ändern. Sie hat nämlich gar keinen. Also ist
constbei statischen Funktionen sinnlos, da es (besonders für den User) keine relevanten Informationen bringt.
-
cppfrager schrieb:
Dann ist also die Datenkapselung bei statischen Elemente nicht wirklich vorhanden sondern nur hinter dem Klassennamen versteckt worden?
Vom Gebrauch her hab ich zumindest bisher nichts gegenteiliges bemerkt, was aber nicht bedeutet, dass es nicht möglich ist, dass ich irgendetwas heftig übersehe.

cppfrager schrieb:
Wenn ich zuviel nerve einfach sagen ich fange erst an C++ zu lernen.
Dafür ist das Forum doch da, und deine Fragen sind ja auch nicht sinnlos (auch wenn ich deine Eingangsfrage zwei mal lesen musste, um zu verstehen, dass sie nicht sinnlos ist, weil ich erst dachte, dass es um statische Memberfunktionen aber dabei um nicht-statische Membervariablen ginge. ;)).
Also, Frage an die, die es genau wissen:
Ist// 1 class foo { public: static int val; static void bar() { val = 0; } };das gleiche wie
// 2namespace foo { int val; void bar() { val = 0; } }?
Edit: Hatte hier ( http://groups.google.de/group/comp.lang.c++.moderated/browse_thread/thread/f1a02a916a3f0ea5# ) mal nachgefragt, und bin jetzt schlauer.

@cppfrager: Ich bezweifel, dass es eine Möglichkeit gibt, um sicherzustellen, dass eine globale Funktion keine Variablen ändert. Der Typmodifizierer const ist ja dafür gedacht, festzulegen, dass eine Memberfunktion das instanzierte Objekt, zu dem sie aufgerufen wird, nicht verändert, wobei man hier natürlich aufpassen muss, weil der Compiler nur auf "bitwise const correctness" überprüfen kann, nicht aber auf "logical const correctness"
-
cppfrager schrieb:
Irgendwie ist mir immer noch nicht klar warum ich diesen Schutz nicht auch bei statischen Elementfunktionen, die statische Datenelemente verändern könnten, nutzen kann(ohne Tricks)?
Weil dieser Schutz nicht zur Compilezeit erfolgen kann.
Klar, der einfache Fall ist kein Problem: Ändernde Zugriffe auf statische Member innerhalb so einer static-const-Methode ließen sich unterdrücken. Aber es ist ja nicht immer so einfach.
Die statische Methode könnte irgendeine Funktion aufrufen, die über beliebig komplizierte Aufrufverschachtelungen dann doch irgendwie statische Member ändert. Oder eine Instanz der Klasse erzeugt, und darüber etwas ändert. Du müsstest also die Information "class-const" über die gesamte Aufrufhierarchie mitgeben, und das nicht nur für diese eine, sondern potenziell für jede Klasse gleichzeitig. Und da du wegen Polymorphie, Funktionszeigern usw. diese Prüfung nicht zur Compilezeit machen kannst, müsstest du diesen Daten- und Performanceballast zur Laufzeit mitschleppen.
-
Das macht Sinn, ich denke damit ist das Thema gegessen. Danke nochmal an alle.
-
@MFK: Die hypothetische statische konstante Memberfunktion (bzw. die konstante globale Funktion) dürfte natürlich nur andere konstante Funktionen aufrufen. Das ist bei nicht-statischen konstansten Memberfunktionen doch genauso, oder seh ich das falsch?
Falls nicht, wär das durchaus vom Compiler umsetzbar und kein anderes Problem als bei den bisherigen Typmodifizierern. Die Frage ist eher, was würde es bringen?
Wenn ich eine konstante Funktion (statisch member oder nicht, ganz egal) aufrufe, worauf würde sich das "konstant" beziehen? Eigentlich darauf, dass sich nichts in meinem kompletten Programm verändert. Ich vermute mal, dass es sowas einfach nicht gibt, weil es ziemlich nutzlos wäre.
-
Dobi schrieb:
@MFK: Die hypothetische statische konstante Memberfunktion (bzw. die konstante globale Funktion) dürfte natürlich nur andere konstante Funktionen aufrufen. Das ist bei nicht-statischen konstansten Memberfunktionen doch genauso, oder seh ich das falsch?
Du kannst aus konstanten Memberfunktionen nicht nur andere konstante Funktionen aufrufen, sondern auch freie Funktionen.
Wenn du aus der freien Funktion auf die const-geschütze Instanz zugreifen willst, musst du eine Referenz oder einen Zeiger übergeben.
Du hast also überall, wo der Schutz erforderlich ist, ein Ding, das die const-Information sowieso in sich trägt.Bei statischen Methoden hast du das nicht. Kein Instanzzeiger, keine const-Information.
-
ipsec schrieb:
...Das
constbei den nicht statischen Methoden macht man eigentlich, damit man sie auch für konstante Instanzen aufrufen kann und weniger, um Programmierfehlern vorzubeugen (wäre auch unlogisch)...Ich kenne eigentlich ausschließlich den letzten Grund. Den ansonsten könnte man sich das const gleich im gesamten Programm schenken (Dann hast du auch nicht das Problem mit konstanten Instanzen).
ipsec schrieb:
...Sicher ist das praktisch, davor sollte man sich aber erstmal die Frage stellen, warum man denn keine Member ändern darf...
Die Frage ist falsch. const zeigt sofort auf einen Blick das die Funktion sicherstellt wird das keine Werte geändert werden. Das hat nichts mit der Frage zu tun, warum sie keine Member ändern sollte. Es ist eine Absicherung an den Aufrufenden, und kann einige Fehlerquellen verhindern.
ipsec schrieb:
...Welche Aussage hat jetzt das
const? Dasxin der Funktion nicht verändert wird. Das hilft mir aber erstmal nicht viel, denn jede andere Funktion könntexverändern...Sicher, aber man sieht es ja, am fehlenden const. Zudem kannst du aus einer konstanten Funktion keine nicht-konstanten Funktionen der Instanz aufrufen. Daher hat das eine mit dem anderen nichts zu tun.
ipsec schrieb:
...Die implizierte Aussage von
constist, dass das Objekt nach dem Aufruf vonfooden gleichen Zustand hat wie vorher. Das interessiert mich aber nur, wenn ich es vor Veränderungen schützen will, also wenn das Objekt selbstconstist...Für dich ist es vielleicht nicht interessant, für viele andere aber schon. Es ist einfach eine Zusicherung, die Fehler vermeiden kann, und Unsicherheiten nimmt.
-
@MFK: Ah, ok. Danke.
