Sie sind auf Seite 1von 12

Programacin Orientada a Objetos en C++

5.1. El Paradigma de la POO en C++.


5.2. Creacin y Destruccin de Objetos.
5.3. Encapsulamiento.
5.4. Constructores y Destructores (Inicializacin de Clases I).
5.5. Herencia.
o 5.5.1. Herencia de Constructores y Destructores (Inicializacin de Clases II).
o 5.5.2. Clases Abstractas.
En esta trabajo no se pretende dar una teora completa de P.O.O. tan slo se presentarn
los conceptos necesarios para una correcta programacin en C++.
La P.O.O. es un paradigma de programacin que se fundamenta en los conceptos
de objeto y clase. En primer lugar, definamos que entendemos por objeto y clase:
Objeto: Una entidad autnoma con una funcionalidad concreta y bien definida.
Clase:

Especificacin de las caractersticas de un conjunto de objetos.
Un objeto es una instancia de una clase.
Los conceptos presentados en esta seccin se ilustrarn usando un ejemplo que se ir
completando poco a poco a medida que se introduzcan nuevos conceptos. Es ms, este
mismo ejemplo se emplea en las secciones dedicadas al tratamiento de excepciones y a
la programacin con hebras. As, preparemos el camino creando un proyecto:
Crear un proyecto (File | New | Application)
Cambiar el nombre del formulario (Name=PpalFrm). Colocar un PaintBox de la
pgina de componentes System que se llame PaintBox, con Align=alTop. Dejar
espacio por debajo del PaintBox para colocar un botn.
Colocar un bevel de ancho 4 y alinearlo en lo alto (Align=alTop). La idea es que
delimite la parte inferior del PaintBox.
Colocar un botn bit que permita terminar la ejecucin del programa. El botn
estar centrado horizontalmente en la parte inferior del formulario.
Guardar el cdigo del formulario como Ppal.cpp y el proyecto como Ejemplo.bpr.
Crear una unidad (File | New | Unit). Guardarla con el nombre ObjGraf.cpp
Cuando se crea una unidad de esta manera se crean, en realidad, dos ficheros, uno
con extensin .cpp y otro con extensin .h. As, disponemos de dos
ficheros:ObjGraf.h, que contendr las declaraciones de las clases con las que vamos
a trabajar, y ObjGraf.cpp, que contendr la definicin (implementacin de los
mtodos) de stas.
En ObjGraf.h:
//--------------------------------------------------

#ifndef ObjGrafH
#define ObjGrafH

// Definicin de la clase TObjGraf

class TObjGraf {};

#endif

//--------------------------------------------------
Ntese que el nombre de la clase va precedido por una T, y, aunque no es obligatorio, si
es muy recomendable ya que es una convencin de C++ Builder que casi todos los
nombres de clases vayan precedidos por T.
Muy Importante: Con el ejemplo anterior slo conseguimos definir la clase, pero no se
crea ningn objeto.
5.1. El Paradigma de la POO en C++
Existen cuatro principios bsicos que cualquier sistema orientado a objetos debe
incorporar, que se esquematizan en la figura 5.1.
Figura 5.1. Pilares de la POO.


5.2. Creacin y Destruccin de Objetos
Ya se ha dicho que una clase es nicamente una especificacin. Para poder utilizar la
funcionalidad contenida en la misma, se deben instanciar las clases.
1. Creacin por Declaracin.
Un objeto se puede instanciar de una forma simple, declarando una variable del tipo
de la clase.
En Ppal.h:
#include "ObjGraf.h"
En Ppal.cpp:
Pulsando dos veces en OnCreate de la pestaa Events del editor de objetos
de PpalFrm:
//--------------------------------------------------

void __fastcall TPpalFrm::FormCreate(TObject *Sender)
{
TObjGraf ObjGraf1();
TObjGraf ObjGraf2;
}

//--------------------------------------------------

Aunque esta forma es posible, y bastante utilizada en la programacin de C++ clsica, en C++
Builder se utiliza en muy contadas ocasiones. Esto es as por dos razones, fundamentalmente:
1. La duracin de los objetos suele ir ms all de una simple funcin o bloque. Debido al
enfoque de la programacin dirigida por eventos, suele ser habitual que un objeto se cree en
un gestor de eventos y se destruya en otro.
2. No se puede usar esta modalidad de creacin con la VCL.
Por lo tanto, nosotros no la utilizaremos.

