C ++: Kann eine Struktur von einer Klasse erben?

70

Ich betrachte die Implementierung einer API, die ich verwende.

Ich bemerkte, dass eine Struktur von einer Klasse erbt und machte eine Pause, um darüber nachzudenken ...

Erstens habe ich in dem C ++ - Handbuch, mit dem ich studiert habe, nicht gesehen, dass eine Struktur von einer anderen Struktur erben kann:

struct A {};
struct B : public A {};

Ich vermute, dass in einem solchen Fall Struktur B von allen Daten in Struktur A erbt. Können wir öffentliche / private Mitglieder in einer Struktur deklarieren?

Aber ich habe Folgendes bemerkt:

 class A {};
 struct B : public A {};  

Aus meinem Online-C ++ - Handbuch:

Eine Klasse ist ein erweitertes Konzept einer Datenstruktur: Anstatt nur Daten zu speichern, kann sie sowohl Daten als auch Funktionen enthalten.

Ist die obige Vererbung auch dann gültig, wenn Klasse A einige Mitgliedsfunktionen hat? Was passiert mit den Funktionen, wenn eine Struktur sie erbt? Und was ist mit dem Gegenteil: eine Klasse, die von einer Struktur erbt?

Praktisch habe ich folgendes:

struct user_messages {
  std::list<std::string> messages;
};

Und ich habe es immer so durchlaufen foreach message in user_messages.messages.

Wenn ich meiner Struktur Elementfunktionen hinzufügen möchte, kann ich die Deklaration ändern und zu einer Klasse "heraufstufen", Funktionen hinzufügen und trotzdem wie zuvor über meine user_messages.messages iterieren?

Offensichtlich bin ich immer noch ein Neuling und mir ist immer noch unklar, wie Strukturen und Klassen miteinander interagieren, was der praktische Unterschied zwischen den beiden ist und welche Vererbungsregeln gelten ...

Augustin
quelle
1
stackoverflow.com/questions/577465/… Sieht aus wie ein Duplikat dieser Frage
ckv
befindet sich die for_each-Schleife innerhalb der Klasse / Struktur oder außerhalb?
Chubsdad
@chubsdad Es ist draußen. Eine HTML-Vorlage geht rekursiv über die messages.messages, um sie als HTML zu rendern.
augustin
1
@augustin: Mein anfängliches Gefühl ist es, ein "Iterator" -Designmuster für die "Nachrichten" -Klasse bereitzustellen, anstatt die "Nachrichten" des Mitglieds öffentlich zu machen.
Chubsdad
1
@augustin: Obwohl im Moment nicht verwandt, haben die Schlüsselwörter 'struct' und 'class' einen kleinen Unterschied. Das Schlüsselwort 'Klasse' kann mit Vorlagen verwendet werden, aber nicht das Schlüsselwort 'Struktur', um Typparameter zu definieren
Chubsdad

Antworten:

112

Ja, struct kann von der Klasse in C ++ erben.

In C ++ sind Klassen und Struktur bis auf ihr Standardverhalten in Bezug auf Vererbung und Zugriffsebenen von Mitgliedern identisch .

C ++ - Klasse

  • Standardvererbung = privat
  • Standardzugriffsebene für Mitgliedsvariablen und Funktionen = privat

C ++ struct

  • Standardvererbung = öffentlich
  • Standardzugriffsebene für Mitgliedsvariablen und Funktionen = public
