Vamos a diseñar, a modo de ejemplo, una pequeña clase a la que llamaremos CCirculo. El objetivo es que nos sirva como medio de aprendizaje.
El diagrama los vamos a realizar en el software Dia
Pensemos en las propiedades de un círculo.
Un círculo tiene:
radio
área
perímetro
Hay otras cualidades que no lo vamos a considerar como pueden ser el color o las coordenadas del centro, si el círculo está en un sistema. Para nuestro ejemplo mínimo es suficiente.
Esta proceso de extraer de un objeto solo los atributos o cualidad necesarias (teniendo como norte lo que queremos desarrollar) se llama ABSTRACCIÓN y es un concepto fundamental de la POO.
El área es una propiedad que depende de la medida del radio, por lo tanto no es un atributo principal, lo mismo ocurre con el perímetro (longitud de la circunferencia que delimita el circulo), por lo tanto nuestra clase solo tendrá un atributo. Notar que tanto el área como el perímetro dependen de la medida del radio.
El rectángulo presenta tres secciones, la primera corresponde al nombre de la clase, nosotros lo vamos a llamar CCirculo. La siguiente sección corresponde a los atributos, que en este caso (de momento) solo tendrá uno, el radio.
Y la última sección corresponde a las operaciones. Éstas operaciones corresponden a las acciones que puede realizar un objeto de esta clase.
Los valores de los atributos o cualidades pueden variar entre un objeto y otro de la misma clase. Dos círculos pueden tener distintas medidas para el radio. Las buenas normas de programación señalan que no es adecuado que un atributo pueda ser modificado directamente, dicho sea de paso, otro concepto importante de la POO, el ENCAPSULAMIENTO. Para modificar el valor de un atributo de un objeto se debe hacer a través de una operación perteneciente a la misma clase, por eso los atributos tienen una visibilidad privada (visible solo para la clase y sus clases derivadas). En el diagrama vemos que radio está precedido por un "-" que indica tal situación. En cambio las operaciones, que son accesibles desde fuera de la clase, tienen un signo "+". Si una operación necesita ser privado, tendrá también un "-". Hay operaciones que solo son accesible desde dentro de la clase, en este caso debe ser privado. Eso depende de cada operación.
+setRadio(rad_in:float):void
setRadio es el nombre de la función y es una operación cuyo propósito es poner o establecer un valor para el atributo radio. Esta operación tiene un parámetro que es de tipo float (debe ser del mismo tipo que el atributo a modificar) de nombre rad_in. Esta operación no retorna valor alguno, por eso es de tipo void.
En C++ esta operación se escribe así: void setRadio(float rad_in){...} Entre las llaves debe ir la definición de la función.
+getRadio() : float const;
Esta función lo que hace es "leer" el valor del atributo radio, y ponerlo en el lugar donde es invocada la función, por eso retorna un valor de tipo float y es constante porque la función no debe modificar ese valor.
En C++ esta función se escribe así: float getRadio() const {...}
Las otras dos funciones obtienen tanto el área como el perímetro en base al valor del radio. Una explicación más detallada la vamos a dar cuando definamos estas funciones.
La definición de la clase CCirculo la vamos a escribir en el archivo CCirculo.h, también llamado archivo de cabecera. La definición de los métodos de la clase en el archivo CCirculo.cpp, también llamado archivo de implementación.
Cabe aclarar que como IDE vamos a utilizar Geany. Un entorno simple y minimalista y en el cual me siento muy a gusto.
Es esta imagen se puede apreciar la vista del editor.
// CCirculo.h
/*************************************
Armando B. VERA
Prof. de Matemática e Informática
*************************************/
#include <iostream>
#ifndef CCIRCULO_H
#define CCIRCULO_H
#include <iostream>
class CCirculo {
private:
float radio;
public:
// Sección Constructores y destructor
CCiculo();
CCirculo(float rad_in);
CCirculo(CCirculo &c); // Constructor de copia
~CCirculo();
// Métodos de asignación (setter)
void setRadio(float rad_in);
// Métodos de lectura
float getRadio() const;
// Otros métodos
float perimetro();
float area();
};
#endif //CCIRCULO_H
Observar que la llave de cierre de la clase debe estar seguido de un punto y coma ";". Es el único lugar donde es obligatorio el uso del punto y coma después de la llave.
Cabe aclarar que en este archivo debemos incluir la librerías que vamos a utilizar en nuestra clase, por eso pusimos #include <iostream>. También podemos incluir otras clases desarrolladas por nosotros mismos o por terceros.
Para que no haya múltiples definiciones de una misma clase, con los problemas que esto acarrearía, es que se utiliza las directivas de preprocesador #ifndef y #define ... #endif. Lo que hace esta directiva es preguntar si no está definida la clase CCIRCULO_H, si se cumple esta condición, y solo ahí, entonces define la clase. Si estuviera definida en otro lugar, la compilación del archivo seguiría después del #endif.
Este archivo conviene guardarlo en un directorio o carpeta. Nosotros lo vamos a poner en /home/armando/Escritorio/CLASES/CCirculo en Linux. La idea es que dentro de la carpeta CCirculo estén los archivos CCirculo.h, CCirculo.cpp y pCCiculo.cpp, este último, archivo de un programa fuente de prueba de la clase. A su vez es común que los directorios que contienen estos archivos de clases estén dentro de otros que contienen al proyecto.
El archivo de implementación, archivo que contiene el código fuente de las operaciones es CCirculo.cpp y también lo vamos a guardar en la misma carpeta CCirculo.
// CCirculo.cpp
/*************************************
Armando B. VERA
Prof. de Matemática e Informática
*************************************/
#include "CCirculo.h"
double const PI=3.141592;
// Definición de los constructores
CCirculo::CCirculo(){
radio=0.0;
}
CCirculo::CCirculo(float rad_in){
radio=rad_in;
}
CCirculo::CCirculo(CCirculo &c){
radio=c.radio;
}
CCirculo::~CCirculo(){}
// Definición de los métodos de asignación
void setRadio(float rad_in){
radio=rad_in;
}
// Definición de los métodos de lectura
float getRadio() const{
return radio;
}
// Definición de otros métodos
float perimetro(){
float p=0.0;
p=2*PI*radio;
return p;
}
float area(){
float a=0.0;
a=PI*radio*radio;
return a;
}
La compilación lo podemos hacer desde el terminal utilizando la siguiente instrucción:
$ g++ -c CCirculo.cpp
Esta instrucción genera un archivo binario con con nombre CCirculo.o denominado archivo objeto (nombre que nada tiene que ver con la POO) que no es ejecutable. Es una pieza pre-compilada lista para ser enlazada a un archivo ejecutable.
La compilación puede realizarse directamente desde el IDE presionando la tecla de función F8 o haciendo click en el icono correspondiente que puede apreciarse en la imagen de la izquierda.
Si la Compilación ha tenido éxito, el compilador los muestra, lo mismo ocurre si hay errores y/o avisos.
Una vez que compilamos con éxito, en la carpeta CCirculo habrá un nuevo archivo, binario, con nombre CCirculo.o producto de esa traducción a lenguaje máquina que realizó el compilador. Este archivo no es ejecutable directamente por si solo, pero si a través de un enlace de un ejecutable. Lo vamos a ver en el archivo de prueba.
Cabe resaltar que nuestra clase es de los más básico, pero aún así podemos ya utilizarlo en algún programa. Vamos a crear un programa de prueba de la clase que hemos desarrollado. Lo llamaremos pCCirculo.cpp
//pCCirculo.cpp
/*************************************
Armando B. VERA
Prof. de Matemática e Informática
*************************************/
#include "CCirculo.h"
using namespace std;
int main(){
cout << "\t *********************************************" <<endl;
cout << "\t\t Programa de prueba de la clase \t " << endl;
cout << "\t\t CCirculo \t\t\t" << endl;
cout << "\t *********************************************" <<endl;
float radio=0.0;
CCirculo miCirc;
cout << "\t Ingrese una valor para la medida del radio del círculo:";
cin >> radio;
miCirc.setRadio(radio);
cout<< "\n\n\t Características del Círculo de radio " << miCirc.getRadio() << endl;
cout << "\t -------------------------------------------" << endl;
cout << "\t Radio: " << miCirc.getRadio() << endl;
cout << "\t Longitud de la Circunferencia: " << miCirc.perimetro() << endl;
cout << "\t Área: " << miCirc.area() << endl;
return 0;
}
Para compilar lo podemos hacer de dos formas distintas. Directamente desde el terminal con la siguiente instrucción:
$ g++ -o pCCirculo CCirculo.o pCCirculo.cpp
el parámetro -o de g++ está diciendo que lo que sigue es el nombre del archivo de salida. Luego ponemos el nombre del archivo pre-compilado objeto CCirculo.o y por ultimo el archivo fuente pCCirculo.cpp.
Puede observarse la instrucción directa desde el terminal. Si no hay errores g++ nos devuelve el promp y espera el ingreso de otros comandos. Si las hay, se informa por esa misma vía.
Para ejecutar el programa desde el terminal escribimos ./pCCirculo, es decir, anteponemos los caracteres y punto (.) barra (/) al nombre del archivo que queremos ejecutar, en este caso pCCirculo.
La otra opción consiste en escribir está instrucción en el IDE Geany para luego utilizar el icono correspondiente o la instrucción del panel de tareas.
Haciendo click en el menú Construir se despliega una ventana con varias opciones, la última es Establecer comandos de construcción. Es la que nos permite escribir la instrucción "a medida" de nuestras necesidades. Al hacer click se despliega una serie de ventanas con tres secciones bien definidas, Comandos de C++, Comandos independientes y Comandos de ejecución, como se observa en la figura siguiente.
En la primera sección figuran los comandos por defectos, aquellos que tenemos configurado en nuestro IDE. No lo vamos a tocar. En la segunda, Comandos independientes, presenta un panel o cuadrícula de cuatro filas por cuatro columnas como puede observarse en el gráfico. En la primera columna podemos agregar la etiqueta "que queramos", el la segunda el comando de compilación y en la tercera un path que indica el directorio de trabajo.
En la primera columna, fila cuatro notamos que está vacía. Haciendo click se despliega la ventana "Establecer etiqueta del elemento" donde podemos escribir el nombre con el cual vamos a invocar al comando de compilación, este nombre aparece al hacer click en el panel que se despliega al presionar Construir el el menú principal.
Nosotros lo llamaremos "Construir prueba de clase".
Presionamos Aceptar y notamos que el campo Etiqueta de la fila cuatro ya no está vacía.
El siguiente paso consiste en escribir el comando de compilación campo "Comando" de esa misma fila. Escribimos entonces g++ -o pCCirculo CCirculo.o pCCirculo.cpp.
Se muestra en el gráfico siguiente.
El último paso consiste en establecer el directorio de trabajo. Escribimos en ese campo de la misma fila el path donde se encuentra nuestro proyecto. Como en este caso no hay proyecto lo que hacemos es escribir el path donde está nuestro directorio de clase /home/armando/Escritorio/CLASES/CCirculo.
Le damos aceptar y ya podemos utilizar el IDE para compilación múltiples. Haciendo click en "Construir" se despliega un ventana de opciones entre los cuales se encuentra "Construir prueba de clase" que es la opción que hemos configurado.
Todo en un instante