You are on page 1of 26

Unidad

3. Programacin Orientada a Objetos



Es una metodologa de diseo de software y un paradigma de programacin en el que define a los
programas en trminos de clases de objetos, objetos que son entidades que combinan su estado
(es decir, datos) y su comportamiento (esto es, procedimientos o funciones). La programacin
orientada a objetos expresa un programa como un conjunto de estos objetos, y que a su vez se
comunican entre ellos para realizar tareas. Esto difiere de los lenguajes procedurales tradicionales,
en los que los datos y los procedimientos estn separados y sin relacin. Los programas diseados
con orientacin a objetos estn pensados para ser cdigos ms simples de mantener y reutilizar.

La programacin orientada a objetos anima al programador a pensar los programas
principalmente en trminos de tipos de datos, y en segundo lugar en las operaciones (mtodos)
especficas que interactan con esos datos. Mientras que los lenguajes procedurales animan al
programador a pensar sobre todo en trminos de procedimientos, y en segundo lugar en los datos
que sos procedimientos manejan.

Conceptos de Programacin Orientada a Objetos


El paradigma orientado a objetos se enfoca a las caractersticas de comportamiento y estructura
de las entidades como unidades completas, lo que nos permite disear software de manera
modular y con un alto manejo de estructuras de datos complejas. El paradigma de programacin
orientado a objetos se apoya en los siguientes conceptos:

Abstraccin (de datos) involucra la formulacin de un concepto (clase) poniendo atencin en las
similitudes y diferencias entre las entidades de un conjunto, para extraer las caractersticas
esenciales que lo distingan y evitar las caractersticas no relevantes. Y as, se establece una sola
representacin del concepto que tenga esas caractersticas pertinentes.

Es la capacidad de crear tipos de datos definidos por el usuario extrayendo las propiedades
esenciales de un concepto, sin preocuparse de los detalles exactos de la implementacin. Algunos
simplemente lo definen como la capacidad de enfocarse en lo esencial.

Encapsulacin asegura que los usuarios de un objeto no alteren de manera inesperada el
contenido de un objeto; solo sus mtodos internos estn autorizados para acceder a ellos y su
interfaz pblica especifica como otros objetos podran interactuar con l.

La abstraccin y la encapsulacin estn representadas por la clase. La clase es una abstraccin,
porque define los atributos y mtodos de un determinado conjunto de objetos con caractersticas
comunes, y es una encapsulacin por que constituye una caja negra que encierra tanto los datos
que almacena como los mtodos que permiten manipularlos.

Polimorfismo es la propiedad que permite a una operacin tener diferente comportamiento en
diferentes objetos. Es decir, diferentes objetos reaccionan de manera diferente al mismo mensaje
(de modo que un mismo mtodo pueda tener mltiples implementaciones).



Herencia es la capacidad de definir una nueva clase a partir de otra. De esta forma, la
reutilizacin de cdigo esta garantizada. Las clases estn clasificadas en una jerarqua estricta,
donde la clase padre es conocida como superclase y la clase hijo como clase derivada. Esto
significa que la clase derivada dispone de todos los atributos y mtodos de su superclase.

Los anteriores conceptos son los pilares fundamentales de la programacin orientada a objetos y
describen de manera precisa su funcionamiento. La construccin de programas orientados a
objetos permite facilitar la comunicacin, incrementar la productividad y la consistencia en los
modelos computacionales, as como facilitar la modificacin de los programas y reducir la
complejidad y el esfuerzo de resolucin de problemas.


1.1 Definicin de clase, atributo, mtodo y objeto

Recuerde que las clases son abstracciones de entidades presentes en un dominio determinado de
problemas, y que las clases estn compuestas de diversos componentes que involucran el
comportamiento del modelo a plasmar, as pues definiremos brevemente esos componentes.

Una clase es un tipo de dato definido por el usuario (dato abstracto), es muy similar a una
estructura, ya que especifica los datos que se vern involucrados en la construccin del programa,
pero adems deber contemplar la implementacin de las funciones que debern interactuar con
dichos datos. Con frecuencia se dice que la clase es equivalente a la generalizacin de un objeto.

Se dice que los datos o atributos contenidos en la clase son el conjunto de caractersticas que
definen las propiedades de un objeto especifico, generalmente se conocen como variables del
objeto. Y por otro lado, las funciones o mtodos son pequeos programas altamente
independientes asociados a los datos especficos de la clase. De manera que stos son los
componentes necesarios para construir un objeto cualquiera.

As pues, los objetos son cajas negras que mantienen ocultas propiedades estructurales llamadas
atributos, y propiedades de comportamiento llamadas mtodos. De esta forma, los objetos son
entonces instancias o ejemplares de una clase.

Como una forma de estandarizar la nomenclatura de clases, se especifican dos reglas muy
sencillas. Los nombres de las clases debern iniciar con mayscula y escribirse en singular, y los
nombres de los atributos y los mtodos debern escribirse preferentemente con minsculas.











Abstraccin de Datos


La Abstraccin de datos involucra la formulacin de un concepto (clase) poniendo atencin en las
similitudes y diferencias entre las entidades de un conjunto, para extraer las caractersticas
esenciales que lo distingan y evitar las caractersticas no relevantes. Y as, se establece una sola
representacin del concepto que tenga esas caractersticas pertinentes. Algunos simplemente lo
definen como la capacidad de enfocarse en lo esencial.


2.1
Tipos de datos definidos por el usuario en C (datos abstractos)


Es muy comn emplear las estructuras de datos como tipos de datos definidos por el usuario,
adems de que resultan muy tiles ya que a partir de ellas podemos definir un nuevo tipo de dato
que podr estar compuesto de elementos de otros tipos y en algunos casos quizs de ms
estructuras. Por otro lado, las funciones juegan un papel trascendental en la definicin de datos,
ya que es posible construir funciones que manejen esos tipos de datos definidos por el usuario, lo
que puede aumentar y simplificar el diseo de programas ya que las funciones pueden estar
asociadas a un tipo de dato en especial.

