Menu
Coddy logo textTech

Const-Memberfunktionen

Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy. Lektion 29 von 104.

Du hast das Schlüsselwort const bei Getter-Methoden in der vorherigen Lektion gesehen. Aber was bedeutet es genau, wenn const nach der Parameterliste einer Funktion erscheint? Eine const-Memberfunktion verspricht, keine Membervariablen des Objekts zu ändern.

class Rectangle {
    int width;
    int height;
public:
    Rectangle(int w, int h) : width(w), height(h) {}
    
    int getArea() const {      // const-Memberfunktion
        return width * height;  // Das Lesen von Membern ist erlaubt
    }
    
    void setWidth(int w) {     // Non-const - verändert das Objekt
        width = w;
    }
};

Das const nach der Parameterliste teilt dem Compiler mit: „Diese Funktion wird den Zustand des Objekts nicht ändern.“ Wenn du versuchst, eine Membervariable innerhalb einer const-Funktion zu ändern, wird der Compiler einen Fehler ausgeben.

Dies wird bei der Arbeit mit const-Objekten oder const-Referenzen unerlässlich. Ein const-Objekt kann nur const-Memberfunktionen aufrufen:

void printArea(const Rectangle& rect) {
    std::cout << rect.getArea();    // OK - getArea() ist const
    // rect.setWidth(10);           // FEHLER - setWidth() ist nicht const
}

Funktionen als const zu kennzeichnen, wenn sie das Objekt nicht verändern, ist eine gute Praxis. Dadurch wird deine Absicht dokumentiert, die Funktion kann mit const-Objekten arbeiten, und der Compiler kann versehentliche Änderungen erkennen. Jede Memberfunktion, die Daten nur liest, sollte als const gekennzeichnet werden.

challenge icon

Aufgabe

Einfach

Erstellen wir einen Temperaturkonverter, der zeigt, wann und warum const-Memberfunktionen verwendet werden. Du erstellst eine Klasse, deren einige Methoden Daten nur lesen (und const sein sollten), während andere den Zustand des Objekts ändern.

Du erstellst zwei Dateien, um deinen Code zu organisieren:

  • Temperature.h: Definiere eine Temperature-Klasse, die einen Temperaturwert speichert und verschiedene Möglichkeiten zum Lesen und Ändern dieses Werts bereitstellt. Deine Klasse sollte Folgendes enthalten:
    • Ein privates Member celsius (double) zum Speichern der Temperatur
    • Einen Konstruktor, der einen anfänglichen Celsius-Wert übernimmt
    • Eine getCelsius()-Methode, die den gespeicherten Wert zurückgibt. Sie sollte const sein, da sie nur Daten liest
    • Eine getFahrenheit()-Methode, die die Temperatur mithilfe der Formel celsius * 9.0 / 5.0 + 32.0 berechnet und zurückgibt; sie sollte ebenfalls const sein, da sie nichts ändert
    • Eine getKelvin()-Methode, die die Temperatur mithilfe von celsius + 273.15 in Kelvin zurückgibt: ebenfalls const
    • Eine setCelsius(double value)-Methode, die die gespeicherte Temperatur aktualisiert. Sie kann nicht const sein, da sie das Objekt ändert
    • Eine adjustBy(double delta)-Methode, die delta zur aktuellen Temperatur addiert; auch sie ist nicht const
  • main.cpp: Zeige, wie const-Memberfunktionen sowohl mit normalen als auch mit const-Objekten funktionieren. Lies zunächst einen Temperaturwert aus der Eingabe ein und:
    • Erstelle ein Temperature-Objekt mit dem Eingabewert
    • Gib "Initial: <celsius>C = <fahrenheit>F = <kelvin>K" aus
    • Verändere die Temperatur um 10.0 Grad
    • Gib "After adjustment: <celsius>C" aus
    • Erstelle eine Hilfsfunktion void printReadings(const Temperature& temp), die eine const-Referenz übernimmt und "Reading: <celsius>C, <fahrenheit>F" ausgibt. Diese Funktion kann für temp nur const-Methoden aufrufen
    • Rufe printReadings() mit deinem Temperaturobjekt auf
    • Setze die Temperatur auf 0.0 (Gefrierpunkt)
    • Gib "Freezing point: <celsius>C = <fahrenheit>F" aus

Formatiere alle Temperaturwerte mit einer Nachkommastelle mithilfe von std::fixed und std::setprecision(1) aus <iomanip>.

Die wichtigste Erkenntnis hier ist, dass printReadings() eine const-Referenz erhält und daher nur als const markierte Methoden aufrufen kann. Deshalb ist es wichtig, deine Getter-Methoden korrekt als const zu markieren. Dadurch können sie in Situationen verwendet werden, in denen das Objekt nicht geändert werden darf.

Probier es selbst

#include <iostream>
#include <iomanip>
#include "Temperature.h"
using namespace std;

// TODO: Implementiere die Methoden der Temperature-Klasse hier
// Konstruktor
Temperature::Temperature(double initialCelsius) {
    // TODO: Initialisiere celsius
}

// TODO: Implementiere getCelsius() als const

// TODO: Implementiere getFahrenheit() als const

// TODO: Implementiere getKelvin() als const

// TODO: Implementiere setCelsius(double value)

// TODO: Implementiere adjustBy(double delta)


// TODO: Erstelle eine Hilfsfunktion printReadings, die eine const Temperature& nimmt 
// und "Reading: <celsius>C, <fahrenheit>F" ausgibt
// Note: Diese Funktion kann nur const-Methoden auf temp aufrufen!


int main() {
    double initialTemp;
    cin >> initialTemp;

    // Ausgabeformatierung festlegen
    cout << fixed << setprecision(1);

    // TODO: Erstelle ein Temperature-Objekt mit dem Eingabewert

    // TODO: Gib "Initial: <celsius>C = <fahrenheit>F = <kelvin>K" aus

    // TODO: Passe die Temperatur um 10.0 Grad an

    // TODO: Print "After adjustment: <celsius>C"

    // TODO: Rufe printReadings() mit deinem Temperature-Objekt auf

    // TODO: Set the temperature to 0.0 (freezing point)

    // TODO: Print "Freezing point: <celsius>C = <fahrenheit>F"

    return 0;
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-C++-Compiler