C / C ++ Struct vs Class

108

Nach Abschluss meiner C ++ - Klasse schien es mir, dass die Strukturen / Klassen bis auf ein paar kleine Unterschiede praktisch identisch sind.

Ich habe noch nie in C programmiert. aber ich weiß, dass es Strukturen hat. Ist es in C möglich, andere Strukturen zu erben und einen Modifikator für öffentlich / privat festzulegen?

Wenn Sie dies in regulärem C tun können, warum in aller Welt brauchen wir C ++? Was unterscheidet Klassen von einer Struktur?


quelle

Antworten:

146

In C ++ sind Strukturen und Klassen ziemlich gleich. Der einzige Unterschied besteht darin, dass Zugriffsmodifikatoren (für Mitgliedsvariablen, Methoden und Basisklassen) in Klassen standardmäßig privat und Zugriffsmodifikatoren in Strukturen standardmäßig öffentlich sind.

In C ist eine Struktur jedoch nur eine aggregierte Sammlung von (öffentlichen) Daten und weist keine anderen klassenähnlichen Merkmale auf: keine Methoden, kein Konstruktor, keine Basisklassen usw. Obwohl C ++ das Schlüsselwort geerbt hat, wurde die Semantik erweitert. (Dies ist jedoch der Grund, warum Dinge in Strukturen standardmäßig öffentlich sind - eine Struktur, die wie eine C-Struktur geschrieben wurde, verhält sich wie eine.)

Während es möglich ist, eine OOP in C zu fälschen - zum Beispiel Funktionen zu definieren, die alle einen Zeiger auf eine Struktur als ersten Parameter verwenden, oder gelegentlich Strukturen mit denselben ersten Feldern zu "Unter- / Oberklassen" zu zwingen -, ist dies immer eine Art angeschraubt und ist nicht wirklich Teil der Sprache.

Antal Spector-Zabusky
quelle
Aus OOP-Perspektive .Net-Leute haben es so definiert. ✓ Denken Sie daran, eine Struktur anstelle einer Klasse zu definieren, wenn Instanzen des Typs klein und häufig kurzlebig sind oder häufig in andere Objekte eingebettet sind. X Vermeiden Sie das Definieren einer Struktur, es sei denn, der Typ weist alle folgenden Merkmale auf: 1. Er stellt logisch einen einzelnen Wert dar, ähnlich den primitiven Typen (int, double usw.). 2. Es hat eine Instanzgröße unter 16 Bytes. 3. Es ist unveränderlich.
Abhijeet
5
@Abhijeet Das ist die Unterscheidung zwischen Strukturen und Klassen in C #, aber das ist für C ++ und noch mehr für C einfach irrelevant. In C # sind Klassen und Strukturen tatsächlich unterschiedlich. Nicht so in C ++, und C hat nur Strukturen ohne OO.
Antal Spector-Zabusky
Wäre es nicht besser, dieselbe C-Semantik in der C ++ - Struktur beizubehalten? und wenn es erforderlich ist, eine "Struktur in C ++" zu verwenden, verwenden Sie einfach eine Klasse? Ich habe nie den Vorteil gehabt, eine "erweiterte" Struktur in C ++ im Vergleich zu C zu haben. Ich verwende weiterhin gerne die Struktur, wie sie in C entworfen wurde, andernfalls verwende ich eine Klasse, mit einigen Ausnahmen, die zulässig sind.
Raffaello
15

Abgesehen von den Unterschieden beim Standardzugriff (öffentlich / privat) gibt es keinen Unterschied.

Einige Shops, die in C und C ++ codieren, verwenden jedoch "class / struct", um anzugeben, welche in C und C ++ (struct) verwendet werden können und welche nur C ++ (class) sind. Mit anderen Worten, in diesem Stil müssen alle Strukturen mit C und C ++ funktionieren. Aus diesem Grund gab es vor langer Zeit einen Unterschied, als C ++ noch als "C mit Klassen" bekannt war.

Beachten Sie, dass C-Gewerkschaften mit C ++ arbeiten, aber nicht umgekehrt. Beispielsweise

union WorksWithCppOnly{
    WorksWithCppOnly():a(0){}
    friend class FloatAccessor;
    int a;
private:
    float b;
};

Und ebenfalls

typedef union friend{
    int a;
    float b;
} class;

funktioniert nur in C.

Lance Diduck
quelle
9
Es ist ziemlich dumm, cpp-Schlüsselwörter in Ihrem c-Code zu verwenden und dann zu behaupten, dass es nicht cpp-kompatibel ist
Dani
7

Ich werde die vorhandenen Antworten ergänzen, da modernes C ++ jetzt eine Sache ist und offizielle Kernrichtlinien erstellt wurden, um bei Fragen wie diesen zu helfen.

Hier ist ein relevanter Abschnitt aus den Richtlinien:

C.2: Verwenden Sie die Klasse, wenn die Klasse eine Invariante hat. Verwenden Sie struct, wenn die Datenelemente unabhängig voneinander variieren können