2. Creacin Dinmica
Es la forma habitual de crear objetos en C++ Builder, y se realiza mediante el
operador new.
Cuando usamos new para instanciar un objeto, se usa una variable
que referencie o apunte al nuevo objeto creado (de otra manera ste quedara
totalmente inaccesible). En definitiva, se requiere la declaracin previa de
un puntero a objetos del tipo del que se va a crear.
En Ppal.cpp:
TObjGraf * ObjGraf; // Variable Global.
// ObjGraf es un puntero a objetos de tipo TObjGraf

//--------------------------------------------------

void __fastcall TPpalFrm::FormCreate(TObject *Sender)
{
ObjGraf = new TObjGraf;
}

//--------------------------------------------------
Cuidado! Cuando se utiliza esta forma de instanciacin de clases es
responsabilidad nicamente del programador la correcta destruccin de los mismos.

3. Destruccin de objetos
Cuando un objeto deja de ser til hay que eliminarlo. De esta manera la aplicacin
recupera los recursos (memoria) que ese objeto haba acaparado cuando se cre.
La destruccin de objetos creados en tiempo de ejecucin con new se realiza
mediante el operador delete.
En Ppal.cpp:
Pulsando dos veces en OnDestroy de la pestaa Events del editor de objetos
de PpalFrm:
//--------------------------------------------------

void __fastcall TPpalFrm::FormDestroy(TObject *Sender)
{
delete ObjGraf;
}

//--------------------------------------------------

5.3. Encapsulamiento
En la programacin clsica (lenguaje C, p.e.) existen datos y procedimientos que actan
sobre esos datos. No hay una relacin aparente entre datos y procedimientos (funciones)
y esta relacin se establece de manera ms o menos pecisa de acuerdo a la
profesionalidad del programador.
En un objeto podemos distinguir dos aspectos bien diferenciados:
Estado -----------> Propiedades
Comportamiento ---> Mtodos
En P.O.O. los datos y los procedimientos que los gestionan estn relacionados
explcitamente y se "encapsulan" en un objeto. La especificacin de las propiedades de
un objeto y los mtodos de acceso se realiza en la declaracin de la clase de la que se
instancia el objeto.
En la figura 5.2 esquematizamos las propiedades y mtodos que se van a asociar a los
objetos de la clase TObjGraf:
Figura 5.2. Propiedades y mtodos de los objetos de la clase TObjGraf.

La declaracin de propiedades y mtodos de los objetos de la clase TObjGraf se realiza
de la siguiente manera:
En ObjGraf.h:
//--------------------------------------------------

class TObjGraf {

public:
int X; // Propiedades
int Y;
TColor Color;
TPaintBox *PaintBox;

void Mostrar (void); // Mtodos
};

//--------------------------------------------------

Acceso a Miembros de un Objeto
Para acceder a los miembros de un objeto se usan los operadores tpicos de acceso a
miembros: el operador . para referencia directa al objeto y el operador -> para acceso a
travs de un puntero. Como nosotros siempre creamos los objetos con new, y los
referenciamos mediante un puntero, el operador de acceso que utilizaremos es el
operador ->
En Ppal.cpp:
//--------------------------------------------------

void __fastcall TPpalFrm::FormCreate(TObject *Sender)
{
...
int ValorY;
...
ObjGraf->X = 5;
ValorY = ObjGraf->Y;
ObjGraf->Mostrar(); //Equivalente a (*Obj).Mostrar();
}

//--------------------------------------------------
Nota: Los puntos suspensivos no son una palabra reservada de C++, simplemente
significan que se omite una parte del cdigo, ya sea porque es irrelevante o porque ya se
ha expuesto anteriormente.

5.4. Constructores y Destructores
Son mtodos que permiten establecer el estado inicial y final de un objeto. Los
constructores se pueden definir con un conjunto de argumentos arbitrario, pero no
pueden devolver nada. Y los destructores no pueden recibir ni devolver ningn valor.
El constructor debe llamarse igual que la clase, y el destructor el nombre de la clase
precedido del carcter ~
Un constructor se ejecuta cuando se crea un nuevo objeto: 1) por declaracin, 2)
cuando se crea dinmicamente con el operador new. Un destructor se ejecuta cuando el
objeto deja de existir: 1) porque su mbito acaba, 2) cuando se libera explcitamente
con el operador delete.
En ObjGraf.h:
class TObjGraf {
...

// Constructor de objetos TObjGraf

TObjGraf (TPaintBox *_PaintBox, TColor _Color=clBlack,
int _X=0, int _Y=0);

// El destructor sera: ~TObjGraf (void);
};
En ObjGraf.cpp:
TObjGraf :: TObjGraf (TPaintBox * _PaintBox, TColor _Color,
int _X, int _Y)
{
PaintBox = _PaintBox;
Color = _Color;
X = _X;
Y = _Y;
}
En Ppal.cpp:
void __fastcall TPpalFrm::FormCreate(TObject *Sender)
{
ObjGraf = new TObjGraf (PaintBox, clRed, 10, 10);
}
Importante: No es necesario escribir un destructor salvo si el objeto requiere memoria
dinmica adicional. De ser as, la tarea del destructor ser, bsicamente, liberar la
memoria dinmica que ocupa el objeto que se va a destruir.

