Zugriffsspezifizierer in C++
Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy — Lektion 34 von 104.
C++ bietet drei Zugriffsspezifizierer, die steuern, wer auf Klassenmitglieder zugreifen kann: public, protected und private. Diese bilden die Grundlage der Kapselung.
class Account {
public:
std::string ownerName; // Von überall zugänglich
protected:
double interestRate; // Zugänglich in dieser Klasse und abgeleiteten Klassen
private:
double balance; // Nur innerhalb dieser Klasse zugänglich
};Auf Public-Member kann von überall zugegriffen werden – innerhalb der Klasse, von abgeleiteten Klassen und von externem Code. Private-Member sind am restriktivsten und nur innerhalb der Klasse selbst zugänglich. Protected liegt dazwischen – es verhält sich gegenüber der Außenwelt wie private, aber abgeleitete Klassen können auf diese Member zugreifen.
class Account {
private:
double balance;
public:
Account() : balance(0) {}
void deposit(double amount) {
balance += amount; // OK - innerhalb der Klasse
}
};
int main() {
Account acc;
acc.deposit(100); // OK - deposit ist public
// acc.balance = 500; // FEHLER - balance ist private
}Standardmäßig sind alle Member in einer Klasse privat, wenn kein Spezifizierer angegeben wird. Dies ermutigt Sie dazu, explizit zu entscheiden, was offengelegt werden soll. Die allgemeine Praxis besteht darin, Datenelemente privat zu machen und öffentliche Methoden bereitzustellen, um sicher mit ihnen zu interagieren.
Aufgabe
EinfachLassen Sie uns ein einfaches Mitarbeiterverwaltungssystem erstellen, das zeigt, wie Zugriffsspezifizierer steuern, wer auf was zugreifen kann. Sie werden eine Klasse erstellen, in der einige Daten vollständig privat sind, einige für potenzielle Unterklassen zugänglich sind und einige für jeden offen sind.
Sie werden zwei Dateien erstellen, um Ihren Code zu organisieren:
Employee.h: Definieren Sie eineEmployee-Klasse, die alle drei Zugriffsspezifizierer verwendet, um Daten angemessen zu schützen:- Öffentlich (Public): Der
name(string) des Mitarbeiters — dieser kann von überall aus aufgerufen werden - Geschützt (Protected): Die
department(string) des Mitarbeiters — zugänglich innerhalb der Klasse und durch abgeleitete Klassen, aber nicht von außen - Privat (Private): Das
salary(double) des Mitarbeiters — nur innerhalb der Klasse selbst zugänglich - Ein Konstruktor, der name, department und salary entgegennimmt, um alle drei Mitglieder zu initialisieren
- Eine öffentliche Methode
getSalary(), die den privaten salary-Wert zurückgibt - Eine öffentliche Methode
getDepartment(), die den geschützten department-Wert zurückgibt - Eine öffentliche Methode
giveRaise(double amount), die das Gehalt um den angegebenen Betrag erhöht (nur wenn der Betrag positiv ist) - Eine öffentliche Methode
displayInfo(), welche die Informationen des Mitarbeiters im folgenden Format ausgibt:"Name: <name>, Department: <department>, Salary: "Name: <name>, Department: <department>, Salary: $<salary>"lt;salary>"
- Öffentlich (Public): Der
main.cpp: Demonstrieren Sie die Funktionsweise von Zugriffsspezifizierern, indem Sie mit einem Employee-Objekt interagieren. Lesen Sie den Namen, die Abteilung und das Gehalt eines Mitarbeiters aus der Eingabe (drei separate Zeilen) und führen Sie dann Folgendes aus:- Erstellen Sie einen
Employeemit den Eingabewerten - Geben Sie den Namen des Mitarbeiters direkt aus, indem Sie auf das öffentliche Mitglied zugreifen:
"Direct access - Name: <name>" - Geben Sie die Abteilung über den Getter aus:
"Via getter - Department: <department>" - Geben Sie das Gehalt über den Getter aus:
"Via getter - Salary: "Via getter - Salary: $<salary>"lt;salary>" - Geben Sie dem Mitarbeiter eine Gehaltserhöhung von
5000.0 - Geben Sie
"After raise:"aus - Rufen Sie
displayInfo()auf, um die aktualisierten Informationen anzuzeigen
- Erstellen Sie einen
Formatieren Sie alle Gehaltswerte mit zwei Dezimalstellen unter Verwendung von std::fixed und std::setprecision(2) aus <iomanip>. Konvertieren Sie die Gehaltseingabe mit std::stod() von einem String in einen Double-Wert.
Die wichtigste Erkenntnis hierbei ist, dass Sie zwar direkt von main aus auf name zugreifen können, aber nicht direkt auf department oder salary — Sie müssen die öffentlichen Getter-Methoden verwenden. Dies ist Kapselung in Aktion: Die Klasse kontrolliert, wie auf ihre Daten zugegriffen wird und wie diese geändert werden.
Spickzettel
C++ bietet drei Zugriffsspezifizierer, um den Zugriff auf Klassenmitglieder zu steuern:
- public: Von überall zugänglich
- protected: Innerhalb der Klasse und abgeleiteter Klassen zugänglich
- private: Nur innerhalb der Klasse selbst zugänglich
class Account {
public:
std::string ownerName; // Von überall zugänglich
protected:
double interestRate; // In dieser Klasse und abgeleiteten Klassen zugänglich
private:
double balance; // Nur innerhalb dieser Klasse zugänglich
};Standardmäßig sind alle Mitglieder in einer Klasse private, wenn kein Spezifizierer angegeben ist.
Beispiel zur Demonstration der Zugriffskontrolle:
class Account {
private:
double balance;
public:
Account() : balance(0) {}
void deposit(double amount) {
balance += amount; // OK - innerhalb der Klasse
}
};
int main() {
Account acc;
acc.deposit(100); // OK - deposit ist public
// acc.balance = 500; // FEHLER - balance ist private
}Best Practice: Machen Sie Datenelemente privat und stellen Sie öffentliche Methoden bereit, um sicher mit ihnen zu interagieren.
Probier es selbst
#include <iostream>
#include <string>
#include <iomanip>
#include "Employee.h"
using namespace std;
int main() {
// Eingabe lesen
string name;
string department;
string salaryStr;
getline(cin, name);
getline(cin, department);
getline(cin, salaryStr);
double salary = stod(salaryStr);
// Präzision für die Gehaltsausgabe festlegen
cout << fixed << setprecision(2);
// TODO: Ein Employee-Objekt mit den Eingabewerten erstellen
// TODO: Den Namen des Mitarbeiters durch direkten Zugriff auf das öffentliche Member ausgeben
// Format: "Direct access - Name: <name>"
// TODO: Die Abteilung mit der Getter-Methode ausgeben
// Format: "Via getter - Department: <department>"
// TODO: Das Gehalt mit der Getter-Methode ausgeben
// Format: "Via getter - Salary: $<salary>"
// TODO: Dem Mitarbeiter eine Gehaltserhöhung von 5000.0 geben
// TODO: "After raise:" ausgeben
// TODO: displayInfo() aufrufen, um die aktualisierten Informationen anzuzeigen
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