Definición de una clase

Una clase es un tipo definido por el usuario que describe los atributos y los métodos de los objetos que se crearan a partir de las mismas. Los atributos definen el estado de un determinado objeto y los métodos son las operaciones que definen su comportamiento. Forman parte de estos métodos los constructores, que permiten iniciar un objeto, y los destructores, que permiten destruirlo. Los atributos y los métodos se denominan en general miembros de la clase.

Veamos el siguiente formato:

En la definición de la clase, se especifican los atributos y métodos que forman parte de la misma. Los atributos son variables miembro que almacenan el estado de los objetos de la clase, mientras que los métodos son funciones miembro que definen el comportamiento de los objetos.

Dentro de la sección public , se declaran los constructores, destructores y los métodos que son accesibles desde fuera de la clase.

La sección private (no mostrada en el ejemplo) se utiliza para declarar las variables y métodos que solo son accesibles desde dentro de la clase. Por defecto, los atributos y métodos de una clase en C++ son private si no se especifica lo contrario.

Los constructores son métodos especiales que se llaman al crear un objeto de la clase y se utilizan para inicializar sus atributos. El destructor se llama cuando un objeto de la clase se destruye y se utiliza para liberar recursos asignados.

Los getters y setters (también conocidos como métodos de acceso) son métodos utilizados para acceder y modificar los atributos de la clase desde fuera de la misma.

Después de la definición de la clase, se puede implementar el código de los métodos (funciones miembro) fuera de la definición de la clase, como se muestra en el ejemplo.

Atributos

Los atributos, también conocidos como variables miembro, son variables que pertenecen a una clase y almacenan el estado o características de los objetos de esa clase. Los atributos definen las propiedades que pueden tener los objetos y cómo se representan internamente.

En C++, los atributos de una clase se declaran dentro de la sección private o public de la definición de la clase. Por defecto, los atributos son private si no se especifica lo contrario.

Aquí tienes un ejemplo de cómo declarar atributos en una clase:

En este ejemplo, la clase Persona tiene tres atributos: nombre, edad y altura. El atributo nombre es una variable de tipo std::string, que representa el nombre de la persona. El atributo edad es una variable de tipo int, que almacena la edad de la persona. El atributo altura es una variable de tipo float, que guarda la altura de la persona.

Los atributos definen la información que se puede almacenar en cada objeto de la clase y pueden ser accedidos y modificados utilizando los métodos apropiados (getters y setters) o directamente si son públicos.

Métodos de una clase

Los métodos de una clase, también conocidos como funciones miembro, son funciones que están definidas dentro de una clase y operan sobre los objetos de esa clase. Los métodos definen el comportamiento de los objetos y permiten realizar operaciones específicas sobre los atributos de la clase.

En C++, los métodos de una clase se definen dentro de la sección public o private de la definición de la clase. Los métodos declarados en la sección public son accesibles desde fuera de la clase, mientras que los métodos declarados en la sección private solo son accesibles desde dentro de la clase.

Aquí tienes un ejemplo de cómo definir métodos en una clase:

En este ejemplo, la clase Persona tiene dos constructores, dos métodos y cuatro atributos (nombre y edad). El constructor por defecto inicializa los atributos a valores predeterminados, mientras que el otro constructor permite establecer los valores de nombre y edad al crear un objeto de la clase.

Los métodos saludar() y cumplirAnio() definen el comportamiento de los objetos de la clase Persona.

El método saludar() imprime un saludo utilizando el nombre almacenado en el atributo nombre,…

…mientras que cumplirAnio() incrementa la edad en uno e imprime un mensaje de feliz cumpleaños.

Además, se proporcionan métodos de acceso (getters y setters) para los atributos nombre y edad, que permiten obtener y establecer sus valores, respectivamente.

Es importante tener en cuenta que los métodos pueden tener parámetros y pueden retornar valores según sea necesario para realizar diversas operaciones sobre los objetos de la clase.

Control de acceso a los miembros de una clase