Vite Falcon
quelle
Vielen Dank. Das ist klar. Bedeutet dies, dass eine Struktur auch Elementfunktionen haben kann, einschließlich eines Konstruktors, und dass wir eine neue Instanz wie für eine Klasse erstellen können: <code> myObject = new myStruct (myVar) <code>?
augustin
8
Ja. Alles, was für eine Klasse gültig ist, gilt für eine Struktur. Sie sind absolut identisch, mit Ausnahme der oben angegebenen Zugriffsmodifikatoren. Es gibt keine Grenzen für das Mischen oder irgendetwas.
Welpe
@DeadMG: Danke. Das ist klar. Ich hatte nach Duplikaten gesucht und sie nicht gefunden. Ich bin immer noch froh, dass ich gefragt habe. Vielen Dank.
augustin
3
Sie können eine Struktur sogar als Klasse weiterleiten und umgekehrt, aber Visual C ++ drosselt dies unter bestimmten Bedingungen.
Fabio Fracassi
3
Ich verwende immer noch Strukturen für reine Daten und Klassen, wenn Elementfunktionen benötigt werden, obwohl sie gleich sind. Kraft der Gewohnheit.
Alexander Rafferty
40

In C ++

struct A { /* some fields/methods ... */ };

ist äquivalent zu:

class A { public: /* some fields/methods ... */ };

Und

class A { /* some fields/methods ... */ };

ist äquivalent zu:

struct A { private: /* some fields/methods ... */ };

Das bedeutet, dass die Mitglieder einer Struktur / Klasse standardmäßig öffentlich / privat sind .

Unter Verwendung structauch ändert die Standard Vererbung auf public, dh

struct A { }; // or: class A { };
class B : A { };

ist äquivalent zu

struct A { }; // or: class  A { };
struct B : private A { };

Und umgekehrt

struct A { }; // or: class A { };
struct B : A { };

ist äquivalent zu:

struct A { }; // or: class A { };
class B : public A { };

Zusammenfassung: Ja, a structkann von einer Klasse erben. Der Unterschied zwischen den Schlüsselwörtern classund structist nur eine Änderung der privaten / öffentlichen Standardspezifizierer.

maxschlepzig
quelle
1
Dies sollte wirklich die gewählte Antwort sein! Sehr deutlich.
Nathanesau
1
Die Beispiele für die Barrierefreiheit bei der Vererbung sind falsch. struct A{}; class B : A{};ist äquivalent zu class A{}; class B : private A {};. Die Zugänglichkeit der Basis wird durch das abgeleitete Wesen bestimmt classoder structnicht durch das Basiswesen classoder struct.
Eljay
1
@ Eljay, du hast recht, ich hatte die Beispiele verwechselt. Ich habe gerade meine Antwort aktualisiert.
Maxschlepzig
7

Der einzige Unterschied zwischen einer Struktur und einer Klasse besteht in der Standardzugriffsebene für Mitglieder (privat für Klassen, öffentlich für Strukturen). Dies bedeutet, dass eine Struktur von einer Klasse erben kann und umgekehrt.

In der Regel gibt es jedoch einen Unterschied in der Verwendung von Strukturen und Klassen, der nicht vom Standard vorgeschrieben wird. Strukturen werden häufig für reine Daten verwendet (oder Objekte ohne Polymorphismus, abhängig von Ihren Projektpräferenzen), und Klassen werden für die anderen Fälle verwendet. Ich betone, dass dies nur ein stilistischer Unterschied ist und nicht erforderlich ist.

Michael Anderson
quelle
6

Das Wichtigste ist, dass Strukturen aus C stammen, während Klassen C ++ sind. Dies bedeutet, dass Strukturen zwar erstklassige objektorientierte Bürger sind, aber auch einen alten Zweck haben. Dies ist der Grund dafür, dass Klassen getrennt sind und Strukturen öffentlich zugänglich sind. Sobald dies erledigt ist, sind sie jedoch absolut identisch und in jeder Hinsicht austauschbar.

Hündchen
quelle
5

Eine Struktur ist dasselbe wie eine Klasse, außer dass eine Klasse ihre Mitglieder standardmäßig auf privat setzt, während eine Struktur ihre Mitglieder standardmäßig auf öffentlich setzt. Infolgedessen können Sie ja zwischen den beiden erben. Siehe in C ++, kann ich eine Klasse aus einer Struktur ableiten .