Eine Invariante ist eine logische Bedingung für die Mitglieder eines Objekts, die ein Konstruktor festlegen muss, damit die Funktionen der öffentlichen Mitglieder sie übernehmen können. Nachdem die Invariante festgelegt wurde (normalerweise von einem Konstruktor), kann jede Elementfunktion für das Objekt aufgerufen werden. Eine Invariante kann informell (z. B. in einem Kommentar) oder formeller unter Verwendung von Expects angegeben werden.

Wenn alle Datenelemente unabhängig voneinander variieren können, ist keine Invariante möglich.

Wenn eine Klasse private Daten enthält, kann ein Benutzer ein Objekt ohne die Verwendung eines Konstruktors nicht vollständig initialisieren. Daher stellt der Klassendefinierer einen Konstruktor bereit und muss seine Bedeutung angeben. Dies bedeutet effektiv, dass der Definierer eine Invariante definieren muss.

Durchsetzung

Suchen Sie nach Strukturen mit allen privaten Daten und Klassen mit öffentlichen Mitgliedern.

Die angegebenen Codebeispiele:

struct Pair {  // the members can vary independently
    string name;
    int volume;
};

// but

class Date {
public:
    // validate that {yy, mm, dd} is a valid date and initialize
    Date(int yy, Month mm, char dd);
    // ...
private:
    int y;
    Month m;
    char d;    // day
};

ClassEs funktioniert gut für Mitglieder, die beispielsweise voneinander abgeleitet oder miteinander verbunden sind. Sie können auch bei der Überprüfung der geistigen Gesundheit nach der Instanziierung helfen. Structs eignen sich gut für "Datenbeutel", in denen nichts Besonderes vor sich geht, aber die Mitglieder logischerweise Sinn machen, wenn sie in Gruppen zusammengefasst werden.

Aus diesem Grund ist es sinnvoll, dass classes zur Unterstützung der Kapselung und anderer verwandter Codierungskonzepte existiert, für die structs einfach nicht sehr nützlich sind.

Dave
quelle
Eine weitere Überlegung ist die Portabilität. structs sind am tragbarsten. Sie können von C oder C ++ oder hin und her verwendet werden. Sie können beispielsweise auch mit dem structModul in Python entpackt werden . Wenn Ihr Projekt die Kompatibilität mit anderen Sprachen, Schnittstellen oder Systemen priorisiert, ziehen structSie es vor class. Für streng programminterne Angelegenheiten bevorzugen class.
Dave
6

In C ist es nicht möglich, Elementfunktionen zu definieren oder Strukturen voneinander abzuleiten.

Außerdem ist C ++ nicht nur C + "Strukturen ableiten". Vorlagen, Referenzen, benutzerdefinierte Namespaces und Operatorüberladungen sind in C nicht vorhanden.

Johannes Schaub - litb
quelle
Ich weiß, dass die Vorlagen usw. in C nicht vorhanden sind, aber mir waren die powerStrukturen in C nicht bekannt . Dann verwendet C ++ nur Strukturen, um mit C abwärtskompatibel zu sein?
4
Nur aus Gründen der Abwärtskompatibilität? Auf praktischer Basis ist wahrscheinlich etwas structdran , aber die Unterscheidung kann ein Signal der Absicht sein: Wenn ich ein benutze, meine ich ein weitgehend passives POD-Ding.
dmckee --- Ex-Moderator Kätzchen
@dmckee: Für das, was es wert ist, sind die meisten STL-Funktoren (dh std::less) als Strukturen definiert, nicht als Klassen.
Billy ONeal
1
C ++ ist nicht vollständig mit C kompatibel. Man könnte sagen, dass das Schlüsselwort struct eine Anpassung für C-Entwickler ist. Ich mag das Schlüsselwort struct für Klassen, die Daten nur in geordneter Weise enthalten, aber selbst nicht (viel) Logik liefern.
Ypnos
@ypnos: Siehe meinen letzten Kommentar. Der einzige Unterschied zwischen den beiden besteht darin, dass die Mitglieder standardmäßig öffentlich und die anderen standardmäßig privat sind.
Billy ONeal
3

Ein weiterer Unterschied in C ++: Wenn Sie eine Klasse von einer Struktur ohne Zugriffsspezifizierer erben, wird sie zur öffentlichen Vererbung, während es sich wie bei einer Klasse um eine private Vererbung handelt.

Mars Rover
quelle
1

C ++ verwendet Strukturen hauptsächlich für 1) Abwärtskompatibilität mit C und 2) POD-Typen. C-Strukturen haben keine Methoden, Vererbung oder Sichtbarkeit.

Chris Hafey
quelle
2
Für das, was es wert ist, werden die meisten STL-Funktoren (dh std::less) als Strukturen definiert, nicht als Klassen.
Billy ONeal
3
Beachten Sie, dass C ++ - Strukturen über Methoden, Vererbung und Sichtbarkeit verfügen.
Robertwb
c struct kann jedoch einen Funktionszeiger als Typ (* addr) (params) enthalten;
Fehler