C++ Modificadores de acceso de clases
En la programación orientada a objetos (OOP) de C++, la encapsulación de datos (Encapsulation) es uno de los conceptos centrales. En pocas palabras, consiste en "ocultar" los datos y solo exponer las interfaces necesarias para uso externo, con el fin de garantizar la seguridad de los datos.
Para controlar quién puede ver estos datos, C++ proporciona tres palabras clave, llamadasmodificadores de acceso:
public(público)private(privado)protected(protegido)
Para facilitar la comprensión, podemosimaginar una clase (Class) como tu casa.:
| modificador | Analogía en la vida real | ¿Quién puede acceder? | Uso típico |
|---|---|---|---|
| public | Sala de estar / puerta principal | Todos(interno de la clase, subclases, código externo) | Funciones de interfaz (API) proporcionadas al exterior. |
| protected | Dormitorio | Tú y tus hijos(interno de la clase, subclases) | Datos utilizados únicamente dentro de la familia (jerarquía de herencia). |
| private | Caja fuerte | Solo tú mismo(solo dentro de la propia clase) | Datos centrales, variables que no se desea que se modifiquen arbitrariamente. |
Nota: si no se escribe ningún modificador, los miembros de la clase C++por defecto son
private(privados).
Miembros públicos (public)
públicoLos miembros se pueden acceder desde cualquier parte del programa, sin necesidad de leerlos o escribirlos mediante funciones miembro. Ejemplo:
Ejemplo
Cuando el código anterior se compila y se ejecuta, produce los siguientes resultados:
Length of line : 6 Length of line : 10
Miembros privados (private)
Los miembros privados están completamente cerrados fuera de la clase; el código externo no puede leerlos, modificarlos ni invocarlos, y las clases derivadas tampoco tienen derecho a acceder directamente a ellos. Solo las funciones miembro de la propia clase y las entidades a las que se les haya otorgado permiso de amistad (friend) pueden operar sobre estos contenidos.
Si en la clase no se utiliza ningún especificador de acceso, los miembros son privados por defecto. Como se muestra en el siguiente ejemplo, width cae automáticamente en la zona privada, lo que indica que todos los miembros no marcados explícitamente se tratan como privados:
Ejemplo
En la práctica, generalmente definimos los datos en la zona privada y las funciones relacionadas en la zona pública, para que estas funciones también puedan ser invocadas desde fuera de la clase, como se muestra a continuación:
Ejemplo
Cuando el código anterior se compila y se ejecuta, produce los siguientes resultados:
Length of box : 10 Width of box : 10
Miembros protegidos (protected)
protectedLa existencia de estos es principalmente parala herencia。
- Si no hay herencia, es
privateigual (invisible para los externos). - Si hay herencia,las subclases (clases derivadas) pueden acceder a los
protectedmiembros, pero no pueden acceder a losprivatemiembros.
En el próximo capítulo, aprenderá sobre clases derivadas y herencia. Ahora puede ver en el siguiente ejemplo que de la clase baseBoxderivamos una subclasesmallBox。
El siguiente ejemplo es similar al anterior; aquíwidthel miembro puede ser accedido por cualquier función miembro de la clase derivada smallBox.
Ejemplo
Cuando el código anterior se compila y se ejecuta, produce los siguientes resultados:
Width of box : 5
Cambios de acceso en la herencia
Cuando define una subclase (por ejemplo,class B : public A), lo que sigue a los dos puntospublictambién es un modificador de acceso, que determinacómo se "comportan" los miembros de la clase padre en la subclase.。
Esto parece complicado, pero solo tiene que recordar esteprincipio de degradación:
La forma de herencia determina el permiso máximo de los miembros de la clase padre en la subclase.
Si la forma de herencia es más estricta que el permiso original del miembro, el permiso del miembro se "degrada" al nivel de la forma de herencia.
Tabla de cambios de permisos
| Permiso original del miembro de la clase padre | Herencia public(la más común) | Herencia protected | Herencia private |
|---|---|---|---|
| public | Se mantiene public | Se degrada a protected | Se degrada a private |
| protected | Se mantiene protected | Se mantiene protected | Se degrada a private |
| private | Inaccesible | Inaccesible | Inaccesible |
Nota: inaccesible significa que el código de la subclase no puede usar directamente esa variable, pero la variable todavía existe en la memoria.
Código de demostración completo
Para mostrar claramente, renombramos las variables comopub_var(público),pro_var(protegido),pri_var(privado).
Ejemplo
using namespace std;
class Parent {
public:
int pub_var;
protected:
int pro_var;
private:
int pri_var; // Solo Parent mismo puede acceder
public:
Parent() { pub_var = 1; pro_var = 2; pri_var = 3; }
};
// 1. Herencia pública (Public Inheritance) - la más común, tal cual
class ChildA : public Parent {
public:
void test() {
cout << pub_var << endl; // OK
cout << pro_var << endl; // OK
// cout << pri_var << endl; // ¡Error! Los miembros privados de la clase padre no son visibles
}
};
// 2. Herencia protegida (Protected Inheritance) - todos se vuelven protegidos
class ChildB : protected Parent {
public:
void test() {
cout << pub_var << endl; // OK, pero desde la perspectiva de ChildB, es protected
cout << pro_var << endl; // OK
}
};
// 3. Herencia privada (Private Inheritance) - todos se vuelven privados
class ChildC : private Parent {
public:
void test() {
cout << pub_var << endl; // OK, pero desde la perspectiva de ChildC, es private
cout << pro_var << endl; // OK, pero desde la perspectiva de ChildC, es private
}
};
int main() {
ChildA a;
cout << a.pub_var << endl; // OK, el exterior puede acceder
// cout << a.pro_var << endl; // Error, el exterior no puede acceder a protected
ChildB b;
// cout << b.pub_var << endl; // ¡Error! Porque es herencia protected, pub_var se vuelve protected fuera
ChildC c;
// cout << c.pub_var << endl; // ¡Error! Porque es herencia private, pub_var se vuelve private fuera
return 0;
}
Resumen
- Public: Todo el mundo puede usarlo. Se usa como interfaz (API).
- Private: Solo uno mismo puede usarlo. Para almacenar datos (opción segura por defecto).
- Protected: Solo la familia (cadena de herencia) puede usarlo. Para dejar una puerta trasera a las subclases.
Herencia:
- Herencia Public: los atributos de la clase padre permanecen sin cambios (la más común).
- Herencia Private/Protected: restringirá los permisos de los miembros de la clase padre, generalmente se usa en escenarios de implementación especiales.
Clases y objetos en C++