Getters y Setters
Parte de la sección Programación Orientada a Objetos del Journey de C++ de Coddy — lección 28 de 104.
Cuando los miembros de una clase son privados, el código externo no puede acceder a ellos directamente. Los getters y setters son métodos públicos que proporcionan acceso controlado a estos miembros privados: los getters recuperan valores y los setters los modifican.
class Temperature {
double celsius; // Privado - no se puede acceder directamente
public:
// Getter - devuelve el valor
double getCelsius() const {
return celsius;
}
// Setter - modifica el valor con validación
void setCelsius(double value) {
if (value >= -273.15) { // Comprobación de cero absoluto
celsius = value;
}
}
};El verdadero poder de los setters es la validación.
En lugar de permitir que se asigne cualquier valor, puedes aplicar reglas. En el ejemplo anterior, se rechazan las temperaturas por debajo del cero absoluto. Sin un setter, cualquiera podría asignar datos no válidos directamente.
Los getters también pueden transformar los datos antes de devolverlos:
class Temperature {
double celsius;
public:
double getCelsius() const { return celsius; }
// Getter calculado - no almacena fahrenheit, lo calcula
double getFahrenheit() const {
return celsius * 9.0 / 5.0 + 32.0;
}
void setCelsius(double value) { celsius = value; }
};Observa la palabra clave const en los getters: esto indica que no modifican el objeto. Los setters no pueden ser const, ya que su propósito es cambiar los valores de los miembros. Este patrón de uso de getters y setters es fundamental para el encapsulamiento, brindándote un control total sobre cómo se accede y se modifican los datos de tu clase.
Desafío
FácilVamos a construir un sistema de perfil de jugador que demuestre cómo los getters y setters proporcionan un acceso controlado a los datos privados, incluyendo la validación y las propiedades calculadas.
Crearás dos archivos para organizar tu código:
Player.h: Define una clasePlayerque gestione el perfil de un personaje de juego con acceso protegido a los datos. Tu clase debe tener:- Miembros privados:
name(string),level(int), yexperience(int) - Un constructor que reciba un nombre e inicialice
levela1yexperiencea0 - Un getter
getName()que devuelva el nombre del jugador - Un getter
getLevel()que devuelva el nivel actual - Un getter
getExperience()que devuelva los puntos de experiencia actuales - Un setter
setName()que solo acepte nombres con al menos 3 caracteres — si no es válido, mantén el nombre actual sin cambios - Un setter
addExperience(int points)que solo acepte valores positivos. Cuando la experiencia alcance o supere100, el jugador sube de nivel: incrementa el nivel en 1 y resta 100 de la experiencia. Esto puede suceder varias veces si se añade suficiente experiencia. - Un getter calculado
getExperienceToNextLevel()que devuelva cuántos puntos de experiencia más se necesitan para alcanzar el siguiente nivel (siempre100 - current experience)
Marca todos los getters como
constya que no modifican el objeto.- Miembros privados:
main.cpp: Demuestra tus getters y setters en acción. Lee un nombre de jugador y los puntos de experiencia a añadir desde la entrada (cada uno en una línea separada), luego:- Crea un
Playercon el nombre de entrada - Imprime
"Player: <name>, Level: <level>, XP: <experience>" - Añade los puntos de experiencia de entrada usando
addExperience() - Imprime la misma línea de estado de nuevo para mostrar el estado actualizado
- Imprime
"XP to next level: <amount>" - Intenta cambiar el nombre a
"Al"(debería fallar la validación) - Imprime
"Name after invalid change: <name>" - Cambia el nombre a
"Champion"(debería tener éxito) - Imprime
"Name after valid change: <name>"
- Crea un
La entrada de experiencia se proporcionará como una cadena que deberás convertir a un entero. Incluye tu archivo de cabecera en main.cpp usando #include "Player.h".
Hoja de referencia
Los getters y setters son métodos públicos que proporcionan acceso controlado a los miembros privados de una clase.
Patrón básico de getter y setter:
class Temperature {
double celsius; // Miembro privado
public:
// Getter - devuelve el valor (marcado como const)
double getCelsius() const {
return celsius;
}
// Setter - modifica el valor
void setCelsius(double value) {
celsius = value;
}
};Setters con validación:
void setCelsius(double value) {
if (value >= -273.15) { // Validar antes de asignar
celsius = value;
}
}Getters calculados:
// Devuelve un valor calculado sin almacenarlo
double getFahrenheit() const {
return celsius * 9.0 / 5.0 + 32.0;
}Puntos clave:
- Los getters deben marcarse como
constya que no modifican el objeto - Los setters no pueden ser
constporque cambian los valores de los miembros - Los setters permiten la validación para prevenir datos inválidos
- Los getters pueden transformar o calcular valores antes de devolverlos
Pruébalo tú mismo
#include <iostream>
#include <string>
#include "Player.h"
using namespace std;
int main() {
// Leer el nombre del jugador
string playerName;
getline(cin, playerName);
// Leer los puntos de experiencia a añadir (como string, convertir a int)
string expString;
getline(cin, expString);
int expToAdd = stoi(expString);
// TODO: Crear un Player con el nombre de entrada
// TODO: Imprimir el estado inicial: "Player: <name>, Level: <level>, XP: <experience>"
// TODO: Añadir los puntos de experiencia de entrada usando addExperience()
// TODO: Imprimir la línea de estado actualizada
// TODO: Imprimir "XP to next level: <amount>"
// TODO: Intentar cambiar el nombre a "Al" (debería fallar la validación)
// TODO: Imprimir "Name after invalid change: <name>"
// TODO: Cambiar el nombre a "Champion" (debería tener éxito)
// TODO: Imprimir "Name after valid change: <name>"
return 0;
}
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
1Fundamentos de OOP
Archivos externosConstrucción y compilación en C++Archivos de cabecera y archivos fuenteNamespaces y alcanceIntroducción a OOP en C++Clases vs ObjetosEl puntero 'this'Métodos (Funciones miembro)Atributos (Miembros de datos)Conceptos básicos de Ctors y DtorsResumen - Calculadora simple4Propiedades de clase
Miembros de instancia vs. estáticosGetters y SettersFunciones miembro constPalabra clave mutableMétodos y variables estáticosFunciones y clases amigasResumen - Gestor de cuentas bancarias7Herencia
Herencia básicaNiveles de acceso en la herenciaOrden de llamada de Ctor y DtorSobrescritura de métodosFunciones virtuales y VTableHerencia múltipleHerencia virtualResumen - Jerarquía de empleados2Gestión de memoria
Memoria Stack vs HeapPunteros y referenciasMemoria dinámica (new/delete)Punteros inteligentes en C++RAII en C++Resumen - Gestor de arrays dinámicos5Encapsulamiento
Especificadores de acceso en C++Especificadores de acceso en profundidadOcultamiento de informaciónStruct vs ClassClases anidadas e internasResumen - Sistema de registros de estudiantes8Polimorfismo
Polimorfismo: Compilación vs. Tiempo de ejecuciónSobrecarga de funcionesFunciones virtuales revisadasFunciones virtuales purasClases abstractasDiseño de interfaces en C++Dynamic Casting y RTTIResumen: Calculadora de figuras11Conceptos avanzados de POO
Composición vs. HerenciaMixins mediante CRTPIdioma PimplBorrado de tiposEnum Classes y tipado fuerteManejo de excepciones en POOJerarquías de excepciones personalizadas14Patrones de diseño - Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositeRAII como patrón3Constructores y Destructores
Constructor por defectoConstructor parametrizadoConstructor de copiaConstructor de movimientoListas de inicialización del constructorConstructores delegadosAnálisis profundo del destructorRegla de tres / cinco / ceroResumen - Clase String6Sobrecarga de operadores
Introducción a la sobrecarga de operadoresSobrecarga de operadores aritméticosSobrecarga de operadores de comparaciónOperadores de flujo (Stream)Sobrecarga del operador de asignaciónSobrecarga de los operadores [] y ()Operadores de conversión de tiposResumen - Clase Matrix9Plantillas
Plantillas de funcionesPlantillas de clasesEspecialización de plantillasPlantillas variádicasConceptos básicos de SFINAE y Type TraitsResumen - Contenedor genérico