En el siguiente ejemplo se muestra como podemos construir un programa a partir de estructuras,
y despus desarrollar las funciones necesarias para poder interactuar con dichas estructuras.
Construimos una estructura llamada Horaria que define 3 valores hora, minuto, segunda. El
programa principal genera una variable de tipo estructura Horario a la cual se le asignan valores
iniciales y que posteriormente es enviada por referencia (&) a las funciones Militar() y Standar(),
que se encargan de mostrar la hora en formato universal y estndar.


#include <iostream>
using namespace std;
/* tipo Horario definido por el usuario mediante una estructura simple */
struct Horario {
int hora, minuto, segundo;
};

/* declaracin de prototipos */
void Militar ( Horario & ); // reciben una referencia por alias
void Standar ( Horario & );

int main(){
Horario Mexico; // variable tipo Horario
Mexico.hora = 14;
// asignan valores a los miembros
Mexico.minuto = 57;
Mexico.segundo = 0;

cout << "La hora en Mexico es ";

Militar( Mexico ); /* envia como parmetro la variable Mexico */


cout << " formato militar, \n es decir las ";
Standar( Mexico );
Mexico.hora = 29;
// asigna un valor invlido al miembro cout << "\n datos invalidos
";
Militar( Mexico );
cout << endl;
return 0;
}

/* definicin de funciones prototipo */

/* recibe como argumento la referencia a la variable tipo Horario */
void Militar ( Horario &t ){
// imprime los miembros de la estructura
t. cout << ( t.hora < 10 ? "0":"" ) << t.hora << ( t.minuto < 10 ? "0":"" ) << t.minuto;
/* Recuerde que el operador condicional es ( condicin ? valor-cierto : valor-falso ) */
}

/* recibe como argumento la referencia de la variable tipo Horario */
void Standar ( Horario &t ){
cout << ( ( t.hora == 0 || t.hora == 12 ) ? 12 : t.hora % 12 )
<< ":" << ( t.minuto < 10 ? "0":"" ) << t.minuto
<< ":" << (t.segundo < 10 ? "0":"" ) << t.segundo
<< ( t.hora < 12 ? " AM" : " PM");
}


2.2
Tipos de datos abstractos en C++

En la programacin estructurada los programas se dividen en dos componentes: procedimientos y
datos. Este mtodo permite empaquetar cdigo de programa en procedimientos, pero Qu
sucede con los datos?, las estructuras de datos utilizadas en programacin estructurada son
globales o se pasan como parmetros, por lo que en esencia los datos se manipulan de manera
separada de los procedimientos.

En el paradigma Orientado a Objetos los programas se consideran como un solo componente, en
el que estn contenidos tanto los procedimientos, como los datos. De manera que cada
componente que se genere es catalogado como un objeto. As pues, un objeto es una unidad que
contiene datos y funciones que operan sobre esos datos. De manera tal que a las variables de un
objeto se les conoce como miembros o propiedades, y a las funciones que operan sobre los datos
se les denominan mtodos.

En los lenguajes de programacin orientados a objetos, la clase es la unidad bsica de
programacin y los objetos son variables o instancias de la misma clase que inevitablemente
debern de entablar una comunicacin entre s mediante el paso o envo de mensajes (acciones
que debe ejecutar el objeto) a travs de los mtodos. El paso de mensajes es el trmino utilizado
para referirnos a la invocacin o llamada de una funcin miembro de un objeto.

Cada vez que se construye un objeto de una clase, se crea una instancia de esa clase. En general,
los trminos objetos e instancias de una clase se pueden utilizar indistintamente. Una clase es una
coleccin de objetos similares (generalizacin) y un objeto es una instancia o ejemplar de una
definicin de una clase.

Las clases, en lenguaje C++, son el tipo de dato abstracto que nos permite realizar el proceso de
abstraccin de manera eficiente ya que nos abocamos al diseo especifico de la clase esbozando
sus caractersticas mas importantes describiendo nicamente los prototipos de las funciones
miembro (declaracin) y posteriormente desarrollamos la implementacin de cada una de las
funciones miembro para esa clase en especial (definicin).

Para el diseo de clases en C++ emplearemos la palabra clave class y especificamos el nombre de
la clase, posteriormente declaramos los miembros y los mtodos (funciones miembro) de la clase.
Adicionalmente por el momento emplearemos dos etiquetas que nos indicaran el tipo de acceso a
los miembros de la clase, public y private. Los datos miembro public (pblicos) sern vistos desde
cualquier punto fuera de la clase y los datos private (privados) estarn nicamente disponibles por
los mtodos pertenecientes a la clase. A continuacin se presenta la estructura gramatical de la
declaracin e implementacin de clases en C++:

// declaracin del dato abstracto

class <Nombre-clase>
{
// declaracin de variables miembro o propiedades
[private:|public:|protected:]
tipo <lista-de-variables>;

// declaracin de funciones miembro o mtodos
[private:|public:|protected:]
<tipo-de-regreso> <funcin-miembro>([lista-argumentos]);
};

// implementacin de la funcin

<tipo-de-regreso> <Nombre-clase>::<funcin-miembro>([lista-argumentos])
{
// declaracin de variables locales
// cuerpo de la funcin
}


Construccin de Clases y objetos


Retomaremos el ejemplo visto en la seccin anterior y lo replantearemos para su solucin
mediante clases. Primeramente disearemos la estructura indispensable para su funcionamiento
(declaracin), empleando la tcnica de abstraccin, y nos ocuparemos de colocar los elementos
indispensables para su funcionamiento.

3.1. Componentes de una Clase



Son todos aquellos datos y funciones (elementos) que forman parte de un determinado objeto, y
que representan sus caractersticas y propiedades particulares. La clase encapsula estos elementos
y los dota de ciertos criterios de visibilidad y manipulacin con respecto a otras clases.



3.2. Datos y Funciones miembro

Datos miembro: Son todas la variables asociadas a una clase particular y representan las
propiedades o caractersticas ms bsicas de un objeto.

Funciones miembro: Son todas las funciones o mtodos que estn relacionadas con un objeto
particular, es decir, son todas aquellas acciones que puede realizar un objeto de cierta clase y que
por lo general manipulan sus propiedades.

Inicialmente necesitamos declarar un nombre para la clase, en este caso emplearemos el mismo
nombre de la estructura Horario. Ahora recordemos que la estructura Horario estaba compuesta
de 3 elementos (hora, minuto, segundo), para este caso dejaremos restringido el acceso a estos
datos a travs de la etiqueta private, ya que no deseamos que estos datos sean manipulados por
algn usuario o clase externa.

De forma similar declararemos las funciones (prototipos) que deseamos implementar para la
clase, nicamente se declaran los prototipos de las funciones y su tipo de acceso, y ms adelante
se implementara el mecanismo o funcionamiento para cada funcin miembro.

El mtodo constructor, como su nombre lo indica, es la funcin miembro responsable de construir
la infraestructura (datos) necesaria para que un objeto este disponible. Es una funcin que lleva
exactamente el mismo nombre de la clase y es la primera funcin en ejecutarse de manera
automtica cuando se crea una instancia de la clase.

#include<iostream>
using namespace std;

/*** declaracin
***/
class Horario {
private: // identificador de acceso restringido a variables
/*** datos miembro ***/
int hora, minuto, segundo;

public: // identificador de acceso libre a mtodos
Horario(); // mtodo constructor
void ajuste(int, int, int); /*** mtodos miembro (prototipos) ***/
void Militar();
void Standar();
};

3.3 Implementacin de Funciones miembro



Consisten en desarrollar el mecanismo de funcionamiento para cada funcin miembro, es decir, es
la parte de programacin de la funcin. Aqu es donde realmente se realiza el proceso de
programacin, es importante aclarar que todos los datos y funciones miembro de una clase son
alcanzados de manera global a la clase. De esta manera cualquier funcin miembro de una clase
podr acceder a cualquiera de sus miembros, incluyendo a los elementos privados.

A continuacin implementamos las funciones miembro para la clase que acabamos de declarar.
Note que el mtodo constructor no tiene tipo, adems tome en cuenta que en la implementacin
de los mtodos es necesario colocar primero el nombre de la clase y despus el operador :: que
es el operador de pertenencia (alcance) en la implementacin, seguido ir el nombre del mtodo
que ser implementado, incluyendo los argumentos que recibir.


/*** definicin de la clase ***/

Horario::Horario()
//Constructor: inicializa la estructura del objeto
{
hora = minuto = segundo = 0;
}

/* mtodo "ajuste" asigna una nuevo horario valido */
void Horario::ajuste( int h, int m, int s)
{
hora = ( h >= 0 && h < 24 ) ? h : 0; minuto = ( m >= 0 && m < 60 ) ? m : 0; segundo = ( s >= 0
&& s < 60 ) ? s : 0;
}

/* mtodo Militar, imprime la hora en formato militar de 24 hrs */
void Horario::Militar() {
cout << ( hora < 10 ? "0":"" ) << hora
<< ( minuto < 10 ? "0":"" ) << minuto;
}

/* mtodo Estndar, imprime la hora en formato estndar AM/PM */
void Horario::Standar() {
cout << ( ( hora == 0 || hora == 12 ) ? 12 : hora % 12 )
<< ":" << ( minuto < 10 ? "0":"" ) << minuto
<< ":" << (segundo < 10 ? "0":"" ) << segundo
<< ( hora < 12 ? " AM" : " PM");
}

Observe que los mtodos miembro realizan exactamente la mismas instrucciones que las
funciones desarrolladas en el programa estructurado. A excepcin de la funcin miembro ajuste
que fue incorporada en el mecanismo de la clase para que nos permitiera realizar la modificacin
de los datos miembro privados (hora, minuto y segundo).

Creacin y Uso de Objetos



Ahora veremos como emplear la clase Horario en un programa, debe tomar en cuenta que lo que
ahora haremos ser definir variables del tipo Horario y de esta manera crear objetos (instancias)
de la clase Horario. Una vez declarado un objeto, el mtodo constructor ser el primer mtodo en
ejecutarse inmediatamente, de tal manera que el constructor es el encargado de crear la
infraestructura necesaria para que el objeto funcione. Una vez creado, los mtodos pblicos del
objeto estarn disponibles, y pueden ser accedidos de manera muy similar a las estructuras
empleando el operador miembro . (punto), como veremos a continuacin:





int main(){
Horario Mexico; /* declaramos un objeto de la clase Horario, enseguida se ejecutara el
mtodo constructor Horario() */
cout << "Hora inicial ";
Mexico.Militar(); // llamamos a uno de los mtodos
cout << " es decir ";
Mexico.Standar();
cout << "\n Nuevo horario en Mxico ";
int h, m, s;
cin >> h >> m >> s;
Mexico.ajuste(h, m, s); // modificamos los datos usando ajuste()
cout << "\nLa hora en Mexico es ";
Mexico.Standar();
// llamamos a uno de los mtodos del objeto
system(pause);
return 0;
}

Los mtodos constructores inicializan variables y en la mayora de los casos crean la
infraestructura necesaria para que el objeto pueda trabajar con sus propios datos, por ejemplo
inicializacin de variables y vectores dinmicos. Una vez que el objeto a cumplido su labor y ya no
es necesario que ocupe espacio de memoria, ser ejecutado automticamente mtodo destructor,
que se encargar de liberar el espacio de datos en memoria pertenecientes al objeto.

Por lo general los mtodos destructores son mas usados cuando generamos espacio dinmico y
requerimos del destructor para que realice la liberacin de memoria de las variables dinmicas.
Mas adelante veremos ejemplos mas claros y efectivos de la utilizacin del mtodo destructor.


3.4 Constructor y Destructor
3.5 Tipos de Constructores

Como ya se explico, los constructores son el primer mtodo que se ejecuta al crear un objeto de
esa clase, tiene la labor de inicializar las variables y crear toda la estructura necesaria para que los
objetos de una determinada clase funcionen como se pretende.

En los lenguajes orientados a objetos como C++ existe la posibilidad de que una misma funcin
pueda ser declarada varias veces, con la nica restriccin de que el nmero de argumentos puede
variar desde ningn argumento hasta n. A esta caracterstica de las funciones se le llama
sobrecarga de funciones, y es muy til cuando se necesita inicializar un objeto de varias
maneras. Veamos un ejemplo nuevamente con la clase Horario que hemos empleado:

class Horario {
private:
int hora, minuto, segundo;
public:
Horario(); // constructor por defecto
Horario(int, int, int); // constructor general
void ajuste(int, int, int);
void Militar();
void Standar(); };

/* constructor por defecto, sin argumentos */
Horario::Horario() {
hora = minuto = segundo = 0;
}

/* constructor general, con argumentos */
Horario::Horario(int h, int m, int s) {
ajuste(h,m,s);
}

Una vez definidas las funciones constructoras, estamos en posibilidad de generar objetos de la
clase Horario. Ahora, lo que haremos ser declarar un par de objetos de ste tipo y emplearemos
dos modos diferentes de declaracin para cada objeto; uno para un objeto llamado mex el cual no
cuenta con argumentos y otro llamado usa con argumentos de entrada. El objeto mex ser
construido empleando el constructor sin argumentos, mientras que el objeto usa ser construido
empleando el constructor con argumentos. El compilador es el encargado de manejar la
sobrecarga, ya que en base al nmero de argumentos del objeto, el compilador determinar a que
funcin le corresponde encargarse de la construccin del objeto.

int main( void )
{
Horario mex, usa(13,30,0);
cout << Horario en Mxico ; mex.Standar(); // 00:00:00 AM cout << Horario en USA ;
usa.Standar(); // 01:30:00 PM system(pause);
return 0;
}


Tambin es posible tener constructores que tengan valores predeterminados, y as podemos crear
un solo constructor que permita recibir ninguno o varios argumentos. Cada argumento que
ingrese ser asignado de izquierda a derecha en los argumentos de la implementacin del
constructor de la clase, los valores que no sean ingresados sern asignados segn el valor de la
declaracin.


class Horario {
private:
int hora, minuto, segundo;

public:
Horario(int = 0, int = 0, int = 0); // constructor predeterminado
void ajuste(int, int, int);
void Militar();
void Standar();
};
Horario::Horario(int h, int m, int s) { // constructor predeterminado
ajuste(h,m,s);
}

De esta forma podremos declarar objetos con el numero de argumentos que se requiera para el
constructor, por ejemplo podramos decidir que unos objetos inicialicen sin argumentos y otros
con uno, dos o tres argumentos para el caso de la clase Horario.

int main( void )
{
Horario mex, usa(13), can(15,1,1);
cout << Horario en Mxico ; mex.Standar();
//00:00:00 AM
cout << Horario en USA ; usa.Standar();

//01:00:00 PM cout << Horario en Canada ; can.Standar();
//03:01:01 PM
system(pause);
return 0;
}

Adems de los constructores antes mencionados existe un tipo de constructor llamado
constructor de copia, que consiste en crear un nuevo objeto a partir de otro objeto ya existente.
Para ello sera necesario asignar todas las variables miembro del objeto existente al objeto de
recin construccin.

class Horario {
private:
int hora, minuto, segundo;
public:
Horario(int = 0, int = 0, int = 0);
Horario( const Horario & ); // constructor de copia
void ajuste(int, int, int);
void Militar();
void Standar();
};
Horario::Horario( const Horario &x ) { // constructor de copia
hora = x.hora; // asigna los valores x al propietario de la llamada
minuto = x.minuto;

segundo = x.segundo;
}

Los constructores de copia son muy tiles cuando necesitamos construir una replica exacta de un
objeto ya definido previamente, por lo que su construccin depende de un objeto como
argumento.

int main( void )
{
Horario mex(13,30), usa( mex ); // usa se construye a partir de mex
cout << Horario en Mxico ; mex.Standar();// 01:30:00 PM cout << Horario en USA ;
usa.Standar();// 01:30:00 PM cin.get();
return 0;
}

Como ya hemos visto, las formas de disear los constructores varia segn las necesidades y
creatividad del programador. Una buena abstraccin del problema y un eficiente diseo de las
funciones miembro pueden resultar en el desarrollo de una clase eficiente, funcional y optima,
que cubra las necesidades para las que fue desarrollada.

Ejemplo: A continuacin veremos una clase llamada Vector, e implementaremos un par de
constructores (predeterminado y de copia), adems veremos la manera en como puede ser
implementado el mtodo destructor que como se menciono anteriormente, es la contraparte de
los constructores, y tienen el propsito de liberar el espacio dinmico. Los destructores son
ejecutados una vez que se ha perdido el alcance de un objeto, es decir son la ultima funcin que se
ejecutar.

#include <iostream>
using namespace std;

class Vector {
private:
int nelem; // tamao del vector
int * lista; // puntero para el vector dinmico public:
Vector( int = 1 ); // inicializa con 1 elemento
Vector( const Vector & ); // constructor de copia
~Vector(); // destructor
void capturar(); // captura los elementos del vector
void mostrar();
void ordenar();
void suma( const Vector &, const Vector & ); // suma de vectores
};

/* constructor predeterminado */

Vector::Vector( int x ) {
nelem = x; // asignamos a n el numero de elementos
lista = new int [ nelem ]; // construimos el vector dinmico
for( int i = 0; i < nelem; i++ )

lista[ i ] = 0; // inicializamos el vector


}

/* crea una copia exacta de un objeto a partir de otro ya existente */

Vector::Vector( const Vector &x ) {
nelem = x.nelem;
lista = new int [ nelem ];
for( int i = 0; i < nelem; i++ )
lista[ i ] = x.lista[ i ];
}

Vector::~Vector() { // destructor
delete [] lista; // libera espacio asignado de manera dinmica
}

Ahora implementamos el mtodo captura, que es responsable de ingresar cada elemento dentro
del vector dinmico, observe que la variable nelem sirve como delimitador de elementos.

void Vector::capturar() {
/*** captura los elementos del vector ***/
for ( int i = 0; i < nelem; i++ ) {
cout << elemento << i;
cin >> lista[ i ];
}
}

Por otro lado, en ocasiones necesitamos que un objeto interactu con otros objetos, ya sea de su
mismo tipo otro. Para ello es necesario disear algunos mtodos que nos permitan realizar
operaciones ms interesantes. Por ejemplo piense que un objeto de tipo Vector, adems de
almacenar informacin del nmero de elementos, cuenta con la caracterstica de poder realizar
operaciones entre ellos; as pues veremos como sera la implementacin de un procedimiento
suma para vectores del mismo tipo y tamao.