5.5. Herencia
Cuando una clase hereda de otra, la clase derivada incorpora todos los miembros de
la clase base adems de los suyos propios.
La herencia es una herramienta muy importante en muchos aspectos del desarrollo de
aplicaciones:
Organizacin del diseo.
Reusabilidad de clases (propias o no).
Mejora del mantenimiento.
Tomando como base la clase TObjGraf se van a construir dos nuevas
clases, TCirculo y TCuadrado, que derivan de TObjGraf. Esto significa que los objetos de
estas clases tienen asociados las propiedades y mtodos de la clase base, TObjGraf,
adems de los suyos propios. En la figura 5.3 esquematizamos el mecanismo de herencia
para las nuevas clases y las nuevas propiedades que se asocian a los objetos de las clases
derivadas.
Figura 5.3. Las clases TCirculo y TCuadrado heredan las propiedades y mtodos de la
clase TObjGraf.4

En ObjGraf.h:
//*************************************************/
// Definicion de la clase derivada TCirculo
// Deriva de la clase base TObjGraf
//*************************************************/

class TCirculo : public TObjGraf {

public:

int Radio; // Propiedad exclusiva de TCirculo

};

//*************************************************/
// Definicion de la clase derivada TCuadrado.
// Deriva de la clase base TObjGraf
//*************************************************/

class TCuadrado : public TObjGraf {

public:

int Lado; // Propiedad exclusiva de TCuadrado

};
Antes del nombre de la clase base hay que poner public, esto es as porque C++ permite
tambin la herencia private. Pero sta no se suele usar, por lo que nosotros supondremos
que slo existe la public.

5.5.1. Herencia de Constructores y Destructores
Los constructores y destructores de una clase no son heredadas automticamente por sus
descendientes. Deberemos crear en las clases hijas sus propios constructores y
destructores. Es posible, no obstante, emplear los constructores de la clase base pero hay
que indicarlo explcitamente. De ser as, es necesario saber:
1. que los constructores y destructores de las clases base son invocados
automticamente antes que los constructores de las clases derivadas, y
2. que los destructores de las clases derivadas se invocan antes que los de las clases
base.
Para determinar con qu parmetros se llaman a los constructores de las clases base, se
utiliza la lista de inicializacin.
En ObjGraf.h:
//*************************************************/
// Definicion de la clase derivada TCirculo
// Deriva de la clase base TObjGraf
//*************************************************/


class TCirculo : public TObjGraf {

public:

int Radio; // Propiedad exclusiva de TCirculo

// Metodo constructor

TCirculo (TPaintBox *_PaintBox, TColor _Color=clBlack,
int _X=0, int _Y=0, int _Radio=1);

};

//*************************************************/
// Definicion de la clase derivada TCuadrado.
// Deriva de la clase base TObjGraf
//*************************************************/

class TCuadrado : public TObjGraf {

public:

int Lado; // Propiedad exclusiva de TCuadrado

// Metodo constructor

TCuadrado (TPaintBox * _PaintBox, TColor _Color=clBlack,
int _X=0, int _Y=0, int _Lado=1);

};
En ObjGraf.cpp:
TCirculo :: TCirculo (TPaintBox * _PaintBox, TColor _Color,
int _X, int _Y, int _Radio) :
TObjGraf (_PaintBox, _Color, _X, _Y)
{
Radio = _Radio;
}


TCuadrado :: TCuadrado (TPaintBox * _PaintBox, TColor _Color,
int _X, int _Y, int _Lado) :
TObjGraf (_PaintBox, _Color, _X, _Y)
{
Lado = _Lado;
}

5.5.2. Clases Abstractas
Clase abstracta: es una clase que no est completamente especificada (posee mtodos
sin implementar), por lo tanto no se pueden crear instancias de la misma. Una clase
abstracta se usa para servir de clase base a otras clases. En terminologa C++ se dice que
una clase abstracta es aquella que posee al menos un mtodo virtual puro.
Virtual: obliga a las clases derivadas a implementar ese mtodo.
Puro: no pueden crearse instancias de esa clase.
En ObjGraf.h:
class TObjGraf {

public:
...

// Otros metodos

virtual void Mostrar (void) = 0; // Metodo virtual puro
};


