Dies gilt nicht nur für C ++, sondern für jede Sprache, die sowohl Strukturen als auch Klassen bereitstellt.
Jason Bunting
3
Ich bin immer noch anderer Meinung - ich gehe diese Frage semantisch an. Vielleicht gibt es einige technische Unterschiede, aber semantisch sind sie nicht. Strukturen sind sehr nützlich zum Erstellen von Werttypen, Klassen nicht.
Jason Bunting
4
Ich glaube, dass es keinen ernsthaften Grund gibt, Strukturen in C ++ zu verwenden. Für mich sind Strukturen eine weitere redundante "Funktion" von C ++, die nur aus Kompatibilitätsgründen mit C existiert, wie typedefs. Diese wären nicht vorhanden, wenn C ++ ursprünglich nicht als Erweiterung von C behandelt und von Grund auf neu entwickelt worden wäre, z. B. Java. Im Allgemeinen finde ich, dass viele der seltsamsten Dinge in C ++ mit der C-Kompatibilität zu tun haben.
Kostas
5
Struktur - Für POD (einfache alte Daten) und alle Zugänglichkeiten für Mitglieder ist öffentlich. Klasse - Wenn Sie eine bessere Kapselung benötigen und Elementfunktionen benötigen, um mit dem Status der Klasse zu arbeiten.
Navaneeth KN
4
Dies gilt nur durch Konvention. Abgesehen von der Standardkapselung gibt es keinen Unterschied.
Dave Hillier
Antworten:
804
Unterschiede zwischen a classund a structin C ++ bestehen darin, dass Strukturen Standardelemente publicund Basen haben und Klassen Standardelemente privateund Basen haben. Beiden Klassen und Strukturen können eine Mischung aus haben public, protectedund privateMitglieder können Vererbung verwenden und können Elementfunktionen haben.
Ich würde empfehlen, Strukturen als einfache alte Datenstrukturen ohne klassenähnliche Merkmale und Klassen als aggregierte Datenstrukturen mit privateDaten- und Elementfunktionen zu verwenden .
Eine Struktur ohne Modifikatoren oder Methoden wird als POD-Struktur bezeichnet, die als abwärtskompatible Schnittstelle zu C-Bibliotheken existiert, da sie (angeblich) garantiert so angelegt ist, als wäre sie eine C-Struktur. Abgesehen von dieser einen Ausnahme ist der einzige Unterschied wie angegeben.
workmad3
26
@ workmad3: Der Name ist irreführend, aber 9/4 (C ++ 03) sagt: "Eine POD-Struktur ist eine Aggregatklasse, die keine nicht statischen Datenelemente vom Typ Nicht-POD-Struktur, Nicht-POD-Vereinigung enthält (oder ein Array solcher Typen) oder Referenz und hat keinen benutzerdefinierten Kopierzuweisungsoperator und keinen benutzerdefinierten Destruktor. " Es gibt keine Einschränkung für die Verwendung des Klassenschlüssels "struct" und keine Einschränkung für die Verwendung von "public" (aggregierte Anforderungen siehe 8.5.1 / 1). Dies ist kein Unterschied zwischen "struct" und "class".
5
Ihre Verwendung von "Aggregat" könnte angesichts der Definition des Standards missverstanden werden. :)
3
Laut Stroustrups "Principles and Practice" -Buch: "Strukturen sollten hauptsächlich dort verwendet werden, wo die Mitglieder einen beliebigen Wert annehmen können" (dh wo keine sinnvolle Klasseninvariante definiert werden kann)
Antibus
6
Natürlich können Sie Klassen verwenden, wenn Sie eine Schnittstelle zu C herstellen. Es gibt keinen Unterschied zwischen Klassen und Strukturen. Strukturen sind Klassen; Nur der Standardzugriff wird von privat zu öffentlich gespiegelt.
Sebastian Mach
229
Wie alle anderen bemerken, gibt es wirklich nur zwei tatsächliche Sprachunterschiede:
structStandardmäßig wird der öffentliche Zugriff und classstandardmäßig der private Zugriff verwendet.
Beim Erben wird structstandardmäßig die publicVererbung und classstandardmäßig die privateVererbung verwendet. (Ironischerweise ist, wie bei so vielen Dingen in C ++, die Standardeinstellung rückwärts: publicVererbung ist bei weitem die häufigere Wahl, aber die Leute erklären selten structs, nur um beim Eingeben des publicSchlüsselworts " " zu sparen .
Der wirkliche Unterschied in der Praxis besteht jedoch zwischen einem class/ struct, das einen Konstruktor / Destruktor deklariert, und einem, der dies nicht tut. Es gibt bestimmte Garantien für einen POD-Typ mit "einfachen alten Daten", die nicht mehr gelten, sobald Sie die Konstruktion der Klasse übernehmen. Um diese Unterscheidung klar zu halten, verwenden viele Menschen structs absichtlich nur für POD-Typen und verwenden es, wenn sie überhaupt Methoden hinzufügen wollen class. Der Unterschied zwischen den beiden folgenden Fragmenten ist ansonsten bedeutungslos:
class X{public:// ...};struct X{// ...};
(Übrigens, hier ist ein Thread mit einigen guten Erklärungen darüber, was "POD-Typ" eigentlich bedeutet: Was sind POD-Typen in C ++? )
Schönes Beispiel zu den Vererbungsunterschieden: hier .
Liran Orevi
8
Ob Sie verwenden structoder classkeinen Einfluss darauf haben, ob Ihr Objekt POD ist oder ob Sie einen Kopierkonstruktor / Destruktor definieren sollten. Mitgliedsfunktionen haben auch keinen Einfluss darauf, dass etwas POD ist. Als ich noch einmal lese, was Sie geschrieben haben, sehe ich, dass Sie nichts anderes vorschlagen, aber der aktuelle Wortlaut ist verwirrend
David Stone
1
@DavidStone Grundsätzlich sollen POD-Strukturen garantiert abwärtskompatibel mit C-Code sein und daher grundsätzlich nur als C-artige Strukturen entworfen werden.
Justin Time - Stellen Sie Monica
3
Der "echte Unterschied" Teil dieser Antwort ist völlig falsch.
Juanchopanza
177
Die vorhandenen Antworten enthalten viele Missverständnisse.
Ja, möglicherweise müssen Sie Ihre Schlüsselwörter zum Ändern des Zugriffs innerhalb der Klassendefinition neu anordnen, je nachdem, mit welchem Schlüsselwort Sie die Klasse deklariert haben.
Über die Syntax hinaus ist der einzige Grund, einen über den anderen zu wählen, Konvention / Stil / Präferenz.
Einige Leute halten sich gerne an das structSchlüsselwort für Klassen ohne Elementfunktionen, da die resultierende Definition wie eine einfache Struktur aus C aussieht.
In ähnlicher Weise verwenden einige Leute das classSchlüsselwort gerne für Klassen mit Elementfunktionen und privateDaten, da dort "Klasse" steht und daher wie Beispiele aus ihrem Lieblingsbuch über objektorientierte Programmierung aussieht.
Die Realität ist, dass dies ganz bei Ihnen und Ihrem Team liegt und buchstäblich keinen Unterschied für Ihr Programm macht.
Die folgenden zwei Klassen sind bis auf ihren Namen in jeder Hinsicht absolut gleichwertig:
structFoo{int x;};classBar{public:int x;};
Sie können sogar Schlüsselwörter wechseln, wenn Sie neu deklarieren:
Beachten Sie jedoch, dass Sie die Schlüsselwörter bei der Neudefinition nicht wechseln können . Dies liegt nur daran, dass (gemäß der Ein-Definitions-Regel) doppelte Klassendefinitionen über Übersetzungseinheiten hinweg "aus derselben Folge von Token bestehen müssen" . Das heißt , Sie können nicht einmal austauschen const int member;mit int const member;, und haben nichts mit der Semantik zu tun classoder struct.
Dies war sehr informativ und ehrlich gesagt meine Lieblingsantwort. Alle anderen behandeln sie als separate Einheiten, wenn sie unter der Haube gleich sind. Ich frage mich, ob eine Strukturdefinition in der Arduino-Umgebung als cpp-Klasse betrachtet wird, da sie mit g ++ kompiliert wurde.
Benjamin
4
@ Ben Natürlich ist es. Der Arduino-Compiler kompiliert C ++; das ist das Ende davon.
underscore_d
6
Wenn ich dieses Recht verstehe: Solange Ihre Sichtbarkeitsmodifikatoren explizit sind und nicht ausgelassen werden, spielt es keine Rolle. Sie könnten eine riesige C ++ - Anwendung nur mit Strukturen schreiben. oder Sie könnten jeden Fall von struct in class ändern. Solange Sie nicht die Standardsichtbarkeit verwenden, sind die Anwendungen genau gleich.
Ryan Lundy
Ich bin nicht davon überzeugt, dass eine Übersetzungseinheit eines C ++ - Programms die vollständige Deklaration haben kann class foo { public: ... };und eine andere struct foo { ... };, die gemäß der "absolut äquivalenten" Behauptung gelten müsste. Es liegt auf der Hand, dass die unvollständigen Erklärungen struct foo;und class foo;austauschbar sind. Diese geben den Klassenkörper nicht an und sprechen daher nichts für das Zugriffslayout.
Kaz
@Kaz: Sie haben Recht - wenn die Definitionen für buchstäblich denselben Typ waren, müssen sie lexikalisch identisch sein, damit das Verhalten genau definiert ist. Der Strukturschlüssel und der Klassenschlüssel sind jedoch ansonsten logisch austauschbar (wobei die Semantik nicht betroffen ist) Foound Barsind immer noch äquivalente / identische Typen. Ich habe darauf geachtet , "beim erneuten Deklarieren " zu sagen und ein Beispiel zu geben. Wenn ich darüber nachdenke, werde ich dies in der Antwort klarstellen, um sicherzustellen, dass ich die Leute nicht zu UB
Lightness Races in Orbit
54
Ich verwende eine Struktur nur anstelle einer Klasse, wenn ich einen Funktor deklariere, bevor ich ihn in einem Funktionsaufruf verwende, und aus Gründen der Übersichtlichkeit die Syntax minimieren möchte. z.B:
Die Mitglieder und Basisklassen einer Struktur sind standardmäßig öffentlich, während sie in der Klasse standardmäßig privat sind. Hinweis: Sie sollten Ihre Basisklassen explizit öffentlich, privat oder geschützt machen, anstatt sich auf die Standardeinstellungen zu verlassen.
Struktur und Klasse sind ansonsten funktional äquivalent.
OK, genug von diesem blitzsauberen Techno-Gerede. Emotional unterscheiden die meisten Entwickler stark zwischen einer Klasse und einer Struktur. Eine Struktur fühlt sich einfach wie ein offener Stapel von Bits an, der nur sehr wenig Kapselung oder Funktionalität bietet. Eine Klasse fühlt sich wie ein lebendiges und verantwortungsbewusstes Mitglied der Gesellschaft mit intelligenten Diensten, einer starken Verkapselungsbarriere und einer klar definierten Schnittstelle. Da dies die Konnotation ist, die die meisten Leute bereits haben, sollten Sie wahrscheinlich das Schlüsselwort struct verwenden, wenn Sie eine Klasse haben, die nur sehr wenige Methoden und öffentliche Daten enthält (solche Dinge existieren in gut gestalteten Systemen!), Aber ansonsten sollten Sie wahrscheinlich die Klasse verwenden Stichwort.
Ich verstehe nicht, warum sie behaupten, dass Struktur und Klasse funktional gleich sind, aber sagen, dass sie in bestimmten Fällen ohne Begründung die eine der anderen vorziehen sollen.
Deetz
3
Der Grund ist Konvention. Dem Compiler ist es egal, welchen Sie verwenden, aber ein anderer Entwickler, der sich Ihren Code ansieht, kann leichter verstehen, was Sie gemeint haben.
Tal Pressman
3
@deetz: Der gesamte dritte Absatz ist eine Argumentation.
Leichtigkeitsrennen im Orbit
Wow, ich kam aus der 'alten Schule' und hatte keine Ahnung, dass eine Struktur Methoden und sogar Vererbung haben könnte. Ich habe struct immer verwendet, wenn nur Daten ohne Methoden verwendet wurden, und normalerweise, wenn es sich um API-Code handelt, der die struct benötigt. Können Strukturen auch Mehrfachvererbung unterstützen?
Paul McCarthy
21
Ein Ort, an dem eine Struktur für mich hilfreich war, ist, wenn ich ein System habe, das Nachrichten mit festem Format (z. B. eine serielle Schnittstelle) von einem anderen System empfängt. Sie können den Bytestrom in eine Struktur umwandeln, die Ihre Felder definiert, und dann einfach auf die Felder zugreifen.
Natürlich ist dies das gleiche, was Sie in C tun würden, aber ich finde, dass sich der Aufwand, die Nachricht in eine Klasse dekodieren zu müssen, normalerweise nicht lohnt.
Oder Sie könnten einfach operator >>eine Klasse implementieren, anstatt die processMessageFunktion zu schreiben , wodurch Ihr C ++ eher wie richtiges C ++ und weniger wie C aussieht.
Nick Bastin
1
Abgesehen von der Tatsache, dass es nicht zwischen verschiedenen Systemen portierbar ist, verstößt dies gegen Aliasing-Regeln, sodass nicht garantiert werden kann, dass es auch innerhalb einer einzelnen Architektur funktioniert.
underscore_d
@underscore_d Dies kann plattformunabhängig (aber nicht vom Compiler) funktionieren, aber Sie müssen feste Bitfelder und eine __packed__Struktur verwenden und über eine endian-fähige ifdef-Implementierung verfügen (Sie müssen die Reihenfolge auf einem Computer umkehren, auf dem die Endianess der externen Datenquelle entgegengesetzt ist bietet). Es ist nicht schön, aber ich habe Register für Remote-Peripheriegeräte auf eingebetteten Plattformen auf tragbare Weise gepackt / entpackt.
krasische
1
@ Jacwah Huh, guter Punkt. Aliasing ist hier kein Problem, da einer der Zeiger ein charTyp ist, der vom Aliasing ausgenommen ist. Es gibt jedoch immer noch ein Problem, wenn auch ein anderes: Das Umwandeln eines char*in einen anderen Typ, wenn an dieser Adresse nicht wirklich ein Objekt des letzteren Typs bereits initialisiert wurde, ist UB, da es gegen die Lebensdauerregeln verstößt. Afaik, selbst wenn der Zieltyp trivial konstruierbar ist, reicht es für C ++ nicht aus, nur Speicher zuzuweisen, um diesen Speicher formal als diesen Typ zu behandeln.
underscore_d
19
Sie können "struct" in C ++ verwenden, wenn Sie eine Bibliothek schreiben, deren Interna C ++ sind, die API jedoch entweder von C- oder C ++ - Code aufgerufen werden kann. Sie erstellen einfach einen einzelnen Header, der Strukturen und globale API-Funktionen enthält, die Sie sowohl C- als auch C ++ - Code wie folgt aussetzen:
// C access Header to a C++ library#ifdef __cpp
extern"C"{#endif// Put your C struct's herestruct foo
{...};// NOTE: the typedef is used because C does not automatically generate// a typedef with the same name as a struct like C++.typedefstruct foo foo;// Put your C API functions herevoid bar(foo *fun);#ifdef __cpp
}#endif
Dann können Sie eine Funktionsleiste () in eine C ++ - Datei mit C ++ - Code schreiben und von C aus aufrufen, und die beiden Welten können Daten über die deklarierten Strukturen gemeinsam nutzen. Es gibt natürlich andere Einschränkungen beim Mischen von C und C ++, aber dies ist ein vereinfachtes Beispiel.
Beste passende Antwort. C-Kompatibilität ist wirklich der wichtigste Grund. Alle anderen Dinge wie der Standardzugriff sind esoterisch.
Valentin Heinitz
16
Wie jeder sagt, ist der einzige wirkliche Unterschied der Standardzugriff. Aber ich benutze struct besonders, wenn ich keine Kapselung mit einer einfachen Datenklasse möchte, selbst wenn ich einige Hilfsmethoden implementiere. Zum Beispiel, wenn ich so etwas brauche:
+1 für ein Beispiel einer Struktur mit einigen Elementfunktionen, die nicht das Gefühl haben, "die Struktur entfernt zu haben".
Einpoklum
9
Um meine eigene Frage zu beantworten (schamlos): Wie bereits erwähnt, sind Zugriffsrechte der einzige Unterschied zwischen ihnen in C ++.
Ich neige dazu, eine Struktur nur zur Datenspeicherung zu verwenden. Ich werde zulassen, dass es einige Hilfsfunktionen erhält, wenn es die Arbeit mit den Daten erleichtert. Sobald die Daten jedoch eine Flusskontrolle erfordern (dh Getter / Setter, die einen internen Zustand beibehalten oder schützen) oder wichtige Funktionen erwerben (im Grunde genommen objektähnlicher), werden sie zu einer Klasse "aktualisiert", um die Absicht besser zu kommunizieren.
Strukturen ( PODs im Allgemeinen) sind praktisch, wenn Sie eine C-kompatible Schnittstelle mit einer C ++ - Implementierung bereitstellen, da sie über Sprachgrenzen und Linkerformate hinweg portierbar sind.
Wenn Ihnen das nichts ausmacht, ist die Verwendung von "struct" anstelle von "class" vermutlich ein guter Kommunikator der Absicht (wie @ZeroSignal oben sagte). Strukturen haben auch eine vorhersehbarere Kopiersemantik, sodass sie für Daten nützlich sind, die Sie auf externe Medien schreiben oder über das Kabel senden möchten.
Strukturen eignen sich auch für verschiedene Metaprogrammieraufgaben, z. B. für Vorlagen für Merkmale, die nur eine Reihe abhängiger Typedefs verfügbar machen:
template<typename T>struct type_traits {typedef T type;typedef T::iterator_type iterator_type;...};
... Aber das nutzt wirklich nur den Vorteil, dass die Standardschutzstufe von struct öffentlich ist ...
Das ist nicht die richtige Verwendung von POD. Eine Struktur (oder Klasse) kann eine POD-Struktur sein, wenn (und nur wenn) sie NUR POD-Mitglieder enthält.
Martin York
4
"Vorhersagbare Kopiersemantik": Die Symantik ist dieselbe wie für die Klasse (und hat dieselben Probleme (flache Kopie)).
Martin York
2
In diesem Beitrag würden Sie (hoffentlich aus Versehen) glauben lassen, dass alle Strukturen PODs sind. Das ist überhaupt nicht wahr. Ich hoffe, dass die Leute dadurch nicht irregeführt werden.
Michael Dorst
8
Für C ++ gibt es wirklich keinen großen Unterschied zwischen Strukturen und Klassen. Der Hauptfunktionsunterschied besteht darin, dass Mitglieder einer Struktur standardmäßig öffentlich sind, während sie in Klassen standardmäßig privat sind. Ansonsten sind sie sprachlich gleichwertig.
Trotzdem neige ich dazu, Strukturen in C ++ zu verwenden, wie ich es in C # tue, ähnlich wie Brian es gesagt hat. Strukturen sind einfache Datencontainer, während Klassen für Objekte verwendet werden, die auf die Daten einwirken müssen und nicht nur daran festhalten.
Sie sind so ziemlich dasselbe. Dank der Magie von C ++ kann eine Struktur Funktionen enthalten, Vererbung verwenden, mit "neu" erstellt werden usw. wie eine Klasse
Der einzige funktionale Unterschied besteht darin, dass eine Klasse mit privaten Zugriffsrechten beginnt, während eine Struktur mit öffentlichen beginnt. Dies ist die Aufrechterhaltung der Abwärtskompatibilität mit C.
In der Praxis habe ich immer Strukturen als Datenhalter und Klassen als Objekte verwendet.
Beachten Sie jedoch, dass es nicht ratsam ist, etw. Weiterzuleiten. als Klasse ( class X;) und definieren Sie es als struct ( struct X { ... }). Es kann auf einigen Linkern (z. B. g ++) funktionieren und auf anderen (z. B. MSVC) fehlschlagen, sodass Sie sich in der Entwicklerhölle befinden.
@ LightnessRacesinOrbit kann ich leider nicht. Ich kann nicht einmal ein Beispiel herstellen. Das Trivial wird class Foo; struct Foo { void bar() {} }; int main() { Foo().bar(); }nicht nur mit MSVC 2017 kompiliert und ausgeführt, es erzeugt sogar eine eindeutige Warnung, die Fooals deklariert, structaber als definiert wurde class. Aber ich erinnere mich auch deutlich daran, dass es unser Team einen halben Tag gekostet hat, diesen dummen Fehler zu finden. Ich bin mir nicht sicher, welche MSVC-Version wir damals verwendet haben.
Pasbi
Der Linker sollte nicht einmal wissen, ob Sie eine Forward-Deklaration verwendet haben classoder nicht struct, und die beiden sind gemäß dem Standard frei austauschbar (obwohl bekannt ist, dass VS warnt; ich habe immer angenommen, dass dies nur dazu dient, offensichtliche Programmiererfehler zu vermeiden). Hier riecht etwas nicht. Sind Sie sicher, dass es sich nicht um einen ODR-Verstoß handelt?
Ich erinnere mich nicht genau. Das Problem trat nicht direkt in einer Anwendung auf, sondern in einer Bibliothek, die in einem gtest verwendet wurde. Ich weiß nur, dass der Linker unverständliche Fehler verursacht hat (LNK ???). Sobald ich die struct-vorwärts- classvorwärts- ersetzt hatte, verschwanden die Probleme. Ab heute finde ich es auch seltsam. Ich würde mich freuen, wenn Sie etwas Licht ins Dunkel bringen könnten.
Pasbi
3
Klasse.
Klassenmitglieder sind standardmäßig privat.
class test_one {int main_one();};
Ist äquivalent zu
class test_one {private:int main_one();};
Also, wenn Sie es versuchen
int two = one.main_one();
Wir werden eine Fehlermeldung erhalten: main_one is privateweil es nicht zugänglich ist. Wir können es lösen, indem wir es initialisieren, indem wir es als öffentlich angeben, dh
class test_one {public:int main_one();};
Struct.
Eine Struktur ist eine Klasse, in der Mitglieder standardmäßig öffentlich sind.
struct test_one {int main_one;};
Mittel main_oneist privat dh
class test_one {public:int main_one;};
Ich verwende Strukturen für Datenstrukturen, in denen die Mitglieder einen beliebigen Wert annehmen können. Auf diese Weise ist es einfacher.
Ein Vorteil von structover classist, dass eine Codezeile gespeichert wird, wenn "zuerst öffentliche Mitglieder, dann private" verwendet werden. In diesem Licht finde ich das Schlüsselwort classnutzlos.
Hier ist ein weiterer Grund, nur structund nie zu verwenden class. Einige Richtlinien für den Codestil für C ++ schlagen vor, kleine Buchstaben für Funktionsmakros zu verwenden. Der Grund dafür ist, dass der Name bei der Konvertierung des Makros in eine Inline-Funktion nicht geändert werden muss. Hier gilt das gleiche. Sie haben Ihre schöne Struktur im C-Stil und eines Tages müssen Sie einen Konstruktor oder eine bequeme Methode hinzufügen. Ändern Sie es in ein class? Überall?
Die Unterscheidung zwischen structs und classes ist einfach zu mühsam, um das zu tun, was wir tun sollten - das Programmieren. Wie so viele Probleme von C ++ entsteht es aus dem starken Wunsch nach Abwärtskompatibilität.
Warum sollten Sie es in a ändern müssen class? Haben Sie gedacht, dass eine mit dem structSchlüsselwort definierte Klasse keine Elementfunktionen oder keinen Konstruktor haben kann?
Leichtigkeitsrennen im Orbit
@ LightnessRacesinOrbit wegen 1. Konsistenz und 2. einige statische Analysatoren beschweren sich über die Verletzung von 1.
Vorac
Das folgt nicht. An welchen anderen "Konsistenzen" halten Sie sich? Jede Klasse mit einem aufgerufenen Mitglied joe()muss mit einem classSchlüsselwort definiert werden . Jede Klasse mit mindestens 4 intMitgliedern muss mit einem structSchlüsselwort definiert werden ?
Leichtigkeitsrennen im Orbit
@LightnessRacesinOrbit Ich beziehe mich auf die Redewendung "POD-Aggregate sind definiert mit struct, Aggregate mit Methoden sind definiert mit class". Zu viel Aufwand.
Vorac
2
Sie sind dasselbe mit unterschiedlichen Standardeinstellungen (standardmäßig privat für classund öffentlich für standardmäßig struct), sodass sie theoretisch vollständig austauschbar sind.
Wenn ich also nur einige Informationen packen möchte, um mich zu bewegen, verwende ich eine Struktur, auch wenn ich dort einige Methoden (aber nicht viele) eingefügt habe. Wenn es eine größtenteils undurchsichtige Sache ist, bei der die Hauptverwendung über Methoden und nicht direkt für die Datenelemente erfolgt, verwende ich eine vollständige Klasse.
Strukturen haben standardmäßig öffentlichen Zugriff und Klassen haben standardmäßig privaten Zugriff.
Persönlich verwende ich Strukturen für Datenübertragungsobjekte oder als Wertobjekte. Bei Verwendung als solche deklariere ich alle Mitglieder als const, um Änderungen durch anderen Code zu verhindern.
Beide structund classsind unter der Haube gleich, obwohl die structStandardeinstellungen für die Sichtbarkeit unterschiedlich sind. Die Standardeinstellung ist öffentlich und die classStandardeinstellung ist privat. Sie können bei entsprechender Verwendung von privateund eines der beiden ändern, um das andere zu sein public. Beide erlauben Vererbung, Methoden, Konstruktoren, Destruktoren und alle anderen Extras einer objektorientierten Sprache.
Ein großer Unterschied zwischen den beiden besteht jedoch darin, dass structein Schlüsselwort in C unterstützt wird, während dies classnicht der Fall ist. Dies bedeutet , dass man ein verwenden können structin einer Include - Datei , die sein kann #includeentweder in C ++ oder C, solange das structist eine einfache C - Stil structund alles andere in der Include - Datei mit C kompatibel ist, dh keine C ++ bestimmte Schlüsselwörter wie private, public, nein Methoden, keine Vererbung usw. usw. usw.
Der AC-Stil structkann mit anderen Schnittstellen verwendet werden, die die Verwendung des C-Stils unterstützen struct, um Daten über die Schnittstelle hin und her zu übertragen.
Der AC-Stil structist eine Art Vorlage (keine C ++ - Vorlage, sondern ein Muster oder eine Schablone), die das Layout eines Speicherbereichs beschreibt. Im Laufe der Jahre wurden Schnittstellen erstellt, die von C und mit C-Plug-Ins verwendet werden können (hier sehen Sie Java, Python und Visual Basic), von denen einige im C-Stil funktionieren struct.
Technisch sind beide in C ++ gleich - zum Beispiel kann eine Struktur überladene Operatoren usw. haben.
Jedoch :
Ich verwende Strukturen, wenn ich Informationen mehrerer Typen gleichzeitig übergeben möchte. Ich verwende Klassen, wenn ich mich mit einem "funktionalen" Objekt befasse.
Wann würden Sie struct und wann class in C ++ verwenden?
Ich benutze, structwenn ich functorsund definiere POD. Ansonsten benutze ich class.
// '()' is public by default!struct mycompare :public std::binary_function<int,int,bool>{booloperator()(int first,int second){return first < second;}};class mycompare :public std::binary_function<int,int,bool>{public:booloperator()(int first,int second){return first < second;}};
Alle Klassenmitglieder sind standardmäßig privat und alle Strukturmitglieder sind standardmäßig öffentlich. Klasse hat standardmäßige private Basen und Struct hat standardmäßige öffentliche Basen. Struktur im Fall von C kann keine Elementfunktionen haben, während wie im Fall von C ++ Elementfunktionen zur Struktur hinzugefügt werden können. Abgesehen von diesen Unterschieden finde ich nichts Überraschendes an ihnen.
Ich verwende struct nur, wenn ich einige Daten ohne zugehörige Elementfunktionen speichern muss (um die Elementdaten zu bearbeiten) und direkt auf die Datenvariablen zugreifen kann.
Beispiel: Lesen / Schreiben von Daten aus Dateien und Socket-Streams usw. Übergeben von Funktionsargumenten in einer Struktur, in der die Funktionsargumente zu viele sind und die Funktionssyntax zu lang erscheint.
Technisch gesehen gibt es keinen großen Unterschied zwischen Klasse und Struktur, außer der Standardzugänglichkeit. Darüber hinaus hängt es vom Programmierstil ab, wie Sie es verwenden.
Ich dachte, dass Structs als Datenstruktur (wie ein Array von Informationen mit mehreren Datentypen) gedacht war und Klassen für Code Packaging (wie Sammlungen von Unterroutinen und Funktionen) vorgesehen waren.
Ich kann mir nie ein Szenario vorstellen, in dem Sie eine Struktur verwenden würden, wenn Sie private Mitglieder möchten, es sei denn, Sie versuchen absichtlich, verwirrend zu sein.
Es scheint, dass die Verwendung von Strukturen eher ein syntaktischer Hinweis darauf ist, wie die Daten verwendet werden, aber ich möchte lieber nur eine Klasse erstellen und versuchen, dies im Namen der Klasse oder durch Kommentare explizit zu machen.
Meiner Meinung nach ist eine "syntaktische Angabe, wie Daten verwendet werden" ein guter Grund, eine Struktur zu verwenden, insbesondere wenn die Alternative darin besteht, einen Kommentar oder einen Namen im Klassennamen zu verwenden.
Viktor Sehr
2
Wäre es nicht structziemlich explizit zu deklarieren, dass die Mitglieder der Klasse standardmäßig öffentlich sind?
Antworten:
Unterschiede zwischen a
class
und astruct
in C ++ bestehen darin, dass Strukturen Standardelementepublic
und Basen haben und Klassen Standardelementeprivate
und Basen haben. Beiden Klassen und Strukturen können eine Mischung aus habenpublic
,protected
undprivate
Mitglieder können Vererbung verwenden und können Elementfunktionen haben.Ich würde empfehlen, Strukturen als einfache alte Datenstrukturen ohne klassenähnliche Merkmale und Klassen als aggregierte Datenstrukturen mit
private
Daten- und Elementfunktionen zu verwenden .quelle
Wie alle anderen bemerken, gibt es wirklich nur zwei tatsächliche Sprachunterschiede:
struct
Standardmäßig wird der öffentliche Zugriff undclass
standardmäßig der private Zugriff verwendet.struct
standardmäßig diepublic
Vererbung undclass
standardmäßig dieprivate
Vererbung verwendet. (Ironischerweise ist, wie bei so vielen Dingen in C ++, die Standardeinstellung rückwärts:public
Vererbung ist bei weitem die häufigere Wahl, aber die Leute erklären seltenstruct
s, nur um beim Eingeben despublic
Schlüsselworts " " zu sparen .Der wirkliche Unterschied in der Praxis besteht jedoch zwischen einem
class
/struct
, das einen Konstruktor / Destruktor deklariert, und einem, der dies nicht tut. Es gibt bestimmte Garantien für einen POD-Typ mit "einfachen alten Daten", die nicht mehr gelten, sobald Sie die Konstruktion der Klasse übernehmen. Um diese Unterscheidung klar zu halten, verwenden viele Menschenstruct
s absichtlich nur für POD-Typen und verwenden es, wenn sie überhaupt Methoden hinzufügen wollenclass
. Der Unterschied zwischen den beiden folgenden Fragmenten ist ansonsten bedeutungslos:(Übrigens, hier ist ein Thread mit einigen guten Erklärungen darüber, was "POD-Typ" eigentlich bedeutet: Was sind POD-Typen in C ++? )
quelle
struct
oderclass
keinen Einfluss darauf haben, ob Ihr Objekt POD ist oder ob Sie einen Kopierkonstruktor / Destruktor definieren sollten. Mitgliedsfunktionen haben auch keinen Einfluss darauf, dass etwas POD ist. Als ich noch einmal lese, was Sie geschrieben haben, sehe ich, dass Sie nichts anderes vorschlagen, aber der aktuelle Wortlaut ist verwirrendDie vorhandenen Antworten enthalten viele Missverständnisse.
Beides
class
undstruct
deklariere eine Klasse.Ja, möglicherweise müssen Sie Ihre Schlüsselwörter zum Ändern des Zugriffs innerhalb der Klassendefinition neu anordnen, je nachdem, mit welchem Schlüsselwort Sie die Klasse deklariert haben.
Über die Syntax hinaus ist der einzige Grund, einen über den anderen zu wählen, Konvention / Stil / Präferenz.
Einige Leute halten sich gerne an das
struct
Schlüsselwort für Klassen ohne Elementfunktionen, da die resultierende Definition wie eine einfache Struktur aus C aussieht.In ähnlicher Weise verwenden einige Leute das
class
Schlüsselwort gerne für Klassen mit Elementfunktionen undprivate
Daten, da dort "Klasse" steht und daher wie Beispiele aus ihrem Lieblingsbuch über objektorientierte Programmierung aussieht.Die Realität ist, dass dies ganz bei Ihnen und Ihrem Team liegt und buchstäblich keinen Unterschied für Ihr Programm macht.
Die folgenden zwei Klassen sind bis auf ihren Namen in jeder Hinsicht absolut gleichwertig:
Sie können sogar Schlüsselwörter wechseln, wenn Sie neu deklarieren:
(Obwohl dies die Erstellung von Visual Studio-Builds aufgrund von Nichtkonformität unterbricht, gibt der Compiler dabei eine Warnung aus.)
und die folgenden Ausdrücke werden beide als wahr ausgewertet:
Beachten Sie jedoch, dass Sie die Schlüsselwörter bei der Neudefinition nicht wechseln können . Dies liegt nur daran, dass (gemäß der Ein-Definitions-Regel) doppelte Klassendefinitionen über Übersetzungseinheiten hinweg "aus derselben Folge von Token bestehen müssen" . Das heißt , Sie können nicht einmal austauschen
const int member;
mitint const member;
, und haben nichts mit der Semantik zu tunclass
oderstruct
.quelle
class foo { public: ... };
und eine anderestruct foo { ... };
, die gemäß der "absolut äquivalenten" Behauptung gelten müsste. Es liegt auf der Hand, dass die unvollständigen Erklärungenstruct foo;
undclass foo;
austauschbar sind. Diese geben den Klassenkörper nicht an und sprechen daher nichts für das Zugriffslayout.Foo
undBar
sind immer noch äquivalente / identische Typen. Ich habe darauf geachtet , "beim erneuten Deklarieren " zu sagen und ein Beispiel zu geben. Wenn ich darüber nachdenke, werde ich dies in der Antwort klarstellen, um sicherzustellen, dass ich die Leute nicht zu UBIch verwende eine Struktur nur anstelle einer Klasse, wenn ich einen Funktor deklariere, bevor ich ihn in einem Funktionsaufruf verwende, und aus Gründen der Übersichtlichkeit die Syntax minimieren möchte. z.B:
quelle
Aus dem C ++ FAQ Lite :
quelle
Ein Ort, an dem eine Struktur für mich hilfreich war, ist, wenn ich ein System habe, das Nachrichten mit festem Format (z. B. eine serielle Schnittstelle) von einem anderen System empfängt. Sie können den Bytestrom in eine Struktur umwandeln, die Ihre Felder definiert, und dann einfach auf die Felder zugreifen.
Natürlich ist dies das gleiche, was Sie in C tun würden, aber ich finde, dass sich der Aufwand, die Nachricht in eine Klasse dekodieren zu müssen, normalerweise nicht lohnt.
quelle
operator >>
eine Klasse implementieren, anstatt dieprocessMessage
Funktion zu schreiben , wodurch Ihr C ++ eher wie richtiges C ++ und weniger wie C aussieht.__packed__
Struktur verwenden und über eine endian-fähige ifdef-Implementierung verfügen (Sie müssen die Reihenfolge auf einem Computer umkehren, auf dem die Endianess der externen Datenquelle entgegengesetzt ist bietet). Es ist nicht schön, aber ich habe Register für Remote-Peripheriegeräte auf eingebetteten Plattformen auf tragbare Weise gepackt / entpackt.char
Typ ist, der vom Aliasing ausgenommen ist. Es gibt jedoch immer noch ein Problem, wenn auch ein anderes: Das Umwandeln eineschar*
in einen anderen Typ, wenn an dieser Adresse nicht wirklich ein Objekt des letzteren Typs bereits initialisiert wurde, ist UB, da es gegen die Lebensdauerregeln verstößt. Afaik, selbst wenn der Zieltyp trivial konstruierbar ist, reicht es für C ++ nicht aus, nur Speicher zuzuweisen, um diesen Speicher formal als diesen Typ zu behandeln.Sie können "struct" in C ++ verwenden, wenn Sie eine Bibliothek schreiben, deren Interna C ++ sind, die API jedoch entweder von C- oder C ++ - Code aufgerufen werden kann. Sie erstellen einfach einen einzelnen Header, der Strukturen und globale API-Funktionen enthält, die Sie sowohl C- als auch C ++ - Code wie folgt aussetzen:
Dann können Sie eine Funktionsleiste () in eine C ++ - Datei mit C ++ - Code schreiben und von C aus aufrufen, und die beiden Welten können Daten über die deklarierten Strukturen gemeinsam nutzen. Es gibt natürlich andere Einschränkungen beim Mischen von C und C ++, aber dies ist ein vereinfachtes Beispiel.
quelle
Wie jeder sagt, ist der einzige wirkliche Unterschied der Standardzugriff. Aber ich benutze struct besonders, wenn ich keine Kapselung mit einer einfachen Datenklasse möchte, selbst wenn ich einige Hilfsmethoden implementiere. Zum Beispiel, wenn ich so etwas brauche:
quelle
Um meine eigene Frage zu beantworten (schamlos): Wie bereits erwähnt, sind Zugriffsrechte der einzige Unterschied zwischen ihnen in C ++.
Ich neige dazu, eine Struktur nur zur Datenspeicherung zu verwenden. Ich werde zulassen, dass es einige Hilfsfunktionen erhält, wenn es die Arbeit mit den Daten erleichtert. Sobald die Daten jedoch eine Flusskontrolle erfordern (dh Getter / Setter, die einen internen Zustand beibehalten oder schützen) oder wichtige Funktionen erwerben (im Grunde genommen objektähnlicher), werden sie zu einer Klasse "aktualisiert", um die Absicht besser zu kommunizieren.
quelle
Strukturen ( PODs im Allgemeinen) sind praktisch, wenn Sie eine C-kompatible Schnittstelle mit einer C ++ - Implementierung bereitstellen, da sie über Sprachgrenzen und Linkerformate hinweg portierbar sind.
Wenn Ihnen das nichts ausmacht, ist die Verwendung von "struct" anstelle von "class" vermutlich ein guter Kommunikator der Absicht (wie @ZeroSignal oben sagte). Strukturen haben auch eine vorhersehbarere Kopiersemantik, sodass sie für Daten nützlich sind, die Sie auf externe Medien schreiben oder über das Kabel senden möchten.
Strukturen eignen sich auch für verschiedene Metaprogrammieraufgaben, z. B. für Vorlagen für Merkmale, die nur eine Reihe abhängiger Typedefs verfügbar machen:
... Aber das nutzt wirklich nur den Vorteil, dass die Standardschutzstufe von struct öffentlich ist ...
quelle
Für C ++ gibt es wirklich keinen großen Unterschied zwischen Strukturen und Klassen. Der Hauptfunktionsunterschied besteht darin, dass Mitglieder einer Struktur standardmäßig öffentlich sind, während sie in Klassen standardmäßig privat sind. Ansonsten sind sie sprachlich gleichwertig.
Trotzdem neige ich dazu, Strukturen in C ++ zu verwenden, wie ich es in C # tue, ähnlich wie Brian es gesagt hat. Strukturen sind einfache Datencontainer, während Klassen für Objekte verwendet werden, die auf die Daten einwirken müssen und nicht nur daran festhalten.
quelle
Sie sind so ziemlich dasselbe. Dank der Magie von C ++ kann eine Struktur Funktionen enthalten, Vererbung verwenden, mit "neu" erstellt werden usw. wie eine Klasse
Der einzige funktionale Unterschied besteht darin, dass eine Klasse mit privaten Zugriffsrechten beginnt, während eine Struktur mit öffentlichen beginnt. Dies ist die Aufrechterhaltung der Abwärtskompatibilität mit C.
In der Praxis habe ich immer Strukturen als Datenhalter und Klassen als Objekte verwendet.
quelle
Wie andere darauf hingewiesen haben
Es gibt eine klare Empfehlung, wann welche von Stroustrup / Sutter verwendet werden soll:
Beachten Sie jedoch, dass es nicht ratsam ist, etw. Weiterzuleiten. als Klasse (
class X;
) und definieren Sie es als struct (struct X { ... }
). Es kann auf einigen Linkern (z. B. g ++) funktionieren und auf anderen (z. B. MSVC) fehlschlagen, sodass Sie sich in der Entwicklerhölle befinden.quelle
class Foo; struct Foo { void bar() {} }; int main() { Foo().bar(); }
nicht nur mit MSVC 2017 kompiliert und ausgeführt, es erzeugt sogar eine eindeutige Warnung, dieFoo
als deklariert,struct
aber als definiert wurdeclass
. Aber ich erinnere mich auch deutlich daran, dass es unser Team einen halben Tag gekostet hat, diesen dummen Fehler zu finden. Ich bin mir nicht sicher, welche MSVC-Version wir damals verwendet haben.class
oder nichtstruct
, und die beiden sind gemäß dem Standard frei austauschbar (obwohl bekannt ist, dass VS warnt; ich habe immer angenommen, dass dies nur dazu dient, offensichtliche Programmiererfehler zu vermeiden). Hier riecht etwas nicht. Sind Sie sicher, dass es sich nicht um einen ODR-Verstoß handelt?struct
-vorwärts-class
vorwärts- ersetzt hatte, verschwanden die Probleme. Ab heute finde ich es auch seltsam. Ich würde mich freuen, wenn Sie etwas Licht ins Dunkel bringen könnten.Klasse.
Klassenmitglieder sind standardmäßig privat.
Ist äquivalent zu
Also, wenn Sie es versuchen
Wir werden eine Fehlermeldung erhalten:
main_one is private
weil es nicht zugänglich ist. Wir können es lösen, indem wir es initialisieren, indem wir es als öffentlich angeben, dhStruct.
Eine Struktur ist eine Klasse, in der Mitglieder standardmäßig öffentlich sind.
Mittel
main_one
ist privat dhIch verwende Strukturen für Datenstrukturen, in denen die Mitglieder einen beliebigen Wert annehmen können. Auf diese Weise ist es einfacher.
quelle
Ein Vorteil von
struct
overclass
ist, dass eine Codezeile gespeichert wird, wenn "zuerst öffentliche Mitglieder, dann private" verwendet werden. In diesem Licht finde ich das Schlüsselwortclass
nutzlos.Hier ist ein weiterer Grund, nur
struct
und nie zu verwendenclass
. Einige Richtlinien für den Codestil für C ++ schlagen vor, kleine Buchstaben für Funktionsmakros zu verwenden. Der Grund dafür ist, dass der Name bei der Konvertierung des Makros in eine Inline-Funktion nicht geändert werden muss. Hier gilt das gleiche. Sie haben Ihre schöne Struktur im C-Stil und eines Tages müssen Sie einen Konstruktor oder eine bequeme Methode hinzufügen. Ändern Sie es in einclass
? Überall?Die Unterscheidung zwischen
struct
s undclass
es ist einfach zu mühsam, um das zu tun, was wir tun sollten - das Programmieren. Wie so viele Probleme von C ++ entsteht es aus dem starken Wunsch nach Abwärtskompatibilität.quelle
class
? Haben Sie gedacht, dass eine mit demstruct
Schlüsselwort definierte Klasse keine Elementfunktionen oder keinen Konstruktor haben kann?joe()
muss mit einemclass
Schlüsselwort definiert werden . Jede Klasse mit mindestens 4int
Mitgliedern muss mit einemstruct
Schlüsselwort definiert werden ?struct
, Aggregate mit Methoden sind definiert mitclass
". Zu viel Aufwand.Sie sind dasselbe mit unterschiedlichen Standardeinstellungen (standardmäßig privat für
class
und öffentlich für standardmäßigstruct
), sodass sie theoretisch vollständig austauschbar sind.Wenn ich also nur einige Informationen packen möchte, um mich zu bewegen, verwende ich eine Struktur, auch wenn ich dort einige Methoden (aber nicht viele) eingefügt habe. Wenn es eine größtenteils undurchsichtige Sache ist, bei der die Hauptverwendung über Methoden und nicht direkt für die Datenelemente erfolgt, verwende ich eine vollständige Klasse.
quelle
Strukturen haben standardmäßig öffentlichen Zugriff und Klassen haben standardmäßig privaten Zugriff.
Persönlich verwende ich Strukturen für Datenübertragungsobjekte oder als Wertobjekte. Bei Verwendung als solche deklariere ich alle Mitglieder als const, um Änderungen durch anderen Code zu verhindern.
quelle
Beide
struct
undclass
sind unter der Haube gleich, obwohl diestruct
Standardeinstellungen für die Sichtbarkeit unterschiedlich sind. Die Standardeinstellung ist öffentlich und dieclass
Standardeinstellung ist privat. Sie können bei entsprechender Verwendung vonprivate
und eines der beiden ändern, um das andere zu seinpublic
. Beide erlauben Vererbung, Methoden, Konstruktoren, Destruktoren und alle anderen Extras einer objektorientierten Sprache.Ein großer Unterschied zwischen den beiden besteht jedoch darin, dass
struct
ein Schlüsselwort in C unterstützt wird, während diesclass
nicht der Fall ist. Dies bedeutet , dass man ein verwenden könnenstruct
in einer Include - Datei , die sein kann#include
entweder in C ++ oder C, solange dasstruct
ist eine einfache C - Stilstruct
und alles andere in der Include - Datei mit C kompatibel ist, dh keine C ++ bestimmte Schlüsselwörter wieprivate
,public
, nein Methoden, keine Vererbung usw. usw. usw.Der AC-Stil
struct
kann mit anderen Schnittstellen verwendet werden, die die Verwendung des C-Stils unterstützenstruct
, um Daten über die Schnittstelle hin und her zu übertragen.Der AC-Stil
struct
ist eine Art Vorlage (keine C ++ - Vorlage, sondern ein Muster oder eine Schablone), die das Layout eines Speicherbereichs beschreibt. Im Laufe der Jahre wurden Schnittstellen erstellt, die von C und mit C-Plug-Ins verwendet werden können (hier sehen Sie Java, Python und Visual Basic), von denen einige im C-Stil funktionierenstruct
.quelle
Technisch sind beide in C ++ gleich - zum Beispiel kann eine Struktur überladene Operatoren usw. haben.
Jedoch :
Ich verwende Strukturen, wenn ich Informationen mehrerer Typen gleichzeitig übergeben möchte. Ich verwende Klassen, wenn ich mich mit einem "funktionalen" Objekt befasse.
Ich hoffe es hilft.
Zum Beispiel gebe ich hier einen Strukturstudenten in den Methoden get ... () zurück - viel Spaß.
quelle
Ich benutze,
struct
wenn ichfunctors
und definierePOD
. Ansonsten benutze ichclass
.quelle
std::binary_function<>
ist nicht nur veraltet, c ++ 17 entfernt sie sogar.Ich verwende Strukturen, wenn ich einen POD-Typ oder einen Funktor erstellen muss.
quelle
Alle Klassenmitglieder sind standardmäßig privat und alle Strukturmitglieder sind standardmäßig öffentlich. Klasse hat standardmäßige private Basen und Struct hat standardmäßige öffentliche Basen. Struktur im Fall von C kann keine Elementfunktionen haben, während wie im Fall von C ++ Elementfunktionen zur Struktur hinzugefügt werden können. Abgesehen von diesen Unterschieden finde ich nichts Überraschendes an ihnen.
quelle
Ich verwende struct nur, wenn ich einige Daten ohne zugehörige Elementfunktionen speichern muss (um die Elementdaten zu bearbeiten) und direkt auf die Datenvariablen zugreifen kann.
Beispiel: Lesen / Schreiben von Daten aus Dateien und Socket-Streams usw. Übergeben von Funktionsargumenten in einer Struktur, in der die Funktionsargumente zu viele sind und die Funktionssyntax zu lang erscheint.
Technisch gesehen gibt es keinen großen Unterschied zwischen Klasse und Struktur, außer der Standardzugänglichkeit. Darüber hinaus hängt es vom Programmierstil ab, wie Sie es verwenden.
quelle
Ich dachte, dass Structs als Datenstruktur (wie ein Array von Informationen mit mehreren Datentypen) gedacht war und Klassen für Code Packaging (wie Sammlungen von Unterroutinen und Funktionen) vorgesehen waren.
:(
quelle
Ich benutze niemals "struct" in C ++.
Ich kann mir nie ein Szenario vorstellen, in dem Sie eine Struktur verwenden würden, wenn Sie private Mitglieder möchten, es sei denn, Sie versuchen absichtlich, verwirrend zu sein.
Es scheint, dass die Verwendung von Strukturen eher ein syntaktischer Hinweis darauf ist, wie die Daten verwendet werden, aber ich möchte lieber nur eine Klasse erstellen und versuchen, dies im Namen der Klasse oder durch Kommentare explizit zu machen.
Z.B
quelle
struct
ziemlich explizit zu deklarieren, dass die Mitglieder der Klasse standardmäßig öffentlich sind?