void Vector::suma(const Vector &A, const Vector &B ){
if ( A.nelem == B.nelem ) {// verifica que sean iguales
delete [] this->lista; // eliminamos la lista local del objeto this->nelem = A.nelem;
// asignamos el nuevo nelem de A o B lista = new int [nelem];
// creamos un nuevo espacio
for( int i = 0; i < nelem; i++ ) // pasamos los elementos de A y B
lista[i] = A.lista[i] + B.lista[i];
// los elementos de lista local se actualizan
} else
lista[0] = -1; // no definida
}

El procedimiento suma recibe 2 objetos de tipo Vector como argumentos de entrada, de manera
que dichos objetos pueden ser manipulados de forma transparente por el procedimiento suma, as
que sus propiedades pueden ser vistas de manera local. Ahora es importante recordar que el
objeto que ejecuta el procedimiento suma es considerado como el objeto propietario de la

llamada por lo que sus propiedades no necesariamente deben ser referenciadas, pero es posible
hacerlo, empleando el puntero this. De manera que el puntero this es la direccin de un objeto
pasado como parmetro implcito a la funcin miembro.

As que es posible referirnos a los miembros del objeto propietario de la llamada con el puntero
this prescindiendo de l, mas adelante veremos a detalle la utilidad del puntero this. Prestemos
ahora atencin a la operacin de suma realizada dentro del procedimiento y observe que cada
elemento del vector A es sumado con cada elemento del vector B y el resultado es depositado en
la lista de valores del propietario de la llamada.

De esta manera podramos crear un objeto de tipo Vector para manipular sus datos y ms
adelante en caso de necesitar una copia exacta del objeto lo haramos a travs de su constructor
de copia, inclusive es posible realizar una suma de ambos vectores y depositarlo en un tercero
llamado C. Al finalizar el programa el mtodo destructor se encargara automticamente de liberar
el espacio asignado a cada objeto de tipo Vector.

int main( void )
{
Vector R(10), C; R.capturar(); R.mostrar();
Vector S( R ); // crea una copia exacta de R en S
C.suma( R , S ); // realiza una suma de R y S en C
C.mostrar(); system(pause); return 0;
}

Nota: Se deja como ejercicio para el lector implementar los mtodos mostrar (que imprime los
elementos del vector) y ordenar (que ordena los elementos bajo el mtodo de seleccin).

Puntero this

El puntero this es un atributo especial del objeto, el cual guarda la direccin de memoria del
objeto para poder referirse a si mismo en cualquier momento, esto es usado por la manera de
distribuir los objetos en memoria: los atributos de cada objeto son independientes de los de otro
objeto, pero los mtodos son compartidos por todos los objetos declarados del mismo tipo de
clase, as cuando se llama un mtodo del objeto, implcitamente se manda como parmetro el
puntero this de ese objeto para que el mtodo sepa a que atributos referirse a la hora de
procesarlos.

En C++ se define this dentro de un objeto como un puntero al objeto en que est contenido. Se
declara implcitamente como:

class_name *this;

El puntero this se inicializa para apuntar al objeto para el cual se llama a la funcin miembro. Este
puntero es muy til cuando se trabaja con punteros y especialmente en listas enlazadas, cuando
se necesita referenciar un puntero al objeto que se est insertando en la lista.

Programacin I | 2016

La palabra this est disponible para este propsito y puede ser utilizada en cualquier objeto.
Realmente la forma apropiada de referenciar a cualquier variable en una lista es a travs del
uso del puntero predefinido this, escribiendo this -> nombre del miembro, pero el compilador
supone que se est usando, y podemos omitir el puntero.

Tambin hay que tomar en cuenta que:

El tipo de este apuntador this depende del tipo del objeto al cual apunta y que no puede ser
declarado explcitamente, es decir, es declarado y definido por el compilador.

Un uso del apuntador this es impedir que un objeto sea asignado a s mismo.

Es una variable local, es decir, que no puede ser usado explcitamente fuera de la clase.

mbito y acceso a los miembros de una clase.


Cualquier miembro de la clase puede hacer referencia a cualquiera de los otros
elementos miembro de la misma. Las funciones miembro de una clase tienen acceso no
restringido a cualquiera de los datos miembro de esa clase.

El acceso a los datos y funciones miembro de una clase fuera de ella esta restringido por los
identificadores de acceso que se utilizan para controlar la visibilidad de los miembros de una
clase fuera del mbito de la misma. De esta forma los miembros de una clase pueden ser
pblicos, privados o protegidos. Las palabras reservadas (etiquetas) public, private y
protected se utilizan para controlar el modo de acceso a miembros de la clase.

Dentro de una declaracin de clase, cada una de estas etiquetas de acceso se puede utilizar
para preceder a una o ms declaraciones de los miembros de una clase:


pblico: los miembros pblicos son accesibles desde cualquier parte del programa.

privado: los miembros privados slo pueden ser utilizados por las funciones miembro
de la clase y las funciones amigas de la clase.

protegido: los miembros protegidos significan que slo se puede acceder a ellos por
funciones miembro dentro de la misma clase y por funciones miembro de clases derivadas de
esta clase.

Los objetos son instancias de una clase y se emplean como cualquier variable. La principal
diferencia es que pueden llamar a cualquier funcin que pertenezca a la clase. Durante
la ejecucin del programa, los objetos interactan pasndose mensajes y respuestas. Es
fundamental darse cuenta de que un objeto no necesita conocer el funcionamiento interno de
los dems objetos para poder interactuar con ellos. Podemos crear en un programa tantas
instancias de una clase (objetos) como sean necesarios.

Programacin I | 2016

Clases y estructuras


Como recordara las estructuras son tipos de datos definidos por el usuario y pueden ser
definidas y empleadas en cualquier programa estructurado. Las estructuras tambin pueden
formar parte de los elementos de una clase y declarar variables de ese tipo (estructura).

Las reglas de acceso a miembros de una variable tipo estructura son exactamente las mismas
que en la programacin estructurada en C.