class TCirculo : public TObjGraf {

public:
...

// Instanciacion del metodo virtual puro de la clase TObjGraf

void Mostrar (void);

};


class TCuadrado : public TObjGraf {

public:
...

// Instanciacion del metodo virtual puro de la clase TObjGraf

void Mostrar (void);

};
En ObjGraf.cpp:
void TCirculo :: Mostrar (void)
{
PaintBox->Canvas->Pen->Color = Color;
PaintBox->Canvas->Brush->Color = Color;
PaintBox->Canvas->Ellipse(X, Y, X+Radio*2, Y+Radio*2);
}
...

void TCuadrado :: Mostrar (void)
{
PaintBox->Canvas->Pen->Color = Color;
PaintBox->Canvas->Brush->Color = Color;
PaintBox->Canvas->Rectangle(X, Y, X+Lado, Y+Lado);
}
Por qu se especifica el mtodo Mostrar en TObjGraf, como virtual puro, en lugar de
omitirlo? Fundamentalmente podemos considerar dos razones para usar mtodos
virtuales puros:
1. Para obligar a que las clases descendientes los implementen. De esta forma estamos
seguros de que todas las clases descendientes no abstractas de TObjGraf poseen el
mtodo, y se podr invocar con seguridad.
2. Para evitar que se puedan crear instancias de la clase abstracta.
En este estado, si probamos a ejecutar el programa, nos aparecer un error: no se puede
crear una instancia de una clase abstracta. Porqu?: Recordar que en Ppal.cpp el gestor
asociado al evento OnCreate del formulario est escrito como sigue:
//--------------------------------------------------

void __fastcall TPpalFrm::FormCreate(TObject *Sender)
{
ObjGraf = new TObjGraf (PaintBox, clRed, 10, 10);
};

//--------------------------------------------------
As, creemos entonces objetos de las clases hijas:
1. En primer lugar, en Ppal.cpp hay que borrar la declaracin de la variable global:
2. TObjGraf *ObjGraf; // Variable Global.
y en su lugar se declararn cuatro punteros, dos para referenciar a objetos de
tipo TCirculo y otros dos para referenciar a objetos de tipo TCuadrado:
// Punteros a objetos de las clases derivadas.

TCirculo *Cir1, *Cir2;
TCuadrado *Cuad1, *Cuad2;

3. En segundo lugar, modificaremos la funcin FormCreate para que cree dos objetos
de cada clase referenciados por los punteros declarados anteriormente:
4. //--------------------------------------------------
5.
6. void __fastcall TPpalFrm::FormCreate(TObject *Sender)
7. {
8. Cir1 = new TCirculo (PaintBox, clBlack, 100, 100, 30);
9. Cir2 = new TCirculo (PaintBox, clGreen, 210, 40, 20);
10. Cuad1 = new TCuadrado (PaintBox, clRed, 200, 150, 45);
11. Cuad2 = new TCuadrado (PaintBox, clYellow, 120, 70, 25);
12. };
13.
14. //--------------------------------------------------

15. Finalmente, modificaremos la funcin FormDestroy para que elimine los objetos
creados:
16. //--------------------------------------------------
17.
18. void __fastcall TPpalFrm::FormDestroy(TObject *Sender)
19. {
20. delete Cir1;
21. delete Cir2;
22. delete Cuad1;
23. delete Cuad2;
24. }
25.
26. //--------------------------------------------------
Ahora, al ejecutar el programa se crean y se destruyen objetos de las clases derivadas,
aunque no se visualizan en la ventana. Porqu? En ningn momento se ha llamado al
mtodo Mostrar() asociado a cada objeto. Para mostrar los objetos, basta con indicarlo
en el gestor asociado al evento OnPaint del componente PaintBox:
//--------------------------------------------------

void __fastcall TPpalFrm::PaintBoxPaint(TObject *Sender)
{
Cir1->Mostrar();
Cir2->Mostrar();
Cuad1->Mostrar();
Cuad2->Mostrar();
}

//--------------------------------------------------

En este punto, el proyecto debe estar como se indica en el proyecto Ejemplo0.
El resultado es el mostrado en la figura 5.4:
4 Figura 5.4. Resultado del proyecto Ejemplo.bpr.

Das könnte Ihnen auch gefallen