Menu
Coddy logo textTech

Especificadores de acceso en C++

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

C++ proporciona tres especificadores de acceso que controlan quién puede acceder a los miembros de la clase: public, protected y private. Estos forman la base de la encapsulación.

class Account {
public:
    std::string ownerName;      // Accesible desde cualquier lugar
    
protected:
    double interestRate;        // Accesible en esta clase y clases derivadas
    
private:
    double balance;             // Accesible solo dentro de esta clase
};

Los miembros Public pueden ser accedidos desde cualquier lugar: dentro de la clase, desde clases derivadas y desde código externo. Los miembros Private son los más restrictivos, accesibles solo dentro de la propia clase. Protected se sitúa en un punto intermedio: actúa como privado para el mundo exterior, pero las clases derivadas pueden acceder a estos miembros.

class Account {
private:
    double balance;
    
public:
    Account() : balance(0) {}
    
    void deposit(double amount) {
        balance += amount;    // OK - dentro de la clase
    }
};

int main() {
    Account acc;
    acc.deposit(100);         // OK - deposit es público
    // acc.balance = 500;     // ERROR - balance es privado
}

Por defecto, todos los miembros en una class son private si no se proporciona ningún especificador. Esto le anima a decidir explícitamente qué debe ser expuesto. La práctica general es hacer que los miembros de datos sean private y proporcionar métodos public para interactuar con ellos de forma segura.

challenge icon

Desafío

Fácil

Vamos a construir un sistema simple de gestión de empleados que demuestre cómo los especificadores de acceso controlan quién puede acceder a qué. Crearás una clase donde algunos datos son completamente privados, otros son accesibles para posibles subclases y otros están abiertos para todos.

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

  • Employee.h: Define una clase Employee que utiliza los tres especificadores de acceso para proteger los datos de manera adecuada:
    • Public: El name (string) del empleado — se puede acceder desde cualquier lugar
    • Protected: El department (string) del empleado — accesible dentro de la clase y por clases derivadas, pero no desde el exterior
    • Private: El salary (double) del empleado — solo accesible dentro de la propia clase
    • Un constructor que recibe name, department y salary para inicializar los tres miembros
    • Un método público getSalary() que devuelve el valor privado del salario
    • Un método público getDepartment() que devuelve el valor protegido del departamento
    • Un método público giveRaise(double amount) que aumenta el salario en la cantidad dada (solo si la cantidad es positiva)
    • Un método público displayInfo() que imprime la información del empleado en el formato: "Name: <name>, Department: <department>, Salary: "Name: <name>, Department: <department>, Salary: $<salary>"lt;salary>"
  • main.cpp: Demuestra cómo funcionan los especificadores de acceso interactuando con un objeto Employee. Lee el nombre, departamento y salario de un empleado desde la entrada (tres líneas separadas), luego:
    • Crea un Employee con los valores de entrada
    • Imprime el nombre del empleado directamente accediendo al miembro público: "Direct access - Name: <name>"
    • Imprime el departamento usando el getter: "Via getter - Department: <department>"
    • Imprime el salario usando el getter: "Via getter - Salary: "Via getter - Salary: $<salary>"lt;salary>"
    • Dale al empleado un aumento de 5000.0
    • Imprime "After raise:"
    • Llama a displayInfo() para mostrar la información actualizada

Formatea todos los valores de salario con dos decimales usando std::fixed y std::setprecision(2) de <iomanip>. Convierte la entrada del salario de string a double usando std::stod().

La idea clave aquí es que, si bien puedes acceder a name directamente desde main, no puedes acceder a department o salary directamente; debes usar los métodos getter públicos. Esto es la encapsulación en acción: la clase controla cómo se accede y se modifican sus datos.

Hoja de referencia

C++ proporciona tres especificadores de acceso para controlar el acceso a los miembros de la clase:

  • public: Accesible desde cualquier lugar
  • protected: Accesible dentro de la clase y en clases derivadas
  • private: Accesible solo dentro de la propia clase
class Account {
public:
    std::string ownerName;      // Accessible from anywhere
    
protected:
    double interestRate;        // Accessible in this class and derived classes
    
private:
    double balance;             // Accessible only within this class
};

Por defecto, todos los miembros de una clase son private si no se indica ningún especificador.

Ejemplo que demuestra el control de acceso:

class Account {
private:
    double balance;
    
public:
    Account() : balance(0) {}
    
    void deposit(double amount) {
        balance += amount;    // OK - inside the class
    }
};

int main() {
    Account acc;
    acc.deposit(100);         // OK - deposit is public
    // acc.balance = 500;     // ERROR - balance is private
}

Mejor práctica: Hacer que los miembros de datos sean privados y proporcionar métodos públicos para interactuar con ellos de forma segura.

Pruébalo tú mismo

#include <iostream>
#include <string>
#include <iomanip>
#include "Employee.h"

using namespace std;

int main() {
    // Leer la entrada
    string name;
    string department;
    string salaryStr;
    
    getline(cin, name);
    getline(cin, department);
    getline(cin, salaryStr);
    double salary = stod(salaryStr);
    
    // Establecer la precisión para la salida del salario
    cout << fixed << setprecision(2);
    
    // TODO: Crear un objeto Employee con los valores de entrada
    
    // TODO: Imprimir el nombre del empleado accediendo directamente al miembro público
    // Formato: "Direct access - Name: <name>"
    
    // TODO: Imprimir el departamento usando el método getter
    // Formato: "Via getter - Department: <department>"
    
    // TODO: Imprimir el salario usando el método getter
    // Formato: "Via getter - Salary: $<salary>"
    
    // TODO: Dar al empleado un aumento de 5000.0
    
    // TODO: Imprimir "After raise:"
    
    // TODO: Llamar a displayInfo() para mostrar la información actualizada
    
    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