A continuacin veremos un ejemplo de una clase que emplea estructuras y a su vez
declararemos un vector dinmico de tipo estructura que manipular los datos contenidos en el
arreglo. Los objetos Histogram podrn capturar datos relativos al nombre de una ciudad y el
numero de robos ocurridos en ella, posteriormente mostrara los datos en forma de tabular y el
nmero de robos para cada ciudad ser expresado adicionalmente con un histograma.

Desarrollaremos los siguientes mtodos:

Histogram( int ): mtodo constructor que recibe como parmetro el numero de casillas que
se habilitaran para los datos del vector dinmico. El constructor se encargara de realizar el
ciclo para definir el tamao del vector y asignar valores iniciales a cada componente del
vector.

captura( ): mtodo encargado de capturar los datos entidad y frecuencia de robos.

histogram( ): mtodo encargado de mostrar los datos del vector y el histograma relativo a la
frecuencia de robos en cada entidad.


Finalmente para este problema ser deseable insertar un mtodo destructor que se encargue
de liberar el espacio del vector dinmico creado por el constructor. Los mtodos destructores
tiene el mismo nombre que los constructores, con la diferencia de que se antepone el carcter
~ (tilde) al nombre del destructor y no se le asignan argumentos.

A continuacin veremos la manera en como declararemos la clase Histogram y elaboraremos
la implementacin de cada uno de los mtodos miembros que se estarn involucrados en la
clase y as podremos asegurar el buen funcionamiento de la misma:

#include <iostream>
using namespace std;
#include <string.h>

class Histogram /* declaracin de la clase Histogram */
{
private:
struct datos {
char entidad[5];
int frecuencia;
};

Programacin I | 2016


datos *vector;
int num; // conserva el numero de elementos del vector

public:
Histogram( int );
~Histogram();
void captura();
void histogram();
};

Histogram::Histogram( int n ) { /* implementacin de la clase */
num = n;
vector = new datos [n];
for (int i=0; i<num; i++) {
strcpy(vector[i].entidad, "");
vector[i].frecuencia = 0;
}
}

Histogram::~Histogram() {
delete [] vector;
}

void Histogram::captura() {
for( int i = 0; i < num; i++ ) {
cout << "Ciudad " <<(i+1)<< " -> ";
cin.ignore(); cin.get(vector[i].entidad,'\n'); cout << "Robos -> ";
cin >> vector[i].frecuencia;
}
}


void Histogram::histogram()
{
cout <<"Num\t"<<"Ciudad\t"<<"Robos\t"<<"Histograma"<<endl;
for( int i = 0; i < num; i++ ) {
cout << (i+1)<<'\t'<<vector[i].entidad<<'\t'
<<vector[i].frecuencia<<'\t';
for(int j=0; j<vector[i].frecuencia; j++)
cout << '*';
cout << endl;
}
}

Finalmente emplearemos la clase, construyendo un objeto Histogram que recibir una
cantidad especifica de elementos para el vector. Posteriormente empleamos los mtodos
captura( ) y histogram( ), para interactuar con el objeto. Cuando se alcance el final de la
funcin main, el destructor entrara en operacin y liberara el espacio dinmico asignado por el
constructor.

Programacin I | 2016


int main()
{
int num;
cout << "cuantos datos ";
cin >> num;
Histogram vector(num);
vector.captura(); vector.histogram(); cin.ignore(); system(pause); return 0;
}

Observe que la construccin de la clase resulta un poco mas compleja pero a la larga resulta
mas intuitiva ya que lo que se construye dentro de la clase es un vector dinmico de tipo
estructura que posteriormente es manipulado de una manera mas tradicional.

7 Clases Internas (anidadas)



En la estructura de una clase, los miembros de clase pueden ser otras clases. De manera que
es posible construir clases anidadas, clases que contienen clases y que en teora son
estructuras evolucionadas. La utilizacin de clase anidadas se justifica cuando:


Deben utilizarse varias instancias a1, a2, ... etc. de la misma clase.

Los objetos de la clase A no pueden tener existencia independiente ms que
como miembros de la clase contenedora B.

La situacin puede esquematizarse como sigue:

class B
{
class A // clase anidada (clase miembro)
{
...
};
A a1, a2, a3; // Ok. B contiene objetos tipo A
...
};

El identificador de una clase anidada est sujeto a las mismas reglas de acceso que los
restantes miembros. Si una clase anidada se declara en la seccin private de la clase
circundante, la clase anidada ser utilizable slo por los miembros de la clase que la circunde.

A continuacin se muestra un ejemplo del empleo de clases anidadas, en esencia se vera que
es un efecto muy similar a emplear el esquema de estructuras. De hecho es recomendable que
el programador comience a utilizar este tipo de esquemas anidados ya que es la forma
correcta de emplear el esquema de clases.

Tomaremos nuevamente el ejemplo del Histogram y lo replantearemos con clases anidadas:

Programacin I | 2016


#include <iostream>
using namespace std;
#include <string.h>

