Wann benutzt man die "this"-Referenz
-
void MachWas(int blub) { this->blub = blub; }In diesem Fall ist this nötig, da blub jetzt nur noch den Parameter bezeichnet, nicht mehr die Membervariable. Aber man sollte da ohnehin unterschiedliche Bezeichner wählen.
Den this-Zeiger braucht man eher bei der Übergabe an Funktionen, die einen Zeiger benötigen.
-
Genau deshalb bekommen meine Member immer ein
m_spendiert. Dann kann man so schöne Sachen machen wie:class foo_t { private: int m_bar; public: const int &bar; foo_t( int bar ) : m_bar( bar ), bar( m_bar ) { } }; int main( ) { foo_t foo( 42 ); // Der user "sieht" mit IntelliSense "bar" int bar = foo.bar; // und greift auf das Attribut auch mit bar lesend zu. }greetz, Swordfish
-
stilfrage. ich verzichte meistens auf ein m_ oder einen unterstrich am ende und habe trotzdem sehr selten das bedürfnis, this zu verwenden (in dem kontext).
-
Im Zusammenhang mit templates und Vererbung gibts auch einige Ecken wo man this verwenden muss, um dem Compiler klarzumachen, dass man sich auf ein (geerbtes) member bezieht. Ich hab gerade kein beispiel zur Hand.
@swordfish: bei deinem Beispielcode gruselts mir ehrlich gesagt ein wenig. Auch wenn es nur lesend ist, gibst du durch die Referenz direkten Lesezugriff auf die innereien deiner Klasse. Wenn du bei einer späteren Revision m_bar durch eine Funktion ersetzen willst, die einen Wert berechnet, dann musst du die Referenz rausschmeißen und alle Klienten dürfen nicht nur neu kompilieren sondern auch noch sämliche Codestellen suchen und ändern die sich auf bar beziehen, weil bar dann ja nicht mehr gibt. Aus dem Grunde gibts Getter Methoden.class Foo { int bar; public: Foo(int bar) : bar(bar) {} int GetBar() { return bar; } }; int main() { Foo foo(42); int bar = foo.GetBar(); }
-
pumuckl schrieb:
Foo(int bar) : bar(bar) {}das ist im prinzip auch der grund, warum ich keine unterstriche oder m_ bei meinen membervariablen führe.
@pumuckl: so ein beispiel lässt sich leicht herbeizaubern.
template <typename T> struct Base { T t; }; template <typename T> struct Derived : Base<T> { void foo () { t = 12; //Fehler } };lass mich mal ausschlafen, dann erklär ich's auch

-
Mache ich auch nur bei ganz klar "statischen" Attributen...
greetz, Swordfish
-
"ganz klar" gibts leider bei Programmen nur dann, wenn sie nicht mehr weiterentwickelt und gewartet werden. Eine Eigenschaft von Software, die weiterentwickelt wird ist immer, dass man vorher nie weiß und planen kann, was später mal an Änderungen vonnöten ist. Ein weiteres Argument gegen Referenzen im public Interface ist, dass man als Klient gewohnt ist, auf Klassenattribute nur mittels Funktionen zuzugreifen. Wenn man dann plötzlich auf eine nicht-Funktion zugreifen muss, irritiert das...
-
Wird jetzt zwar off topic, aber gut. Bastel mir doch bitte ein Szenario, bei dem ich bei einem allfälligen
human_t::get_sex( )etwas am Objekt herumbasteln muss und deshalb das Attribut nicht durchreichen kann. Gewohnheit? Ich bin es gewohnt, auf public member einer Klasse zuzugreifen. Ob das nun eine Methode oder ein Attribut ist, juckt mich ehrlichgesagt nicht.
greetz, Swordfish
-
Swordfish schrieb:
Ich bin es gewohnt, auf public member einer Klasse zuzugreifen. Ob das nun eine Methode oder ein Attribut ist, juckt mich ehrlichgesagt nicht.
Ich glaube dies würde sich ändern wenn du bereits die Nachteile kräftig ausbaden durftest die ein direkter Attributszugriff hat. Ich habe Beispielsweise ein Projekt übernehmen müssen, das dies sehr intensiv tut, und bis heute nicht die nötige Zeit gehabt es komplett davon zu befreien.
Selbst ein getter und setter das nur durchreicht ist besser als ein direkter Attributszugriff, da man später noch Änderungen (seien es zusätzliche Prüfungen, Rechtebehandlungen oder gar Mechanismen wegen Threading) machen kann ohne die Schnittstelle ändern zu müssen.
Ja, es gibt Teile einer Schnittstelle die sich nicht oder nur sehr unwahrscheinlich ändern. Aber es ist immer besser eine saubere Schnittstelle zu haben die, die Implementierung und Attribute kapselt, da man so noch ohne weiteres die Klasse in einen Adapter für eine Neuimplementierung umtauschen kann.
cu André
-
das wichtige schlagwort ist hierbei schnittstelle. sobald man innereien einer klasse offenlegt, arbeitet man gegen die implementierung einer klasse und nicht mehr gegen die schnittstelle. einmal einen public member offengelegt, schon ist die implementierung in stein gemeißelt und jede spätere änderung wird umständlich und zieht weite kreise.
dass das nicht nur ein theoretisches problem darstellt, konnte ich schon diverse male erleben.und zur eigentlichen frage: ich glaube die verwendung von this zum qualifizierten zugriff auf member ist eher in der java welt verbreitet. in der c-welt werden member eher mit einem prefix versehen. wahrscheinlich aus historischen gründen. denn ehrlich gesagt fällt mir kein grund ein, warum ein "m_" schöner, besser oder effizienter wäre, als ein "this->" vor jedem member-zugriff.
ich persönlich verwende lieber this, um zugriff zu qualifizieren. es ist ein sprachkonstrukt und schliesst so, im gegensatz zu selbst definierten prefixes, fehler schon auf compilerebene aus.
-
Jaja... ihr habt ja Recht. Ich werde mir die Gewohnheit austreiben. (Schnittstelle war der Aha-Moment
)greetz, Swordfish