Struct vs. Klasse
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 Mitgliedsvariablen, Elementfunktionen und Konstruktoren enthalten sowie Vererbung unterstützen. Der einzige Unterschied ist ihre standardmäßige Zugriffsebene.
In einer class sind Member standardmäßig privat. In einer struct sind Member 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 Vererbung. Eine Struktur erbt standardmäßig öffentlich, während eine Klasse privat erbt:
struct DerivedStruct : Base {}; // öffentliche Vererbung
class DerivedClass : Base {}; // private VererbungAbgesehen von diesen Standardeinstellungen gibt es keinen technischen Unterschied. Die Konvention ist jedoch wichtig.
Die meisten C++-Programmierer verwenden struct für einfache Datencontainer mit öffentlichen Mitgliedern (wie eine Koordinate oder eine Konfiguration) und class, wenn Kapselung und Verhalten wichtig sind. Wenn du dieser Konvention folgst, wird die Absicht deines Codes für andere Entwickler klarer.
Aufgabe
EinfachErstellen wir ein einfaches Konfigurationssystem, das anhand der C++-Konventionen demonstriert, wann struct und wann class verwendet werden sollte. Du erstellst eine struct für einfache Daten, die offen zugänglich sein sollen, und eine class für Daten, die Kapselung und kontrollierten Zugriff benötigen.
Du erstellst zwei Dateien, um deinen Code zu organisieren:
Config.h: Definiere sowohl eine Struct als auch eine Klasse, die unterschiedliche Arten von Konfigurationsdaten darstellen.Erstelle zunächst eine
structnamensDimensions: einen einfachen Datencontainer für Breite und Höhe (beidesint). Da Structs standardmäßig öffentliche Member haben, sollten diese ohne Getter direkt zugänglich sein. Füge eine Methodearea()hinzu, die das Produkt aus Breite und Höhe zurückgibt.Erstelle anschließend eine
classnamensAppConfig, die Anwendungseinstellungen mit ordnungsgemäßer Kapselung verwaltet. Sie soll einen Anwendungsnamen (Zeichenkette) und einDimensions-Objekt für die Fenstergröße speichern. Da Klassen-Member standardmäßig privat sind, musst du ihre öffentliche Schnittstelle explizit zugänglich machen. Stelle Folgendes bereit:- Einen Konstruktor, der den Anwendungsnamen, 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: Veranschauliche den Unterschied zwischen der Verwendung von Structs und Klassen. Lies einen Anwendungsnamen, eine Breite und eine Höhe aus der Eingabe ein (drei separate Zeilen), und führe dann Folgendes aus:- Erstelle direkt eine
Dimensions-Struct mit den Breiten- und Höhenwerten: Greife direkt auf ihre Member zu, um Folgendes auszugeben:"Direct struct access: <width> x <height>" - Erstelle ein
AppConfig-Objekt mit allen drei Werten - Rufe
displayConfig()auf, um die vollständige Konfiguration anzuzeigen - Verwende den Getter, um die Fensterabmessungen abzurufen, und gib Folgendes aus:
"Via getter - Area: <area>"
- Erstelle direkt eine
Diese Aufgabe verdeutlicht die Konvention: Verwende struct, wenn du einfache, transparente Daten hast (wie Koordinaten oder Abmessungen), und verwende class, wenn du den Zugriff kontrollieren und Verhalten zu deinen Daten hinzufügen möchtest.
Konvertiere die Eingaben für Breite und Höhe mit std::stoi() von Zeichenketten in Ganzzahlen. Vergiss die Include-Guards in deiner Header-Datei nicht.
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 eine Dimensions-Struktur mit width und height
// Access its members directly to print: "Direct struct access: <width> x <height>"
// TODO: Erstelle ein AppConfig-Objekt mit appName, width und height
// TODO: Rufe displayConfig() auf dem AppConfig-Objekt auf
// TODO: Use getWindowSize() getter to get dimensions and print: "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 & QuelldateienNamespaces & GültigkeitsbereichEinführung in OOP mit C++Klassen vs. ObjekteDer „this“-ZeigerMethoden (Member-Funktionen)Attribute (Datenmember)Grundlagen zu Ctors & DtorsRückblick – Einfacher Taschenrechner4Klassenattribute
Instanz- vs. statische MemberGetter und SetterConst-MemberfunktionenMutable-SchlüsselwortStatische Methoden und VariablenFriend-Funktionen und -KlassenZusammenfassung – Bankkontoverwaltung7Vererbung
Grundlagen der VererbungZugriffsebenen bei der VererbungAufrufreihenfolge von Ctor & DtorÜberschreiben von MethodenVirtuelle Funktionen & VTableMehrfachvererbungVirtuelle VererbungRückblick – Mitarbeiterhierarchie2Speicherverwaltung
Stack- vs. Heap-SpeicherZeiger und ReferenzenDynamischer Speicher (new/delete)Intelligente Zeiger in C++RAII in C++Rückblick – Dynamischer Array-Manager5Kapselung
Zugriffsbezeichner in C++Zugriffsbezeichner im DetailInformationsverbergungStruct vs. KlasseVerschachtelte und innere KlassenWiederholung – Studierendenverwaltungssystem8Polymorphie
Polymorphie zur Compilezeit vs. LaufzeitFunktionsüberladungVirtuelle Funktionen erneut betrachtetRein virtuelle FunktionenAbstrakte KlassenInterface-Design in C++Dynamic Casting & RTTIRückblick – Shape-Calculator3Konstruktoren & Destruktoren
StandardkonstruktorParametrisierter KonstruktorKopierkonstruktorMove-KonstruktorKonstruktor-InitialisierungslistenDelegierende KonstruktorenDestruktor im DetailDrei-/Fünf-/Null-RegelZusammenfassung – String-Klasse6Operatorüberladung
Einführung in die OperatorüberladungArithmetische OperatorüberladungVergleichsoperatorüberladungStream-OperatorenZuweisungsoperatorüberladungÜberladung der Operatoren [] und ()TypkonvertierungsoperatorenWiederholung – Matrix-Klasse9Templates
FunktionstemplatesKlassen-TemplatesTemplate-SpezialisierungVariadische TemplatesGrundlagen zu SFINAE und Type TraitsRückblick – Generischer ContainerÜbe selbstständig: Online-C++-Compiler