class Histogram {
private:
class Datos {
public:
char entidad[5];
int frecuencia;
Datos(){
// constructor de Datos
strcpy(entidad, ""); // podemos implementar la funcin en
frecuencia = 0; // la declaracin si no excede las 6 lneas
}
};
Datos *vector; // puntero a un objeto de tipo Datos int num;

public:
Histogram( int ) { // constructor Histograma
~Histogram(){ delete [] vector; }
void captura();
void histogram();
};
Histogram::Histogram(int n) { // constructor Histogram
num = n;
vector = new Datos [n]; // crea un arreglo dinmico de Datos
}

/* el resto de las funciones son idnticas a la clase previa (1.6) */

Observe que el constructor de Histogram nicamente define el vector dinmico indicando el
tipo y la dimensin, de manera que automticamente ser llamado el constructor de Datos
para cada casilla del arreglo de objetos llamado vector. Este fenmeno ocurre solamente en
C++, pues se trata de objetos simples y no referencias como en el caso de Java. A continuacin
observamos que el empleo de la clase es muy similar al ejemplo visto con las estructuras.

int main()
{
int num;
cout << "cuantos datos ";
cin >> num;
Histogram vector(num); vector.captura(); vector.histogram(); system(pause);
return 0;
}

Programacin I | 2016

8 Creacin y destruccin de objetos dinmicos (Referencias)



Los objetos dinmicos o referencias son en realidad punteros a objetos y pueden ser
manipulados como una variable simple empleando el operador new, o manipulados de
manera compuesta con el operador new [ ]; lo que implica que se tratara de un arreglo
dinmico de objetos como se vio en el ejemplo anterior cuando creamos un vector de tipo
Datos. Las referencias a objetos simples siguen las mismas reglas de creacin y acceso a
miembros de un puntero.

El espacio de almacenamiento de un objeto dinmico se asigna y libera en tiempo de ejecucin
mediante los operadores new y delete. La clase no se ve modificada en su funcionamiento,
nicamente al momento de crear objetos dinmicos ser necesario declararlos, inicializarlos
(new) y eliminarlos (delete). Observemos el ejemplo ya visto de la clase Vector :

class Vector {
private:
int dim, *lista;

public:
Vector( int = 1 ); // constructor predeterminado
Vector( const Vector & ); // constructor de copia
~Vector() {
// destructor
delete [] lista;
cout << " Destructor ";
}
void captura( ); // captura el vector
void mostrar( ); // muestra el contenido del vector
};

/* la implementacin de los mtodos se deja como ejercicio */

Ahora veremos como podemos emplear objetos dinmicos en nuestros programas, observe
que crearemos dos objetos A (dinmico) y B (estndar). El objeto A es declarado como puntero
y es inicializado su espacio con el operador new. Ahora el acceso a los miembros del objeto
puntero es a travs del operador de flecha -> usado en los punteros.

int main(void)
{
Vector *A; // objeto dinmico int i, j;
cout << "tamao de los vectores A y B ";
cin >> i >> j;
cout << "\n Vector A \n";
A = new Vector(i);
A->captura(); A->mostrar();
Vector B(j); // objeto simple cout << "\n Vector B \n"; B.captura();
B.mostrar(); delete A; system(pause); return 0;
}

Programacin I | 2016


Una vez que el objeto ya no es utilizado o es obsoleto se elimina con el operador delete. Una
de las principales caractersticas/beneficios de emplear objetos dinmicos es el ahorro en
espacio de memoria, ya que no contamos con un recolector de basura automtico que libere
el espacio que ya no se utiliza como en el caso de Java.

9. Funciones miembro especiales



9.1 Funciones en lnea ( inline )

Las funciones en lnea (inline) son funciones completas que se incrustan en la declaracin de la
clase, no excediendo un limite razonable de lneas. En realidad la decisin de incrustar o no
ste tipo de funciones en la declaracin corresponde totalmente al compilador.

Las funciones en lnea suelen ejecutarse mas rpido, ya que el compilador inserta una copia de
la funcin en un programa en cada punto que se llama a la funcin. A continuacin veremos un
ejemplo de las funciones inline implementadas en la clase Vector.

class Vector {
private:
int dim, *lista;

public:
Vector( int = 2 ); // constructor predeterminado
~Vector() { // destructor
delete [] lista;
}
inline int longitud() { // indica la longitud del Vector
return dim;
}
void captura( ); // captura el vector
void mostrar( ); // muestra el contenido del vector
};

El mtodo destructor se incrusta como una funcin en lnea ya que la implementacin de dicha
funcin esta disponible en la declaracin de la clase. Adems la funcin longitud( ), que nos
regresa el nmero de elementos en el objeto de tipo Vector, tambin es incrustada como
funcin en lnea. Tomen en cuanta que el cdigo debe ser breve y no se permite la definicin
de datos static, estatutos de control (bucles) y estatutos de seleccin como switch.

Cuando un constructor o destructor esta en lnea, no se suele anteponer la especificacin
inline. No as para el resto de las funciones, se pueden incluir tantas funciones en lnea como
sea necesario, solo recuerde que el limite y la cantidad de lneas en ella lo impondr el
compilador.

Programacin I | 2016


9.2 Funciones y datos estticos ( static )

Cada objeto de una clase tiene sus propios datos miembro. Aunque en ciertos casos es
deseable que todos los objetos de una clase compartan una sola copia de una variable en
especial. Por esta razn se utilizan las variables de tipo static, que presentan informacin a
nivel de clase.

A continuacin mostraremos un ejemplo de su declaracin, suponga que se requiere una clase
Nave, que ser la responsable de crear tantos objetos tipo Nave como sea necesario para un
juego de video. De tal manera que ser necesario tener una variable que sea la responsable de
llevar el conteo del numero total de naves existentes, de tal manera que al momento
de que sean destruidas se decrementa el nmero de naves a ser visualizadas.

#include <iostream>
using namespace std;

class Nave
{
int id; // es privada por defecto (default)

public:
static int total;
Nave() { total++; }
~Nave() { total--; }
};

int Nave::total = 0;

int main()
{
Nave a;
Nave *b = new Nave;
cout << " numero de naves " << a.total;
delete b;
cout << " numero de naves " << Nave::total;
system(pause);
return 0;
}

An cuando los datos miembro static parezcan variables globales, estos tienen alcance de
clase. Los miembros static pueden existir incluso si no se tiene ningn objeto de la clase, el
acceso a estos miembros puede ser a travs del operador de alcance de miembros ::.

Tambin es posible crear funciones static, slo que estas funciones nicamente podrn
alcanzar miembros del mismo tipo.

Programacin I | 2016


#include <iostream>
using namespace std;

class Nave
{
int id; // es privada por defecto (default)

public:
static int total;
Nave() { total++; }
~Nave() { total--; }
inline static int cuenta() { return total; }
};

int Nave::total = 0;

int main()
{
Nave a;
Nave *b = new Nave;
cout << " numero de naves " << a.cuenta();
delete b;
cout << " numero de naves " << Nave::cuenta();
system(pause);
return 0;
}


9.3 Funciones y objetos constantes ( const )

Algunos objetos o variables quizs no requieren modificaciones, para estos casos se emplea el
modificador const, que especfica que un objeto o variable no puede ser modificado.

Un caso tpico en programacin seria el uso de una variable const como PI, cuyo valor siempre
debe ser constante y nunca modificado:

const double PI = 3.141592;

Este tipo de variables pueden ser declaradas de manera global o a nivel de funcin, segn se
requiera y solo pueden ser inicializadas.

Tambin es posible crear objetos constantes, de la misma manera que las variables
const, debern ser inicializados y sus datos miembro no podrn ser modificados. El nico
inconveniente es que los compiladores de C++ no permiten las llamadas de funciones miembro
a objetos const, a menos que las funciones miembro por si mismas tambin sean declaradas
const (las funciones miembro const no pueden modificar al objeto).

Veamos nuevamente un ejemplo con la clase Horario, modificando nicamente las funciones
que regresan valor ( Hora(), Minuto(), Segundo() ).

Programacin I | 2016

#include <iostream>
using namespace std;

class Horario {
private:
int hora, minuto, segundo;

public:
Horario( int = 0, int = 0, int = 0); // constructor predeterminado
void ajuste(int, int, int); // permite ajuste de valores

inline void Hora(int h) // asigna una nueva hora
{ hora = (h >= 0 && h < 24) ? h : 0; }
inline void Minuto(int m)
// asigna un nuevo minuto
{ minuto = (m >= 0 && m < 60) ? m : 0; }
inline void Segundo(int s)
// asigna un nuevo segundo
{ segundo = (s >= 0 && s < 60) ? s : 0; }

inline int Hora() const // regresa la hora
{ return hora; }
inline int Minuto() const
// regresa los minutos
{ return minuto; }
inline int Segundo() const
// regresan los segundos
{ return segundo; }

void Militar() const; // despliega en formato HHMM
void Standar(); // despliega en formato HH:MM:SS AM/PM
};

La implementacin del resto de las funciones seria de la siguiente manera, observe como la
funcin Militar( ) se declaro cosnt y se implementa de la misma manera:

Horario::Horario(int hr, int min, int seg) {
ajuste(hr, min, seg);
}

void Horario::ajuste(int h, int m, int s) { Hora(h);
Minuto(m); Segundo(s);
}

void Horario::Militar() const {
cout << (hora < 10 ? "0":"") << hora
<< (minuto < 10 ? "0":"") << minuto << "\n";
}

void Horario::Standar(){
cout << ( ( hora == 0 || hora == 12 ) ? 12 : hora % 12 )
<< ":" << ( minuto < 10 ? "0":"" ) << minuto
<< ":" << (segundo < 10 ? "0":"" ) << segundo
<< ( hora < 12 ? " AM" : " PM");
return;
}

Programacin I | 2016


Ahora usaremos la clase Horario en un programa generando un par de objeto, ahora y
medioDia; observe el comportamiento que presentan los objetos de tipo const al emplear
mtodos normales.

int main()
{
Horario ahora(6);
const Horario medioDia(12);

cout << "horario actual ";
ahora.Militar();
cout << "\n";

/* no se puede modificar un objeto const aun cuando sus funciones miembro no sean const */

medioDia.Hora(16); // error no accesible

cout << "ahora.Hora " << ahora.Hora() << "\n";
cout << "medioDia.minuto " << medioDia.Minuto() << "\n";

/* mismo caso */

medioDia.Standar(); // error no accesible
ahora.Standar(); system(pause); return 0;
}

Los objetos const solo pueden ser disponibles en sus partes const. Los objetos estndar
pueden acceder a cualquiera de los mtodos, incluso a los const. Debido a esta caracterstica
es ms comn no emplear funciones de tipo const, aunque esto depender directamente del
diseador de la clase.


9.3 Funciones y clases amigas ( friend )

En ocasiones es necesario tener una funcin miembro que no forme parte de una clase, pero
que permita manipular los datos privados de la misma, para este caso se emplean las
funciones amigas. Una funcin amiga (freind) de una clase se define fuera del alcance de la
clase, pero tiene derechos de acceso a los miembros privados de la clase. Una funcin o una
clase completa puede ser declarada como amiga.

A continuacin veremos un ejemplo con una clase denominada Complejo, que define el
comportamiento de un numero complejo. Veremos que la funcin suma regresa un valor de
tipo complejo, as que es necesario declarar dicha funcin como amiga (freind) de la clase para
que pueda manipular de manera independiente el contenido de los objetos de tipo complejo.

Programacin I | 2016



#include <iostream>
using namespace std;

class Complejo
{
private:
double real, imag;
friend Complejo suma(Complejo, Complejo);

public:
Complejo(double r = 0, double i = 0) {
real = r;
imag = i;
}
Complejo( const Complejo &c ) {
real = c.real;
imag = c.imag;
}
inline void mostrar(){
cout << real << (imag > 0 ? " + ":" - ")<< imag << "i\n";
}
void captura();
};


Complejo suma(Complejo x, Complejo y)
{
double r = x.real + y.real; double i = x.imag + y.imag; return Complejo( r , i );
}

void Complejo::captura()
{
cout << "real, imaginario "; cin >> this->real; cin.ignore();
cin >> this->imag;
}

Ahora es posible utilizar la funcin suma para manipular los datos privados de los objetos de
tipo complejo.

int main(){
Complejo x(2,5), y, z; cout << "complejo X: "; x.mostrar();
cout << endl;
cout << "valores de Y: ";
y.captura();
z = suma(x,y);
cout << "\n resultado en Z: ";
z.mostrar();
system(pause);
return 0;
}

Programacin I | 2016

Bibliografa

Bjarne Stroustrup, "The C++ Programming Language", Addison-Wesley, second edition, 1991,
ISBN 0-201-53992-6.

Naba Barkakati, Object-Oriented Programming in C++, Sams, first edition, 1992, ISBN 0-672-
22800-9.

Harvey Deitel & Paul Deitel, Cmo programar en C++, Prentice Hall, segunda edicin, 1999,
ISBN 970-17-0254-9.
Naba Barkakati, Turbo C++ Bible, Sams, first edition, 1992, ISBN 0-672-22742-8. WikiPedia
the free encyclopedia, Programming paradigm
http://en.wikipedia.org/wiki/Programming_paradigm

You might also like