En C++, puedes controlar el acceso a los miembros de una clase utilizando los modificadores de acceso: public, private y protected. Estos modificadores determinan la visibilidad y accesibilidad de los atributos y métodos de una clase.

Aquí tienes una explicación de cada modificador de acceso:

  • public: Los miembros declarados como public son accesibles desde cualquier parte del programa, incluyendo desde fuera de la clase. Estos miembros son visibles y se pueden utilizar libremente.
  • private: Los miembros declarados como private son accesibles únicamente desde dentro de la clase. No se pueden acceder ni utilizar directamente desde fuera de la clase ni desde clases derivadas. La encapsulación se logra al ocultar los detalles de implementación y limitar el acceso a través de métodos de acceso (getters y setters).
  • protected: Los miembros declarados como protected son similares a los miembros private, ya que solo son accesibles desde dentro de la clase y desde clases derivadas. Sin embargo, a diferencia de los miembros private, los miembros protected también pueden ser accedidos por las clases derivadas.

A continuación, se muestra un ejemplo de cómo utilizar los modificadores de acceso en una clase:

En este ejemplo, la clase MiClase tiene tres atributos: atributoPrivado, atributoProtegido y atributoPublico.

También tiene tres métodos: metodoPrivado(), metodoProtegido() y metodoPublico().

El atributoPrivado y el metodoPrivado() están declarados como private, lo que significa que solo son accesibles desde dentro de la propia clase.

El atributoProtegido, el metodoProtegido() y el metodoPublico() están declarados como protected y public, respectivamente, lo que significa que son accesibles desde dentro de la clase y desde las clases derivadas (en caso de existir alguna).

El atributoPublicoestá declarado como public, por lo que es accesible desde cualquier parte del programa.

Acceso públicos

Cuando se declara un miembro de una clase como público (public), ese miembro es accesible desde cualquier parte del programa, incluyendo fuera de la clase. Esto significa que otros objetos o funciones pueden acceder y utilizar directamente el miembro público.

Aquí tienes un ejemplo de cómo se utiliza el acceso público en una clase:

En este ejemplo, la clase MiClase tiene un atributo atributoPublico y un método metodoPublico() declarados como públicos.

El atributo atributoPublico es accesible desde cualquier parte del programa. Por ejemplo, se puede acceder y modificar directamente el valor de atributoPublico desde fuera de la clase:

El método metodoPublico() también es accesible desde cualquier parte del programa. Puede ser llamado directamente sobre un objeto de la clase MiClase:

El acceso público es útil cuando se desea que los atributos y métodos de una clase sean fácilmente accesibles y utilizables desde cualquier parte del programa. Sin embargo, también implica una menor encapsulación, ya que los detalles de implementación son visibles y pueden ser modificados externamente. Por lo tanto, es importante usar el acceso público de manera cuidadosa y considerar qué miembros deben ser públicos para mantener la coherencia y el correcto funcionamiento de la clase.

Acceso privado

Cuando se declara un miembro de una clase como privado (private), ese miembro solo es accesible desde dentro de la propia clase. Esto significa que otros objetos o funciones externas a la clase no pueden acceder directamente al miembro privado.

Aquí tienes un ejemplo de cómo se utiliza el acceso privado en una clase:

En este ejemplo, la clase MiClase tiene un atributo atributoPrivado

…y un método metodoPrivado() declarados como privados.

El atributo atributoPrivado no puede ser accedido o modificado directamente desde fuera de la clase. Si se intenta acceder a atributoPrivado desde fuera de la clase, se producirá un error de compilación:

El método metodoPrivado() tampoco puede ser llamado directamente desde fuera de la clase:

El acceso privado se utiliza para ocultar los detalles de implementación y limitar el acceso a ciertos miembros de la clase. Los miembros privados solo pueden ser accedidos y utilizados desde dentro de la propia clase. Esto permite un mayor control sobre cómo se manipulan y se acceden los datos encapsulados, manteniendo la integridad y consistencia de los objetos de la clase.

