Struct vs. Class
Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy — Lektion 37 von 104.
In C++ sind struct und class nahezu identisch. Beide können Membervariablen, Memberfunktionen und Konstruktoren haben sowie Vererbung unterstützen. Der einzige Unterschied ist ihre Standard-Zugriffsebene.
In einer class sind Elemente standardmäßig privat. In einem struct sind Elemente standardmäßig öffentlich:
struct Point {
int x; // standardmäßig public
int y; // standardmäßig public
};
class Circle {
double radius; // standardmäßig private
public:
double getRadius() { return radius; }
};Dies gilt auch für die Vererbung. Ein struct erbt standardmäßig öffentlich, während eine class privat erbt:
struct DerivedStruct : Base {}; // öffentliche Vererbung
class DerivedClass : Base {}; // private VererbungAbgesehen von diesen Standardeinstellungen gibt es keinen technischen Unterschied. Dennoch spielen Konventionen eine Rolle.
Die meisten C++-Programmierer verwenden struct für einfache Datencontainer mit öffentlichen Membern (wie eine Koordinate oder Konfiguration) und class, wenn Kapselung und Verhalten wichtig sind. Das Befolgen dieser Konvention macht die Absicht Ihres Codes für andere Entwickler klarer.
Aufgabe
EinfachLassen Sie uns ein einfaches Konfigurationssystem erstellen, das zeigt, wann man struct gegenüber class basierend auf C++-Konventionen verwendet. Sie werden ein struct für einfache Daten erstellen, die offen zugänglich sein sollen, und eine class für Daten, die Kapselung und kontrollierten Zugriff erfordern.
Sie werden zwei Dateien erstellen, um Ihren Code zu organisieren:
Config.h: Definieren Sie sowohl ein Struct als auch eine Klasse, die verschiedene Arten von Konfigurationsdaten repräsentieren.Erstellen Sie zuerst ein
structnamensDimensions— ein einfacher Datencontainer für Breite und Höhe (beideint). Da Structs standardmäßig öffentliche Member haben, sollten diese ohne Getter direkt zugänglich sein. Fügen Sie eine Methodearea()hinzu, die das Produkt aus Breite und Höhe zurückgibt.Erstellen Sie dann eine
classnamensAppConfig, die Anwendungseinstellungen mit ordnungsgemäßer Kapselung verwaltet. Sie sollte einen App-Namen (String) und einDimensions-Objekt für die Fenstergröße speichern. Da Klassenmember standardmäßig privat sind, müssen Sie Ihre öffentliche Schnittstelle explizit zugänglich machen. Stellen Sie Folgendes bereit:- Einen Konstruktor, der den App-Namen, die Breite und die Höhe entgegennimmt
- Einen Getter
getAppName(), der den Namen zurückgibt - Einen Getter
getWindowSize(), der dieDimensionszurückgibt - Eine Methode
displayConfig(), die Folgendes ausgibt:"App: <name>, Window: <width>x<height>, Area: <area>"
main.cpp: Demonstrieren Sie den Unterschied zwischen der Verwendung von Struct und Klasse. Lesen Sie einen App-Namen, eine Breite und eine Höhe von der Eingabe ein (drei separate Zeilen) und führen Sie dann Folgendes aus:- Erstellen Sie ein
Dimensions-Struct direkt mit den Breiten- und Höhenwerten — greifen Sie direkt auf seine Member zu, um zu drucken:"Direct struct access: <width> x <height>" - Erstellen Sie ein
AppConfig-Objekt mit allen drei Werten - Rufen Sie
displayConfig()auf, um die vollständige Konfiguration anzuzeigen - Verwenden Sie den Getter, um die Fensterdimensionen abzurufen und zu drucken:
"Via getter - Area: <area>"
- Erstellen Sie ein
Diese Herausforderung hebt die Konvention hervor: Verwenden Sie struct, wenn Sie einfache, transparente Daten haben (wie Koordinaten oder Dimensionen), und verwenden Sie class, wenn Sie den Zugriff kontrollieren und Verhalten um Ihre Daten herum hinzufügen möchten.
Konvertieren Sie die Eingaben für Breite und Höhe mit std::stoi() von Strings in Integer. Vergessen Sie nicht die Header-Guards in Ihrer Header-Datei.
Spickzettel
In C++ sind struct und class fast identisch, mit einem entscheidenden Unterschied: ihrer Standard-Zugriffsebene.
In einem struct sind Member standardmäßig public:
struct Point {
int x; // standardmäßig public
int y; // standardmäßig public
};In einer class sind Member standardmäßig private:
class Circle {
double radius; // standardmäßig private
public:
double getRadius() { return radius; }
};Dies gilt auch für die Vererbung:
struct DerivedStruct : Base {}; // standardmäßig öffentliche Vererbung
class DerivedClass : Base {}; // standardmäßig private VererbungKonvention: Verwenden Sie struct für einfache Datencontainer mit öffentlichen Membern und class, wenn Kapselung und Verhalten wichtig sind.
Probier es selbst
#include <iostream>
#include <string>
#include "Config.h"
using namespace std;
int main() {
// Eingabe lesen
string appName;
string widthStr;
string heightStr;
getline(cin, appName);
getline(cin, widthStr);
getline(cin, heightStr);
int width = stoi(widthStr);
int height = stoi(heightStr);
// TODO: Erstelle ein Dimensions-Struct mit width und height
// Greife direkt auf seine Member zu, um Folgendes auszugeben: "Direct struct access: <width> x <height>"
// TODO: Erstelle ein AppConfig-Objekt mit appName, width und height
// TODO: Rufe displayConfig() für das AppConfig-Objekt auf
// TODO: Verwende den getWindowSize()-Getter, um die Dimensionen zu erhalten und auszugeben: "Via getter - Area: <area>"
return 0;
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienC++ Build & KompilierungHeader-Dateien & QuelldateienNamensräume & GültigkeitsbereicheEinführung in OOP in C++Klassen vs. ObjekteDer 'this'-PointerMethoden (Elementfunktionen)Attribute (Datenelemente)Grundlagen zu Ctors & DtorsRückblick - Einfacher Taschenrechner4Klasseneigenschaften
Instanz- vs. statische MemberGetter und SetterConst-MemberfunktionenMutable-SchlüsselwortStatische Methoden und VariablenFriend-Funktionen & KlassenZusammenfassung - Bankkonto-Manager7Vererbung
Grundlagen der VererbungZugriffsstufen bei VererbungAufrufreihenfolge von Ctor & DtorÜberschreiben von MethodenVirtuelle Funktionen & VTableMehrfachvererbungVirtuelle VererbungRückblick - Mitarbeiter-Hierarchie2Speicherverwaltung
Stack vs. Heap SpeicherZeiger und ReferenzenDynamischer Speicher (new/delete)Smart Pointers in C++RAII in C++Rückblick – Dynamischer Array-Manager5Kapselung
Zugriffsspezifizierer in C++Zugriffsspezifizierer im DetailInformation HidingStruct vs. ClassVerschachtelte & innere KlassenRückblick - Studentenverwaltungssystem8Polymorphie
Kompilierzeit- vs. Laufzeit-PolymorphieFunktionsüberladungVirtuelle Funktionen – WiederholungRein virtuelle FunktionenAbstrakte KlassenInterface-Design in C++Dynamic Casting & RTTIZusammenfassung – Formen-Rechner3Konstruktoren & Destruktoren
StandardkonstruktorParametrisierter KonstruktorKopierkonstruktorVerschiebekonstruktorKonstruktor-InitialisierungslistenDelegierende KonstruktorenDestruktoren im DetailRule of Three / Five / ZeroZusammenfassung - String-Klasse6Operatorüberladung
Einführung in die OperatorüberladungArithmetische OperatorüberladungVergleichsoperatorüberladungStream-OperatorenZuweisungsoperatorüberladungÜberladen der [] und () OperatorenTypumwandlungsoperatorenRückblick - Matrix-Klasse9Templates
FunktionstemplatesKlassentemplatesTemplate-SpezialisierungVariadische TemplatesSFINAE & Type Traits GrundlagenRückblick - Generische Container