In C # gibt es einen schönen Syntaxzucker für Felder mit Getter und Setter. Außerdem mag ich die automatisch implementierten Eigenschaften, mit denen ich schreiben kann
public Foo foo { get; private set; }
In C ++ muss ich schreiben
private:
Foo foo;
public:
Foo getFoo() { return foo; }
Gibt es ein solches Konzept in C ++ 11, das es mir ermöglicht, etwas Syntaxzucker dafür zu haben?
Antworten:
In C ++ können Sie Ihre eigenen Funktionen schreiben. Hier ist ein Beispiel für die Implementierung von Eigenschaften mit unbenannten Klassen. Wikipedia-Artikel
Sie können Ihre eigenen Getter und Setter an Ort und Stelle schreiben. Wenn Sie Zugriff auf Mitglieder der Inhaberklasse wünschen, können Sie diesen Beispielcode erweitern.
quelle
_alpha
für die private Variable undalpha
als Referenz verwenden.sizeof(Foo)
.In C ++ ist dies nicht integriert. Sie können eine Vorlage definieren , um die Funktionalität der Eigenschaften nachzuahmen:
So definieren Sie eine Eigenschaft :
Um einen benutzerdefinierten Getter / Setter zu implementieren, erben Sie einfach:
So definieren Sie eine schreibgeschützte Eigenschaft :
Und um es im Unterricht
Owner
zu benutzen :Sie können einige der oben genannten Punkte in Makros definieren , um sie übersichtlicher zu gestalten.
quelle
In der C ++ - Sprache gibt es nichts, was auf allen Plattformen und Compilern funktioniert.
Aber wenn Sie bereit sind , plattformübergreifende Kompatibilität zu brechen und zu einem bestimmten Compiler begehen Sie in der Lage sein eine solche Syntax zu verwenden, zum Beispiel in Microsoft Visual C ++ können Sie tun
quelle
Sie können mit einem Mitglied von engagierter Art und zwingenden Getter und Setter zu einem gewissen Grad emulieren
operator(type)
undoperator=
für sie. Ob es eine gute Idee ist, ist eine andere Frage und ich gehe zu+1
Kerrek SBs Antwort, um meine Meinung dazu zu äußern :)quelle
friend
zum Feldbesitzer hinzu.Vielleicht werfen Sie einen Blick auf die Eigenschaftsklasse, die ich in den letzten Stunden zusammengestellt habe: /codereview/7786/c11-feedback-on-my-approach-to-c-like-class-properties
Sie können Eigenschaften haben, die sich wie folgt verhalten:
quelle
Mit C ++ 11 können Sie eine Eigenschaftsklassenvorlage definieren und wie folgt verwenden:
Und hier ist die Eigenschaftsklassenvorlage.
quelle
C::*
bedeuten? Ich habe so etwas noch nie gesehen?C
. Dies ähnelt einem einfachen Funktionszeiger, aber um die Elementfunktion aufzurufen, müssen Sie ein Objekt angeben, für das die Funktion aufgerufen wird. Dies wird mit der LinieitsObject->*itsSetter(theValue)
im obigen Beispiel erreicht. Sehen Sie hier für eine detailliertere Beschreibung dieser Funktion.Wie viele andere bereits gesagt haben, gibt es keine integrierte Unterstützung in der Sprache. Wenn Sie jedoch auf den Microsoft C ++ - Compiler abzielen, können Sie die Microsoft-spezifische Erweiterung für Eigenschaften nutzen, die hier dokumentiert ist.
Dies ist das Beispiel von der verlinkten Seite:
quelle
Nein, C ++ hat kein Konzept von Eigenschaften. Obwohl es umständlich sein kann, getThis () oder setThat (value) zu definieren und aufzurufen, geben Sie dem Verbraucher dieser Methoden eine Erklärung ab, dass einige Funktionen auftreten können. Der Zugriff auf Felder in C ++ teilt dem Verbraucher hingegen mit, dass keine zusätzlichen oder unerwarteten Funktionen auftreten. Eigenschaften würden dies weniger offensichtlich machen, da der Zugriff auf Eigenschaften auf den ersten Blick wie ein Feld zu reagieren scheint, aber tatsächlich wie eine Methode reagiert.
Nebenbei habe ich in einer .NET-Anwendung (einem sehr bekannten CMS) versucht, ein Kundenmitgliedschaftssystem zu erstellen. Aufgrund der Art und Weise, wie sie Eigenschaften für ihre Benutzerobjekte verwendet hatten, wurden Aktionen ausgelöst, die ich nicht erwartet hatte, und meine Implementierungen wurden auf bizarre Weise ausgeführt, einschließlich unendlicher Rekursion. Dies lag daran, dass ihre Benutzerobjekte beim Versuch, auf einfache Dinge wie StreetAddress zuzugreifen, die Datenzugriffsschicht oder ein globales Caching-System aufriefen. Ihr gesamtes System basierte auf dem, was ich als Missbrauch von Immobilien bezeichnen würde. Hätten sie Methoden anstelle von Eigenschaften verwendet, hätte ich wahrscheinlich viel schneller herausgefunden, was schief gelaufen ist. Hätten sie Felder verwendet (oder zumindest ihre Eigenschaften eher wie Felder verhalten lassen), wäre das System meiner Meinung nach einfacher zu erweitern und zu warten gewesen.
[Bearbeiten] Meine Gedanken geändert. Ich hatte einen schlechten Tag gehabt und war ein bisschen geschimpft. Diese Bereinigung sollte professioneller sein.
quelle
Basierend auf https://stackoverflow.com/a/23109533/404734 gibt es hier eine Version mit einem öffentlichen Getter und einem privaten Setter:
quelle
Dies ist nicht gerade eine Eigenschaft, aber es macht das, was Sie wollen, auf einfache Weise:
Hier verhält sich das große X wie
public int X { get; private set; }
in der C # -Syntax. Wenn Sie vollständige Eigenschaften wünschen, habe ich einen ersten Versuch unternommen, um sie hier zu implementieren .quelle
X
des neuen Objekts weiterhin auf das Element des alten Objekts, da es nur wie ein Zeigerelement kopiert wird. Dies ist an sich schon schlecht, aber wenn das alte Objekt gelöscht wird, kommt es zusätzlich zu einer Speicherbeschädigung. Damit dies funktioniert, müssten Sie auch Ihren eigenen Kopierkonstruktor, Zuweisungsoperator und Verschiebungskonstruktor implementieren.Sie wissen das wahrscheinlich, aber ich würde einfach Folgendes tun:
Dieser Ansatz ist einfach, verwendet keine cleveren Tricks und erledigt den Job!
Das Problem ist jedoch, dass einige Leute ihren privaten Feldern keinen Unterstrich voranstellen möchten und diesen Ansatz daher nicht wirklich verwenden können, aber zum Glück für diejenigen, die dies tun, ist es wirklich einfach. :) :)
Die get- und set-Präfixe verleihen Ihrer API keine Klarheit, machen sie jedoch ausführlicher. Ich glaube nicht, dass sie nützliche Informationen hinzufügen, weil jemand, der eine API verwenden muss, wenn die API sinnvoll ist, wahrscheinlich erkennt, was sie ist verzichtet auf die Präfixe.
Eine weitere Sache, es ist leicht zu verstehen, dass dies Eigenschaften sind, weil
name
es kein Verb ist.Im schlimmsten Fall muss die Person, wenn sie konsistent ist und die Person nicht erkannt hat, dass
name()
es sich um einen Accessor undname(value)
einen Mutator handelt, diese nur einmal in der Dokumentation nachschlagen, um das Muster zu verstehen.So sehr ich C # liebe, ich glaube nicht, dass C ++ überhaupt Eigenschaften braucht!
quelle
foo(bar)
(anstelle der langsamerenfoo = bar
) verwenden, aber Ihre Accessoren haben überhaupt nichts mit Eigenschaften zu tun ...foo(bar)
anstattfoo=bar
mit einervoid foo(Bar bar)
Mutator-Methode für eine_foo
Mitgliedsvariable erreicht zu werden.Nein. Aber Sie sollten überlegen, ob es nur get: set-Funktion und keine zusätzliche Aufgabe gibt, die in get: set-Methoden ausgeführt wird. Machen Sie es einfach öffentlich.
quelle
Ich habe die Ideen aus mehreren C ++ - Quellen gesammelt und in ein schönes, immer noch recht einfaches Beispiel für Getter / Setter in C ++ eingefügt:
Ausgabe:
Sie können es hier online testen: http://codepad.org/zosxqjTX
quelle
Muss Ihre Klasse wirklich eine Invariante erzwingen oder handelt es sich nur um eine logische Gruppierung von Elementelementen? Wenn es das letztere ist, sollten Sie erwägen, das Ding zu einer Struktur zu machen und direkt auf die Mitglieder zuzugreifen.
quelle
Es gibt eine Reihe von Makros geschrieben Hier . Dies hat praktische Eigenschaftsdeklarationen für Werttypen, Referenztypen, schreibgeschützte Typen, starke und schwache Typen.
quelle