Para permitir el acceso controlado a los atributos privados desde fuera de la clase, se suelen utilizar métodos de acceso, como los getters y setters, que son métodos públicos que permiten obtener y modificar los valores de los atributos privados de forma controlada.

Acceso protegido

Cuando se declara un miembro de una clase como protegido (protected), ese miembro es accesible desde dentro de la propia clase y desde las clases derivadas (clases que heredan de la clase base). Sin embargo, los miembros protegidos no son accesibles desde fuera de la clase ni desde funciones o objetos que no sean derivados de la clase base.

Aquí tienes un ejemplo de cómo se utiliza el acceso protegido en una clase:

En este ejemplo, la clase ClaseBase tiene un atributo atributoProtegido

…y un método metodoProtegido() declarados como protegidos.

La clase ClaseDerivada hereda de ClaseBase y puede acceder a los miembros protegidos.

Sin embargo, desde fuera de las clases base o derivada, no sepuede acceder directamente a los miembros protegidos debido a su nivel de protección. Estos miembros están diseñados para ser utilizados y manipulados dentro de la jerarquía de herencia, donde las clases derivadas pueden acceder a ellos y aprovechar su funcionalidad extendida.

El acceso protegido se utiliza para permitir que las clases derivadas hereden y utilicen ciertos miembros de la clase base, mientras que restringe el acceso directo desde fuera de la jerarquía de herencia. Esto ayuda a mantener la encapsulación y el control sobre los miembros protegidos, evitando modificaciones y acceso no deseados desde objetos o funciones externas.

Clases en ficheros de cabecera

En C++, las clases se pueden definir en ficheros de cabecera (también conocidos como archivos de encabezado o header files). Los ficheros de cabecera tienen la extensión «.h» o «.hpp» y contienen las declaraciones de las clases y otros elementos que se desean hacer públicos.

La idea detrás de los ficheros de cabecera es separar la interfaz (declaración) de una clase de su implementación (definición). Esto permite que otros archivos de código fuente puedan incluir el fichero de cabecera y utilizar los elementos públicos de la clase sin necesidad de conocer los detalles de implementación.

A continuación, se muestra un ejemplo de cómo se puede definir una clase en un fichero de cabecera:

MiClase.h:

En este ejemplo, se define la clase MiClase en el fichero de cabecera «MiClase.h«.

La directiva#ifndef se utiliza para evitar la inclusión repetida del fichero de cabecera en el mismo archivo y prevenir conflictos de definición.

A continuación, se incluyen las declaraciones de la clase, incluyendo el atributo privado y el método público.

Luego, se utiliza la directiva #endif para finalizar la sección condicional y cerrar el bloque de declaración de la clase.

Una vez que se ha definido la clase en el fichero de cabecera, otros archivos de código fuente pueden incluir el fichero de cabecera para utilizar la clase:

main.cpp:

En este ejemplo, el archivo de código fuente «main.cpp» incluye el fichero de cabecera «MiClase.h«.

Esto permite que el código en «main.cpp» acceda a la clase MiClase y utilice sus elementos públicos, como el método metodoPublico().

Usar ficheros de cabecera para definir las clases tiene varias ventajas, como la separación clara entre la interfaz y la implementación, la reutilización de código y la capacidad de compilar los archivos de código fuente por separado. También ayuda a evitar problemas de dependencia circular entre los archivos de código fuente.

Es importante recordar que, aunque las declaraciones de las clases se encuentren en el fichero de cabecera, la implementación de los métodos y funciones asociados a las clases generalmente se realiza en archivos de código fuente separados con extensión .cpp. Esto ayuda a mantener una organización clara del código y permite que la implementación de los métodos y funciones esté separada de las declaraciones, lo que facilita la compilación y la legibilidad del código. Además, al tener la implementación en archivos de código fuente separados, se evita la necesidad de recompilar todos los archivos cada vez que se realiza un cambio en la implementación de una clase, lo que puede ahorrar tiempo durante el proceso de desarrollo.