In welchen Szenarien ist es besser, eine struct
gegen ein class
in C++?
- Was sind die Unterschiede zwischen struct und class in C++? (30 Antworten )
Antworten
Zu viele Anzeigen?Strukturen ( PODs ) sind praktisch, wenn Sie eine C-kompatible Schnittstelle mit einer C++-Implementierung bereitstellen, da sie über Sprachgrenzen und Linkerformate hinweg portabel sind.
Wenn das für Sie keine Rolle spielt, dann ist die Verwendung von "struct" anstelle von "class" ein guter Indikator für die Absicht (wie @ZeroSignal oben sagte). Strukturen haben auch mehr vorhersehbar Kopieren Semantik, so dass sie für Daten, die Sie beabsichtigen, auf externe Medien zu schreiben oder über den Draht zu senden nützlich sind.
Strukturen sind auch praktisch für verschiedene Metaprogrammieraufgaben, wie z.B. Traits-Templates, die einfach eine Reihe von abhängigen Typdefs offenlegen:
template <typename T> struct type_traits {
typedef T type;
typedef T::iterator_type iterator_type;
...
};
...Aber das ist eigentlich nur ein Ausnutzen der Tatsache, dass die Standardschutzstufe von struct öffentlich ist...
Wie andere bereits festgestellt haben
- beide sind abgesehen von der Standard-Sichtbarkeit gleichwertig
- es kann Gründe dafür geben, dass man gezwungen ist, das eine oder das andere zu verwenden, aus welchen Gründen auch immer
Es gibt eine klare Empfehlung von Stroustrup/Sutter, wann man was verwenden sollte:
Denken Sie jedoch daran, dass es nicht ratsam ist, etw. als Klasse zu deklarieren ( class X;
) und definieren es als struct ( struct X { ... }
). Bei einigen Linkern (z. B. g++) kann es funktionieren, bei anderen (z. B. MSVC) nicht, so dass Sie sich in der Entwicklerhölle wiederfinden.
Ein Vorteil von struct
über class
ist, dass es eine Zeile Code einspart, wenn man sich an das Prinzip "erst öffentliche Mitglieder, dann private" hält. Vor diesem Hintergrund finde ich das Schlüsselwort class
unbrauchbar.
Ein weiterer Grund für die ausschließliche Verwendung von struct
und nie class
. Einige Code-Stilrichtlinien für C++ empfehlen die Verwendung von Kleinbuchstaben für Funktionsmakros mit der Begründung, dass der Name nicht geändert werden muss, wenn das Makro in eine Inline-Funktion umgewandelt wird. Das gilt auch hier. Sie haben eine schöne Struktur im C-Stil, und eines Tages stellen Sie fest, dass Sie einen Konstruktor oder eine einfache Methode hinzufügen müssen. Ändern Sie es in eine class
? Überall?
Die Unterscheidung zwischen struct
s und class
es ist einfach zu umständlich und behindert uns bei dem, was wir eigentlich tun sollten - dem Programmieren. Wie so viele Probleme von C++ resultiert es aus dem starken Wunsch nach Rückwärtskompatibilität.
Beide struct
y class
sind unter der Haube die gleichen, wenn auch mit unterschiedlichen Voreinstellungen für die Sichtbarkeit, struct
ist standardmäßig öffentlich und class
Standard ist privat. Sie können das eine durch die entsprechende Verwendung von private
y public
. Beide erlauben Vererbung, Methoden, Konstruktoren, Destruktoren und all die anderen Vorzüge einer objektorientierten Sprache.
Ein großer Unterschied zwischen den beiden ist jedoch, dass struct
als Schlüsselwort wird in C unterstützt, während class
ist nicht. Das bedeutet, dass man eine struct
in einer Include-Datei, die #include
entweder in C++ oder C, solange die struct
ist ein einfacher C-Stil struct
und alles andere in der Include-Datei ist kompatibel mit C, d.h. keine C++-spezifischen Schlüsselwörter wie private
, public
keine Methoden, keine Vererbung, etc. etc. etc.
A C-Stil struct
kann mit anderen Schnittstellen verwendet werden, die die Verwendung von C-Stil struct
um Daten über die Schnittstelle hin und her zu transportieren.
A C-Stil struct
ist eine Art Schablone (keine C++-Schablone, sondern eher ein Muster oder eine Schablone), die das Layout eines Speicherbereichs beschreibt. Im Laufe der Jahre wurden Schnittstellen geschaffen, die von C aus und mit C-Plug-ins (wir schauen auf Java, Python und Visual Basic) verwendet werden können und von denen einige mit C-Stil arbeiten struct
.
Nachdem ich jahrelang in C++, meiner Hauptsprache, programmiert habe, bin ich zu dem Schluss gekommen, dass dies eine weitere dumme Eigenschaft von C++ ist.
Es gibt keinen wirklichen Unterschied zwischen den beiden, und es gibt keinen Grund, warum ich zusätzliche Zeit damit verbringen sollte, zu entscheiden, ob ich meine Entität als Struktur oder als Klasse definieren sollte.
Um diese Frage zu beantworten, können Sie Ihre Entität immer als struct definieren. Die Mitglieder werden standardmäßig öffentlich sein, was die Norm ist. Aber noch wichtiger ist, dass die Vererbung standardmäßig öffentlich ist. Geschützte Vererbung und noch schlimmer, private Vererbung sind die Ausnahmen.
Ich habe noch nie einen Fall gehabt, in dem private Vererbung das Richtige war. Ja, ich habe versucht, Probleme zu erfinden, um private Vererbung zu verwenden, aber es hat nicht funktioniert. Und Java, das Vorbild der objektorientierten Programmierung, setzt auf öffentliche Vererbung, wenn man nicht die Accessor-Schlüsselwörter verwendet. Übrigens erlaubt Java keine Accessor-Schlüsselwörter für geerbte Klassen, sie können nur öffentlich vererbt werden. Sie sehen also, dass das cpp-Team hier wirklich versagt hat.
Eine weitere frustrierende Sache über diese, ist, dass, wenn Sie als Klasse definieren und deklarieren als struct Sie Kompilierung Warnung erhalten. Als ob dies etwas ist, das die Leistung oder Genauigkeit Ihres Programms beeinträchtigt. In einer Antwort wurde auch darauf hingewiesen, dass MSVC stattdessen einen Compilerfehler ausgeben kann.
Diejenigen, die bei Regen Klassen und bei Sonnenschein Strukturen nutzen, tun dies auf der Grundlage dessen, was man ihnen beigebracht hat. Es ist nicht etwas, das sie als wahr entdeckt haben. In Java gibt es kein Namenspaar für Klassen, sondern nur das Schlüsselwort class. Wenn Sie eine Datenstruktur wollen, machen Sie einfach alle Mitglieder öffentlich und fügen Sie keine Funktionen hinzu. Das funktioniert in Java und ich sehe darin kein Problem. Was ist das Problem? Sie brauchen 4 oder 5 Zeichen Stücklistencode, um zu bestimmen, wie der Kontext einer Klassenentität zu interpretieren ist.