MBennett
quelle
4

Struktur und Klasse sind ziemlich austauschbar - nur mit unterschiedlichen Standardeinstellungen in diesen Klassen, die standardmäßig auf private Vererbung und Mitglieder, Strukturen auf öffentlich eingestellt sind. Das Schlüsselwort class (und nicht struct) muss z. "Vorlage <Klasse T>".

Trotzdem verwenden viele Programmierer die beiden, um einem Programmierer, der den Code liest, einen kleinen Vorschlag zu machen: Wenn Sie eine Struktur verwenden, schlagen Sie subtil ein weniger einkapselndes OO-Design vor. Eine Struktur kann innerhalb einer Bibliothek verwendet werden - wo es ein faires Spiel ist, den Mut zu haben, während Klassen an der Grenze verwendet werden, an der API-Änderungen Clients stören und eine bessere Abstraktion nützlich sind. Diese sehr lockere Konvention ist aus dem Unterschied in der Standardzugänglichkeit hervorgegangen - faule / effiziente / prägnante (treffen Sie Ihre Wahl) Programmierer tun das Einfachste, es sei denn, es gibt einen anderen Vorteil, und wenn möglich, ist es hilfreich, keine Zugriffsspezifizierer einzugeben.

Tony Delroy
quelle
4

Ja, eine structDose kann von einer Klasse erben. structund classunterscheiden sich nur in dem Zugriffsspezifizierer, der für die Mitglieder und für eine Basisklasse (oder Strukturen) angenommen wird, wenn dies nicht explizit in C ++ angegeben ist. Für Strukturen ist es public. Für Klassen ist es private.

Der Satz, den Sie aus dem Handbuch zitieren, bezieht sich auf das Konzept einer Klasse in C ++ im Vergleich zum Konzept einer Datenstruktur in C. In C ++ wurde ein neues Schlüsselwort classeingeführt, um die Änderung des Konzepts besser widerzuspiegeln, jedoch aus Gründen der Kompatibilität mit Code In C wurde ein altes Schlüsselwort structhinterlassen, dessen Bedeutung wie oben beschrieben ist.

Maciej Hehl
quelle
4

Ja. Struct kann von einer Klasse erben und umgekehrt. Die Barrierefreiheitsregel lautet

$ 11.2 / 2- "Wenn kein Zugriffsspezifizierer für eine Basisklasse vorhanden ist, wird public angenommen, wenn die abgeleitete Klasse als struct deklariert wird, und private wird angenommen, wenn die Klasse als class deklariert wird."

EDIT 2: So können Sie Ihre Klasse ändern als:. Beachten Sie, dass es normalerweise eine schlechte Idee ist, Mitglieder für öffentliche Daten zu haben.

class user_messages {  // i also changed the name when OP was modified :)
public:   
   std::list<std::string> messages;  
};
Chubsdad
quelle
1

Eine Klasse erbt nicht öffentlich von einer Struktur. Eine Struktur erbt öffentlich von einer Klasse oder einer Struktur.

class A
{
public:
    int a;
};
struct B : A
{};

B b; ba = 5; //IN ORDNUNG. a ist zugänglich

class A
{
public:
    int a;
};
struct B : public A
{};

Es bedeutet dasselbe. B b; ba = 5; //IN ORDNUNG. a ist zugänglich

struct A
{int a;};
class B : A
{};

B b; ba = 5; //NICHT OK. a ist NICHT zugänglich

struct A
{int a;};
class B : public A
{};

B b; ba = 5; //IN ORDNUNG. a ist zugänglich

Schließlich:

class A
{int a;};
class B : A
{};

B b; ba = 5; //NICHT OK. a ist NICHT zugänglich

class A
{int a;};
class B : public A
{};

B b; ba = 5; //NICHT OK. a ist NICHT zugänglich

Domonkos Tóth-Lőrincz
quelle