Dieses Makro kann in einem globalen Header oder besser als Compiler-Befehlszeilenparameter definiert werden:
#define me (*this)
Und ein Anwendungsbeispiel:
some_header.h:
inline void Update()
{
/* ... */
}
main.cpp:
#include "some_header.h"
class A {
public:
void SetX(int x)
{
me.x = x;
me.Update();
}
void SomeOtherFunction()
{
::Update();
}
/*
100 or more lines
...
*/
void Update()
{
// ...
}
int x;
};
In einer Klassenmethode verwende ich beim Zugriff auf ein Klassenmitglied immer me
und beim Zugriff auf einen globalen Bezeichner immer ::
. Dies gibt dem Leser, der mit dem Code nicht vertraut ist (wahrscheinlich ich selbst nach ein paar Monaten), lokalisierte Informationen darüber, worauf zugegriffen wird, ohne dass er irgendwo anders suchen muss. Ich möchte definieren, me
weil ich die Verwendung this->
überall zu laut und hässlich finde . Aber kann #define me (*this)
eine gute C ++ - Praxis betrachtet werden? Gibt es einige praktische Probleme mit dem me
Makro? Und wenn Sie als C ++ - Programmierer der Leser von Code sein werden, der das me
Makro verwendet, würden Sie es mögen oder nicht?
Edit: Weil viele Leute nicht spezifisch dagegen argumentieren me
, sondern generell dagegen explizit. Ich denke, es ist möglicherweise nicht klar, welche Vorteile es hat, "dies überall zu verdeutlichen".
Was sind die Vorteile von "explizit dies überall"?
- Als Leser des Codes haben Sie die Gewissheit, auf was zugegriffen wird, und können sich auf andere Dinge konzentrieren, als zu überprüfen, ob in einem entfernten Code wirklich auf das zugegriffen wird, worauf Ihrer Meinung nach zugegriffen wird.
- Sie können die Suchfunktion genauer verwenden. Suche "
this->x
" kann mehr gewünschte Ergebnisse liefern als nur Suche "x
" - Wenn Sie ein Mitglied löschen oder umbenennen, benachrichtigt Sie der Compiler zuverlässig an den Stellen, an denen dieses Mitglied verwendet wird. (Einige globale Funktionen können denselben Namen haben und es besteht die Möglichkeit, dass Sie einen Fehler einführen, wenn Sie dies nicht explizit verwenden.)
- Wenn Sie Code umgestalten und die Nicht-Member-Funktion von Member explizit machen (um eine bessere Kapselung zu erreichen), wird angezeigt, welche Stelle Sie bearbeiten müssen, und Sie können dies einfach durch einen Zeiger auf eine Instanz der Klasse ersetzen, die als Nicht-Member-Funktionsparameter angegeben ist
- Im Allgemeinen gibt es beim Ändern von Code mehr Möglichkeiten für Fehler, wenn Sie dies nicht explizit verwenden, als wenn Sie dies überall explizit verwenden.
- Explizit ist dies weniger laut als explizit „m_“, wenn Sie ein Mitglied von außerhalb (
object.member
vsobject.m_member
) ansprechen (danke an @Kaz, um diesen Punkt zu erkennen) - Explizit löst dies das Problem universell für alle Mitglieder - Attribute und Methoden, wohingegen „m_“ oder ein anderes Präfix praktisch nur für Attribute verwendbar ist.
Ich würde diese Liste gerne polieren und erweitern, sagen Sie mir, ob Sie über andere Vorteile Bescheid wissen, und verwenden Sie Anwendungsfälle, um dies überall explizit zu verdeutlichen .
#define self (*this)
? Sie können sogar beide Makros mischen und einige Dateien VB und andere Python imitieren lassen. :)#include "vb.h"
,#Include pascal.h
, oder#include FOTRAN.h
und haben die nächste Person , um Ihren Code zu berühren einreichen TDWTF .me_x
.Antworten:
Nein ist es nicht.
Achten Sie auf den Programmierer, der Ihren Code in einigen Jahren, lange nachdem Sie sich auf grünere Weiden begeben haben, pflegt, und befolgen Sie die üblichen Konventionen der von Ihnen verwendeten Sprache. In C ++ müssen Sie fast nie schreiben
this
, da die Klasse in der Symbolauflösungsreihenfolge enthaltenthis->
ist und impliziert wird, wenn ein Symbol im Klassenbereich gefunden wird. Also schreibe es einfach nicht so wie alle anderen.Wenn Sie oft verwirrt sind, welche Symbole aus dem Klassenbereich stammen, verwenden Sie für gewöhnlich ein gemeinsames Benennungsmuster für Mitglieder (Felder und manchmal private Methoden; ich habe nicht gesehen, dass es für öffentliche Methoden verwendet wird). Häufig werden Suffixe mit
_
oder Präfixe mitm_
oder verwendetm
.quelle
this
um explizit zu verdeutlichen, dass die Variable für die Methode nicht lokal ist. Die Frage ist hier, ob das Makro vorhanden seinme
sollte, nicht, obthis
etwas verwendet werden sollte.me.
anstelle von verwendetthis->
. Da dies nicht erforderlichthis->
ist, istme.
das Makro nicht erforderlich und daher auch nicht erforderlich.this->
"notwendig" ist. Tatsächlich sagt das OP, dass er verwendet,this->
obwohl es nicht notwendig ist. Die Frage ist, ob stattdessenme.
verwendet werden sollthis->
, was diese Antwort eigentlich nicht beantwortet.this
und daher eine Diskussion über diesen Punkt erforderlich ist, um eine vollständig ausgewogene Schlussfolgerung zu erzielen.Sie möchten also eine neue Sprache erstellen. Dann tun Sie dies und lähmen Sie C ++ nicht.
Es gibt verschiedene Gründe, dies nicht zu tun:
this
ist, und durch Hinzufügen eines solchen Makros fügen Sie tatsächlich ein neues Schlüsselwort hinzu. Was ist, wenn jeder etwas vorstellt, das ihm gefällt? Wie würde Code aussehen?(*this).
oder gar nicht verwendenthis->
, außer in einigen besonderen Fällen (siehe diese Antwort und suche nach "this->")Ihr Code unterscheidet sich nicht von dem
#define R return
, den ich im eigentlichen Code gesehen habe. Grund? Weniger tippen!Ich gehe ein wenig vom Thema ab, aber hier werde ich auf Punkt 3 eingehen (nicht verwenden
(*this).
oderthis->
in einer Klasse).Zuallererst
(*this).
oderthis->
werden verwendet, um auf Mitgliedsvariablen oder Funktionen des Objekts zuzugreifen. Es zu benutzen ist bedeutungslos und bedeutet mehr Tippen. Außerdem ist das Lesen eines solchen Codes schwieriger, da mehr Text vorhanden ist. Das bedeutet eine härtere Wartung.Was sind die Fälle, in denen Sie verwenden müssen
this->
?(a) Unglückliche Auswahl des Namens des Arguments.
In diesem Beispiel
this->
ist erforderlich, da das Argument denselben Namen wie die Mitgliedsvariable hat:(b) Beim Umgang mit Vorlagen und Vererbung (siehe dies )
Dieses Beispiel kann nicht kompiliert werden, da der Compiler nicht weiß, auf welche Variable
v
zugegriffen werden soll.quelle
*this.
undthis->
this->
ist so nützlich wieauto
in Pre-C ++ 11. Mit anderen Worten, es erhöht nur das Code-Rauschen.Ich schlage vor, dies nicht zu tun. Dies gibt einem Leser, der mit Ihrem Makro nicht vertraut ist, einen großen " WTF ", wenn er dies sieht. Code wird nicht besser lesbar, wenn "neue Konventionen" über die allgemein akzeptierten hinaus erfunden werden, ohne dass dies wirklich erforderlich ist.
Das mag Ihnen so erscheinen, vielleicht weil Sie viel in Sprachen mit dem Schlüsselwort programmiert haben
me
(Visual Basic, nehme ich an?). Tatsächlich ist es aber nur eine Frage der Gewöhnung - esthis->
ist ziemlich kurz, und ich denke, die meisten erfahrenen C ++ - Programmierer werden Ihrer Meinung nicht zustimmen. Und im obigen Fall ist weder die Verwendung vonthis->
noch die Verwendung vonme
angemessen - Sie erzielen die geringste Unordnung, wenn Sie diese Schlüsselwörter weglassen, wenn Sie auf Datenelemente innerhalb von Elementfunktionen zugreifen.Wenn Sie möchten, dass Ihre privaten Mitgliedsvariablen von den lokalen Variablen unterschieden werden, fügen Sie ihnen einen Link
m_
als Präfix oder einen Unterstrich als Suffix hinzu (aber wie Sie hier sehen können , ist auch diese Konvention für viele Leute "zu laut").quelle
_
sollte angehängt werden ; als Präfix ist es für interne Symbole von Standardbibliotheken und Herstellererweiterungen reserviert.__
(zwei Unterstrichen) oder einem Unterstrich gefolgt von einem Großbuchstaben beginnt . Ein einzelner Unterstrich, gefolgt von einem Kleinbuchstaben, ist in Ordnung, sofern er nicht im globalen Namespace enthalten ist.Bitte tu es nicht! Ich versuche, mit einer großen Codebasis umzugehen, in der Makros überall sind, um das Schreiben zu sparen. Das Schlimme an meiner Neudefinition ist, dass der Präprozessor ihn überall dort ersetzt, wo dies nicht im Geltungsbereich liegt / nicht zutrifft, zum Beispiel als eigenständige Funktion. Möglicherweise hat Ihr Kollege eine lokale Variable, die mich irgendwo anders nennt. Er wird sich nicht über das Debuggen freuen ... Am Ende haben Sie Makros, die Sie nicht in allen Bereichen verwenden können.
quelle
NEIN!
Stellen Sie sich die Verwirrung vor, die auftreten wird, wenn jemand diesen Header einbindet, Ihren Trick nicht kennt und an anderer Stelle in seiner Datei eine Variable oder Funktion namens "me" hat. Sie wären schrecklich verwirrt, wenn eine unergründliche Fehlermeldung ausgegeben würde.
quelle