Menu
Coddy logo textTech

Funciones miembro const

Parte de la sección Programación Orientada a Objetos del Journey de C++ de Coddy — lección 29 de 104.

Has visto la palabra clave const en los métodos getter en la lección anterior. Pero, ¿qué significa exactamente cuando const aparece después de la lista de parámetros de una función? Una función miembro const promete no modificar ninguna variable miembro del objeto.

class Rectangle {
    int width;
    int height;
public:
    Rectangle(int w, int h) : width(w), height(h) {}
    
    int getArea() const {      // función miembro constante
        return width * height;  // Se permite la lectura de miembros
    }
    
    void setWidth(int w) {     // No const - modifica el objeto
        width = w;
    }
};

El const después de la lista de parámetros le dice al compilador: "Esta función no cambiará el estado del objeto." Si intentas modificar una variable miembro dentro de una función const, el compilador producirá un error.

Esto se vuelve esencial al trabajar con objetos const o referencias const. Un objeto const solo puede llamar a funciones miembro const:

void printArea(const Rectangle& rect) {
    std::cout << rect.getArea();    // OK - getArea() es const
    // rect.setWidth(10);           // ERROR - setWidth() no es const
}

Marcar las funciones como const cuando no modifican el objeto es una buena práctica. Documenta tu intención, permite que la función trabaje con objetos const y ayuda al compilador a detectar modificaciones accidentales. Cualquier función miembro que solo lea datos debería marcarse como const.

challenge icon

Desafío

Fácil

Construyamos un convertidor de temperatura que demuestre cuándo y por qué usar funciones miembro const. Crearás una clase donde algunos métodos solo leen datos (y deben ser const) mientras que otros modifican el estado del objeto.

Crearás dos archivos para organizar tu código:

  • Temperature.h: Define una clase Temperature que almacena un valor de temperatura y proporciona varias formas de leerlo y modificarlo. Tu clase debe tener:
    • Un miembro privado celsius (double) para almacenar la temperatura
    • Un constructor que toma un valor inicial en Celsius
    • Un método getCelsius() que devuelve el valor almacenado — este debe ser const ya que solo lee datos
    • Un método getFahrenheit() que calcula y devuelve la temperatura en Fahrenheit usando la fórmula celsius * 9.0 / 5.0 + 32.0 — también const ya que no modifica nada
    • Un método getKelvin() que devuelve la temperatura en Kelvin usando celsius + 273.15 — const también
    • Un método setCelsius(double value) que actualiza la temperatura almacenada — este no puede ser const ya que modifica el objeto
    • Un método adjustBy(double delta) que suma el delta a la temperatura actual — también non-const
  • main.cpp: Demuestra cómo funcionan las funciones miembro const tanto con objetos regulares como con objetos const. Lee un valor de temperatura inicial de la entrada, luego:
    • Crea un objeto Temperature con el valor de entrada
    • Imprime "Initial: <celsius>C = <fahrenheit>F = <kelvin>K"
    • Ajusta la temperatura por 10.0 grados
    • Imprime "After adjustment: <celsius>C"
    • Crea una función auxiliar void printReadings(const Temperature& temp) que toma una referencia const e imprime "Reading: <celsius>C, <fahrenheit>F" — esta función solo puede llamar a métodos const en temp
    • Llama a printReadings() con tu objeto de temperatura
    • Establece la temperatura a 0.0 (punto de congelación)
    • Imprime "Freezing point: <celsius>C = <fahrenheit>F"

Formatea todos los valores de temperatura con un decimal usando std::fixed y std::setprecision(1) de <iomanip>.

La idea clave aquí es que printReadings() recibe una referencia const, por lo que solo puede llamar a métodos marcados como const. Es por esto que marcar correctamente tus métodos getter como const es importante — permite que funcionen en contextos donde el objeto no puede ser modificado.

Hoja de referencia

Una función miembro const promete no modificar ninguna variable miembro del objeto. La palabra clave const se coloca después de la lista de parámetros de la función:

class Rectangle {
    int width;
    int height;
public:
    int getArea() const {      // función miembro const
        return width * height;  // Se permite leer miembros
    }
    
    void setWidth(int w) {     // No-const - modifica el objeto
        width = w;
    }
};

Las funciones miembro const solo pueden leer variables miembro, no modificarlas. Si intentas modificar una variable miembro dentro de una función const, el compilador producirá un error.

Un objeto const o una referencia const solo puede llamar a funciones miembro const:

void printArea(const Rectangle& rect) {
    std::cout << rect.getArea();    // OK - getArea() es const
    // rect.setWidth(10);           // ERROR - setWidth() no es const
}

Marca las funciones como const cuando no modifiquen el objeto. Esto documenta tu intención, permite que la función trabaje con objetos const y ayuda al compilador a detectar modificaciones accidentales. Cualquier función miembro que solo lea datos debe marcarse como const.

Pruébalo tú mismo

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

// TODO: Implementar los métodos de la clase Temperature aquí
// Constructor
Temperature::Temperature(double initialCelsius) {
    // TODO: Inicializar celsius
}

// TODO: Implementar getCelsius() como const

// TODO: Implementar getFahrenheit() como const

// TODO: Implementar getKelvin() como const

// TODO: Implementar setCelsius(double value)

// TODO: Implementar adjustBy(double delta)


// TODO: Crear una función auxiliar printReadings que reciba un const Temperature& 
// y que imprima "Reading: <celsius>C, <fahrenheit>F"
// Note: ¡Esta función solo puede llamar a métodos const en temp!


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

    // Configurar el formato de salida
    cout << fixed << setprecision(1);

    // TODO: Crear un objeto Temperature con el valor de entrada

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

    // TODO: Ajustar la temperatura en 10.0 grados

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

    // TODO: Llamar a printReadings() con tu objeto de temperatura

    // TODO: Establecer la temperatura a 0.0 (punto de congelación)

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

    return 0;
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos