Está en la página 1de 22

UNIVERSIDAD MILITAR NUEVA GRANADA

DEPARTAMENTO DE TECNOLOGÍAS DEL CONOCIMIENTO


MANUAL DE PROGRAMACIÓN II EN C++

FUNDAMENTOS POO
INTRODUCCIÓN:

La solución integral de los problemas de ingeniería necesita competencias en diferentes


áreas del conocimiento, y en este caso particular, el aprendizaje de herramientas eficientes
para el desarrollo de software específico, por parte del estudiante, reviste gran importancia.
Las soluciones de software en la actualidad ofrecen gran versatilidad frente a las soluciones
físicas, dadas sus características de escalabilidad y evolución.

La Programación Orientada a Objetos se hace pertinente para ampliar la visión de los


estudiantes, como programadores, con conceptos de mayor dimensión y abstracción que
les permitan resolver problemas con mayor grado de complejidad y más cercanos a la
realidad. De esta forma un estudiante adquiere habilidades para abordar problemas de
forma integral y puede aplicar el desarrollo e implementación de software en cualquier área,
incluso no relacionada con ingeniería.

El presente documento busca exponer de forma clara los principales conceptos


relacionados con la Programación Orientada a Objetos y mostrar sus principales
aplicaciones, así como ilustrar con ejemplos aplicados a problemas de ingeniería, sus
conocidas ventajas frente a otras técnicas y metodologías de programación.

Objetivos:

General

Presentar los conceptos y aplicaciones de la Programación Orientada a Objetos (POO), las


técnicas de implementación de esta metodología en lenguaje C++ y sus ventajas en el
desarrollo de software de aplicación específica.

Específicos

 Comprender las nociones de la abstracción de datos a través del estudio de los Tipos
de Datos Abstractos (TDA) más utilizados.

 Presentar los conceptos fundamentales de la POO y su implementación en lenguaje


C++. - Presentar la herencia y sus principales características, como una forma de
reutilización de software.

 Estudiar la utilización de apuntadores, como una de las características más poderosas


del lenguaje C++.

 Presentar las técnicas para crear y manipular estructuras dinámicas de datos.

Manual de Programación II – Fundamentos POO Página 1


9. CONCEPTOS BÁSICOS DE PROGRAMACIÓN ORIENTADA A OBJETOS

Introducción

En la vida diaria los seres humanos piensan en objetos. La Programación Orientada a


Objetos (POO) es una forma de realizar programas que utiliza, precisamente, los objetos
como su elemento de construcción fundamental. En esta unidad modular se presentan los
conceptos básicos de la POO y su implementación en el lenguaje C++.

Objetivo General

Presentar los conceptos fundamentales de la POO y su implementación en lenguaje C++.

Objetivos específicos

- Conocer los fundamentos de la POO en el lenguaje C++. - Aprender a diseñar y utilizar


clases y objetos en C++. - Conocer las principales características de la implementación de
clases en el lenguaje C++.

9.1 CONCEPTOS FUNDAMENTALES DE POO

Pensar en objetos es pensar como lo hacemos en la vida real. Si usted mira a su alrededor
lo que ve son objetos, personas, animales, libros, computadores, muebles, edificios, etc. La
Programación Orientada a Objetos (POO) es un estilo de programación que emplea los
objetos como componentes fundamentales para la construcción de programas. Es decir,
realiza un modelado de objetos reales, sus características y comportamiento.

Objetos

Un objeto es una representación detallada, concreta y particular de algo. Corresponden a


los objetos reales del mundo que nos rodea, o a objetos internos del programa. Vistos de
esta manera, son tipos abstractos de datos que están conformados por atributos y funciones
que actúan sobre esos atributos. Es decir, un objeto es una unidad que contiene datos y las
funciones que operan sobre esos datos. A los elementos de un objeto se les conoce como
miembros; las funciones que operan sobre los datos se denominan “funciones miembro” y
los datos se denominan miembros datos.

Los objetos pueden se cualquier entidad del mundo real:

- Objetos físicos:

 Carros
 Barcos
 Personas
 Animales, etc.

- Tipos de datos definidos por el usuario:

Manual de Programación II – Fundamentos POO Página 2


 Hora del día
 Fraccionarios

En C++ un programa consta de objetos. Los objetos de un programa se comunican entre sí


mediante el paso o envío de mensajes (acciones que debe ejecutar el objeto).

Adicionalmente, un objeto tiene una identidad que determina su estado y su


comportamiento particular en un momento dado. Dicha identidad permite diferenciar objetos
entre sí. Por otro lado, el estado de un objeto es el conjunto de valores concretos que lo
caracterizan en un momento dado.

Mensajes

Los objetos de un programa se comunican entre sí mediante el paso o envío de mensajes.


Estos mensajes producen la ejecución de las funciones de los objetos. Sin embargo, los
objetos se ocultan información entre sí, es decir, en general un objeto no sabe cómo está
implementado otro objeto diferente.

Clases

La definición de objeto nos lleva a una de los conceptos fundamentales de la POO que es
el de clase. Una clase se puede considerar como un patrón para construir objetos, es decir,
son tipos de datos definidos por el programador, quien determina las estructuras de datos
y las operaciones asociadas con ese tipo.

En C++, un objeto es sólo un tipo de variable de una clase determinada. Cada vez que se
construye un objeto de una clase, se crea una instancia de esa clase. Así como a una
instancia del tipo predefinido double se le llama variable, una instancia de una clase es el
objeto. Por consiguiente, una clase define las propiedades y comportamiento de un tipo de
objeto concreto. La instanciación es la lectura de estas definiciones y la creación de un
objeto a partir de ellas.

Es importante diferenciar entre objetos y clases, una clase es una colección de objetos
similares y un objeto es una instancia de una definición de una clase. La clase es
simplemente una declaración, no tiene asociado ningún objeto, de modo que no puede
recibir mensajes ni procesarlos, esto únicamente lo hacen los objetos.

Herencia

La herencia es la propiedad que permite la creación de clases a partir de clases que ya


existen, las cuales heredan características y funciones de las clases existentes. En C++ la
clase original se llama clase base; y las clases definidas a partir de dicha clase base se
denominan clases derivadas. Las clases derivadas pueden heredar atributos de la base,
pero también pueden adicionar sus propias características y funciones.

La herencia produce relaciones jerárquicas entre las clases, pues existen clases hijas y
padres. Dependiendo del tipo de herencia existen clases que reciben características de una
sola clase (herencia simple) y otras clases que reciben atributos de más de una clase base
(herencia múltiple).

Manual de Programación II – Fundamentos POO Página 3


Lenguaje Unificado de Modelado (UML)

El UML es un lenguaje gráfico utilizado para representar los programas orientados a objetos
de manera visual. Representa las relaciones entre clases bases y clases derivadas, así
como entre objetos.

Polimorfismo

Es una característica de la POO que describe el hecho de que una función puede tener un
comportamiento diferente dependiendo del tipo de objeto sobre el cual esté actuando. Por
ejemplo, se puede definir la función multiplicar como la multiplicación entre dos números
escalares, así como la multiplicación entre dos matrices.

Programa orientado a objetos


Un programa orientado a objetos se puede ver como un conjunto de clases. Debe tener una
función principal que se encarga de la creación de los objetos y comienza la ejecución de
las funciones de dichos objetos.

La ejecución de un programa orientado a objetos consta fundamentalmente de tres pasos:

1. Creación de los objetos en el momento en el que se necesiten.


2. Envío y recepción de mensajes entre objetos.
3. Eliminación de los objetos que ya no son necesarios.

9.2 CLASES

La programación orientada a objetos encapsula atributos y operaciones en clases. Una


clase es un tipo abstracto de dato definido por el usuario que está conformado por atributos
y operaciones. En C++ los atributos son implementados como datos mientras que las
operaciones son funciones.

Así como un plano permite la construcción de varias casas, a partir de una clase se pueden
crear varios objetos. Por consiguiente, los objetos son las instancias de las clases, cada
que se construye un objeto de una clase, se está creando una instancia de dicha clase. Por
esta razón, se utilizan indistintamente los términos objeto e instancia de una clase.

Generalmente, las clases se denominan con sustantivos abstractos, como por ejemplo
Animal, Persona, Factura, entre otros.

Ejemplo:

Podemos tener, por ejemplo, una clase denominada Gato con determinadas propiedades y
comportamientos. Una vez creada dicha clase podemos crear dos instancias una llamada
"Garfield" y otra llamada “Mimi” que tendrán ciertas propiedades específicas y los
comportamientos de dicha clase. Los atributos de la clase Gato podrían ser: sexo, color,
raza y nivel de cansancio. Por su parte, las operaciones de Gato podrían ser: paseo, quieto
y muerte.

Manual de Programación II – Fundamentos POO Página 4


Algunas de las principales características de las clases son:

Abstracción:

La abstracción de datos permite no preocuparse de los detalles no esenciales. Al tener un


conjunto de objetos con características similares, su comportamiento e información puede
abstraerse en una sola clase abstracta o interfaz para recoger estas semejanzas. La
abstracción desde el punto de vista de la POO expresa las características esenciales de un
objeto, las cuales lo diferencian de los demás, y permiten determinar límites conceptuales
entre objetos y entre clases. De esta manera, la abstracción minimiza la cantidad de
características que definen a un objeto y evita repetición de código.

La abstracción en POO surge del hecho de que cada clase del programa es un modelo de
un "agente" abstracto que puede realizar funciones, informar y cambiar su estado, y
"comunicarse" con otras clases en el sistema sin revelar cómo se implementan estas
características. Los procesos, las funciones o los métodos pueden también ser abstraídos
y cuando lo están, una variedad de técnicas son requeridas para ampliar una abstracción.

Encapsulamiento:

Las clases tienen la propiedad de ocultar información a otras clases. El encapsulamiento


hace referencia a que los atributos de un objeto solo pueden ser modificados por otro objeto
a través de mensajes explícitos enviados por el primero. Es decir, un objeto no puede
modificar la información de otro directamente, aunque pueden comunicarse entre sí a través
de interfaces.

El encapsulamiento consiste en ocultar los detalles de la implementación de un objeto, a la


vez que se provee una interfaz pública por medio de sus métodos permitidos. También se
define como la propiedad de los objetos de permitir acceso a su estado solamente a través
de su interfaz o de relaciones preestablecidas con otros objetos.

Polimorfismo:

Esta propiedad se refiere al hecho de que una misma función puede tener comportamientos
diferentes y estar asociada a objetos distintos.

Herencia:

Las clases no están aisladas, sino que se relacionan entre sí, formando una jerarquía de
clasificación. Los objetos heredan las propiedades y el comportamiento de todas las clases
a las que pertenecen. La herencia organiza y facilita el polimorfismo y el encapsulamiento
permitiendo a los objetos ser definidos y creados como tipos especializados de objetos
preexistentes. Estos pueden compartir (y extender) su comportamiento sin tener que re-
implementar su comportamiento. Esto suele hacerse habitualmente agrupando los objetos
en clases y estas en árboles o enrejados que reflejan un comportamiento común. Cuando
un objeto hereda de más de una clase se dice que hay herencia múltiple.

Persistencia:

Manual de Programación II – Fundamentos POO Página 5


Hace referencia al tiempo que un objeto es mantenido en memoria y puede ser utilizado por
aplicación sin ser destruido. Cuando un objeto deja de ser necesario, éste puede ser
destruido y la memoria que utilizaba puede devolverse al sistema para ser utilizado por la
misma u otra aplicación.

La definición de una clase consta de dos partes: una declaración y una implementación. La
declaración es la lista de los miembros de la clase. La implementación o cuerpo define las
funciones de la clase. A continuación, se describen cada uno de estos pasos.

9.2.1 DECLARACIÓN DE UNA CLASE

Las clases están conformadas por un conjunto de características y de funciones, las cuales
son equivalentes a las funciones en los lenguajes estructurados. Se diferencian de ellos en
que es posible acceder a las variables de la clase de forma implícita. A los atributos se les
conoce como miembros dato y son las características que describen el objeto. Las
funciones son conocidas en C++ como función miembro o como métodos en otros lenguajes
de programación. Dichas funciones pueden estar relacionadas entre sí, modificar el estado
del objeto o invocar funcionalidades de otros objetos, entre otras cosas.

Una clase se puede definir con struct, union o class pero la forma que caracteriza la POO
es utilizar la palabra reservada class. La sintaxis de una clase es:

//Sintaxis de la declaración de una clase

class nombre_clase
{
membro_dato1;
miembro_dato2;
...
funcion_miembro1();
funcion_miembro2();
...
};

Como se puede ver una clase es sintácticamente igual a una estructura, con la única
diferencia de que en el tipo class todos los miembros son por defecto privados mientras que
en el tipo struct son por defecto públicos. Suponga que usted va a desarrollar un programa
para manejas el inventario de su empresa. Para esto definiremos una clase de tipo elemento
cuyos miembros datos podrían ser: nombre, marca y cantidad; sus funciones podrían ser
simplemente aumentar cantidad y disminuir cantidad.

class elemento {
char nom[20];
char marca[20];
int cantidad;

Manual de Programación II – Fundamentos POO Página 6


void aumentar_cantidad(int numero);
void disminuir_cantidad(int numero);
};

Una de las características fundamentales de una clase es ocultar tanta información como
sea posible. Por consiguiente, es necesario imponer ciertas restricciones en el modo en que
se puede manipular una clase y de cómo se pueden utilizar los datos y el código dentro de
una clase.

En la declaración de una clase se utilizan los especificadores de acceso para controlar la


visibilidad de los miembros de una clase, fuera del ámbito de la clase. Los miembros de
una clase pueden ser públicos, privados o protegidos. Las palabras reservadas public,
private y protected se utilizan para controlar el modo de acceso a la clase.

Dentro de una declaración de clase, cada una de estas palabras se puede utilizar para
preceder a una o más declaraciones de los miembros de una clase:

 Acceso público. Los miembros públicos son accesibles por cualquier parte del
programa.

 Acceso protegido. Los miembros protegidos significan que sólo se puede acceder a
ellos por “funciones miembro” dentro de la misma clase y por funciones miembro de
clases derivadas de esta clase.

 Acceso privado. Los miembros privados sólo pueden ser utilizados por las “funciones
miembro” de la clase y las funciones amigas de la clase.

Una clase puede contener partes públicas y partes privadas. Por defecto, todos los
miembros definidos en la clase son privados. Para hacer las partes de una clase públicas
(esto es, accesibles desde cualquier parte del programa) deben declararse después de la
palabra reservada public. Todas las variables o funciones definidas después de public son
accesibles a las restantes funciones del programa. Dado que una característica clave de la
POO es la ocultación de datos, debe tenerse presente que, aunque se pueden tener
variables públicas, desde un punto de vista conceptual se debe tratar de limitar o eliminar
su uso. En su lugar, deben hacerse todos los datos privados y controlar el acceso a ellos a
través de funciones públicas. Considere la clase de tipo artículo que se declara en el
siguiente ejemplo. En ella se tiene dos miembros dato privados y una función miembro
pública.

class articulo
{
private:
float precio;
char nombre[30];

Manual de Programación II – Fundamentos POO Página 7


public:
void indicar();
};

Por defecto u omisión todo lo declarado dentro de una clase es privado y sólo se puede
acceder a ello con las funciones miembro declaradas en el interior de la clase o con
funciones amigas.

Los miembros que se declaran en la sección protegida de una clase sólo pueden ser
accedidos por funciones miembro declaradas dentro de la clase, por funciones amigas o
por funciones miembro de clases derivadas.

A los miembros que se declaran en la región pública de una clase se puede acceder a
través de cualquier objeto de la clase de igual modo que se accede a los miembros de una
estructura en C++.

En el siguiente ejemplo se declara una clase con más miembros que la clase del ejemplo
anterior. Nótese que hay miembros datos cuyo especificador de acceso está sin definir, por
lo cual serán tomados al compilar como miembros dato privados. De igual forma se declara
un miembro dato público. En cuanto a las funciones todas las funciones de la clase son
públicas.

class alfa
{
int x; //miembros dato privados
float y;
char z;
public:
double k; //miembro dato público
void fijar(int,float,char); //funciones miembro públicas
void visualizar();
};

Miembros dato

La lista de miembros dato de una clase puede comprender cualquier tipo válido en C++.
Puede contener tipos primarios, estructuras e incluso apuntadores a cualquier tipo válido.
Los miembros dato pueden ser incluso clases. En cualquier caso, sólo las instancias de
clases definidas o declaradas previamente pueden ser miembros.

Manual de Programación II – Fundamentos POO Página 8


Los miembros dato declarados en la clase se deben considerar equivalentes a campos de
una estructura, no a variables. Tal como las estructuras, se debe declarar un objeto de un
tipo clase y a continuación se inicializan sus miembros dato.

Además de los especificadores de acceso utilizados para definir los miembros de una clase.
Un miembro dato de una clase se puede declarar estático (static). Para un miembro dato,
la designación static significa que existe sólo una instancia de ese miembro. Un miembro
dato estático es compartido por todos los objetos de una clase. A un miembro dato static se
le asigna una zona fija de almacenamiento en tiempo de compilación, al igual que una
variable global, pero el identificador de la variable está dentro de ámbito utilizando
solamente el operador (::) con el nombre de la clase.

Los miembros datos se asignan generalmente con la misma clase de almacenamiento. Para
declarar o inicializar un miembro static se utiliza la misma notación que una variable global.

class ejemplo
{
public:
static int valor; //declarar miembro estático
};

int ejemplo::valor; //definir miembro estático

void main()
{
ejemplo e1,e2;
e1.valor=1;
e2.valor=10;
}

A los miembros dato static se puede acceder:

 Utilizando el operador punto


 Utilizando el operador flecha, si el lado izquierdo es un apuntador a objeto
 Utilizando el identificador de la clase sin referenciar un objeto real:
ejemplo::valor=3;

Los miembros datos static no siempre tienen que ser public.

class ejemplo
{
private:
static int valor; //declarar miembro estático

Manual de Programación II – Fundamentos POO Página 9


};

int ejemplo::valor=5; //definir miembro estático

void main()
{
ejemplo e1;
e1.valor=1; //error: acceso no válido
}

Para acceder a un miembro dato private static se necesita utilizar el operador (::). Otros
medios son:

 A través de una función miembro de la clase


 A través de una función declarada amiga de la clase

Funciones miembro

Una operación de una clase, es un servicio que la clase proporciona a los clientes de la
clase. Por lo general, los objetos no realizan sus operaciones de manera autónoma, sino
que requieren de la recepción de un mensaje que es enviado por un objeto cliente.

Las funciones miembro implementan las operaciones permitidas sobre los tipos de datos
de una clase. Para declarar una función miembro hay que situar su prototipo en el cuerpo
de la clase. No hay que definir la función dentro de la clase; dicha definición puede estar
fuera de la clase e incluso en un archivo independiente, aunque también pueden ser
definidas en línea dentro de la clase.

Las funciones miembro son necesarias para acceder a los datos privados. En general, son
públicas; si no lo fueran, ninguna otra función podría llamarlas. Se pueden declarar para
devolver valores con tipos incluyendo objetos de clases, apuntadores o referencias. Pueden
ser declaradas también para aceptar cualquier número y tipo de argumentos. Los
argumentos por defecto están permitidos, así como la notación de puntos suspensivos.

9.2.2 IMPLEMENTACIÓN DE UNA CLASE

Una vez se ha declarado la clase es necesario definir cada una de las funciones miembro
que ésta contiene. La definición de funciones miembro es muy similar a la definición
ordinaria de función. Tienen una cabecera y un cuerpo y pueden tener tipos y argumentos.
Una de las principales características de las funciones miembro es que éstas por pertenecer
a la clase pueden tener acceso a las componentes privadas de la clase.

Manual de Programación II – Fundamentos POO Página 10


Existen dos opciones para llevar a cabo la implementación de las funciones miembro de las
clases.

 En la primera opción la función de define en línea (inline). Por cada llamada a esta
función, el compilador genera (vuelve a copiar) las diferentes instrucciones de la función,
por consiguiente, no existe una única copia de la función dentro del código, sino que
cada vez que se realiza una llamada a la función se crea una copia de ella en lugar de
invocarla. La ventaja de este tipo de funciones es que el programa se ejecuta más
rápidamente, el inconveniente es que se requiere mayor espacio en memoria para su
ejecución.

Hay dos formas de implementar la declaración en línea. La primera es implementando


la función inmediatamente ésta es declarada y la segunda es haciendo uso de la palabra
reservada inline. En esta última se utiliza el operador de resolución de ámbito (::) para
identificar la clase a la cual pertenece la función

En la siguiente tabla se presenta un ejemplo de las dos formas de implementaciones de


funciones en línea. En la primera celda implementando la función dentro de la
declaración y en la segunda utilizando la palabra reservada inline.

class ejemplo class ejemplo


{ {
int x,y; int x,y;
public: public:
void f() void f();
{ };
cout<<"x="<<x<<" y= "<<y<<endl; inline void ejemplo::f()
} {
}; cout<<"x= "<<x<<" y= "<<y<<endl;
}

 En la segunda opción la función f se llamará con una llamada verdadera de función.


En este caso la función se implanta por fuera de la declaración de la clase. En este
caso también se hace uso del operador de resolución de ámbito (::) para identificar
la clase a la cual pertenece la función. En el siguiente ejemplo se presenta la misma
clase llamada ejemplo del ejemplo anterior pero ahora la función f está
implementada fuera de la declaración.

//Declaración de una clase y definición de función miembro fuera de la clase

class ejemplo
{
int x,y;
public:

Manual de Programación II – Fundamentos POO Página 11


void f();
};

void ejemplo::f()
{
cout<<"x= "<<x<<" y= "<<y<<endl;
}

Esta declaración significa que la función f es miembro de la clase ejemplo. El nombre de la


clase a la cual está asociada la función miembro se añade como prefijo al nombre de la
función. El operador (::) separa el nombre de la clase del nombre de la función. Diferentes
clases pueden tener funciones del mismo nombre y la sintaxis indica la clase asociada con
la definición de la función.

9.3 OBJETOS

Un objeto es un elemento declarado de un tipo clase. Se conoce también como una


instancia de una clase. Los objetos se pueden tratar como cualquier variable C++. La
principal diferencia es que se puede llamar a cualquiera de las funciones que pertenecen a
un objeto, esto es, se puede enviar un mensaje a ella.

La comunicación con el objeto se realiza a través del paso de mensajes. El envío a una
instancia de una clase produce la ejecución de una función miembro. El paso de mensajes
es el término utilizado para referirnos a la invocación o llamada de una función miembro de
un objeto.

Retomando el primer ejemplo de la sección 2.2.1 en donde se tenía la declaración de una


clase de tipo elemento para manejar un inventario un objeto de esta clase se definiría como
todas las variables en C++, de la siguiente manera:

elemento tornillos, tuercas;

De igual forma, haciendo uso del tercer ejemplo de la sección 2.2.1, se definió una clase de
tipo alfa. Una vez definida esta clase, ésta puede ser usada dentro del main() como se
presenta en el siguiente ejemplo. Nótese que en primer lugar se define un objeto del tipo
alfa. Posteriormente se hace uso de las funciones miembros, las cuales se definieron como
públicas y no se produce ningún error. Sin embargo, no se puede acceder a los miembros
privados.

int main()
{
alfa obj; //declaración de un objeto

Manual de Programación II – Fundamentos POO Página 12


obj.fijar(3,2.1,'a'); //invocar a una función miembro
obj.visualizar(); //invocar a una función miembro

obj.x=4; //error: no se puede acceder a datos privados


obj.k=3.2; //válido: k está en la región pública
return 0;
}

9.3.1 ASIGNACIÓN DINÁMICA DE MEMORIA

Los operadores new y delete se pueden utilizar para crear y destruir objetos de una clase,
así como dentro de funciones constructoras y destructoras.

Un objeto de una determinada clase se crea cuando la ejecución del programa entra en el
ámbito en que está definida y se destruye cuando se llega al final del ámbito. Esto es válido
tanto para objetos globales como locales, ya que los objetos globales se crean al comenzar
el programa y se destruyen al salir de él. Sin embargo, se puede crear un objeto también
mediante el operador new, que asigna la memoria necesaria para alojar el objeto y devuelve
su dirección, en forma de puntero, al objeto en cuestión.

Los constructores normalmente implican la aplicación de new.

p =new int(9) //p es un puntero a int inicializado a 9


cadena cad1("hola");
cadena *cad2=new cadena;

Un objeto creado con new no tiene ámbito, es decir, no se destruye automáticamente al


salir fuera del ámbito, sino que existe hasta que se destruye explícitamente mediante el
operador delete.

class cadena
{
char *datos;
public:cadena(int);
~cadena();
};
cadena::cadena(int lon)
{
datos=new char[lon];
}
cadena::~cadena()

Manual de Programación II – Fundamentos POO Página 13


{
delete datos;
}

9.3.2 CONSTRUCTORES

El objetivo de un constructor es el de inicializar un objeto cuando éste es creado.


Asignaremos los valores iniciales así como los procesos que ésta clase deba realizar.

Un constructor es una función especial que sirve para construir o inicializar objetos. En C++
la inicialización de objetos no se puede realizar en el momento en que son declarados; sin
embargo, tiene una característica muy importante y es disponer de una función llamada
constructor que permite inicializar objetos en el momento en que se crean.

Un constructor es una función que sirve para construir un nuevo objeto y asignar valores a
sus miembros dato. Se caracteriza por:

 Tener el mismo nombre de la clase que inicializa


 Puede definirse inline o fuera de la declaración de la clase
 No devuelve valores
 Puede admitir parámetros como cualquier otra función
 Puede existir más de un constructor, e incluso no existir

Si no se define ningún constructor de una clase, el compilador generará un constructor por


defecto. El constructor por defecto no tiene argumentos y simplemente sitúa ceros en cada
byte de las variables instancia de un objeto. Si se definen constructores para una clase, el
constructor por defecto no se genera.

Un constructor del objeto se llama cuando se crea el objeto implícitamente: nunca se llama
explícitamente a las funciones constructoras. Esto significa que se llama cuando se ejecuta
la declaración del objeto. También, para objetos locales, el constructor se llama cada vez
que la declaración del objeto se encuentra. En objetos globales, el constructor se llama
cuando se arranca el programa.

El constructor por defecto es un constructor que no acepta argumentos. Se llama cuando


se define una instancia pero no se especifica un valor inicial.

Se pueden declarar en una clase constructores múltiples, mientras tomen parte diferentes
tipos o número de argumentos. El compilador es entonces capaz de determinar
automáticamente a qué constructor llamar en cada caso, examinando los argumentos. Los
argumentos por defecto se pueden especificar en la declaración del constructor. Los
miembros dato se inicializarán a esos valores por defecto, si ningún otro se especifica.

Ejemplo

Manual de Programación II – Fundamentos POO Página 14


class prueba
{
tipo1 d1;
tipo2 d2;
tipo3 d3;
public:
prueba(tipo1 p1, tipo2 p2, tipo3 p3):d1(p1),d2(p2),d3(p3)
{ }
};

Un constructor que crea un nuevo objeto a partir de uno existente se llama constructor
copiador o de copia. El constructor de copias tiene sólo un argumento: una referencia
constante a un objeto de la misma clase. Un constructor copiador de una clase complejo
es:

complejo::complejo(const complejo &fuente)


{
real=fuente.real;
imag=fuente.imag;
}

Si no se incluye un constructor de copia, el compilador creará un constructor de copia por


defecto. Este sistema funciona de un modo correcto en la mayoría de los casos, aunque en
ocasiones puede producir dificultades. El constructor de copia por defecto inicializa cada
elemento de datos del objeto a la izquierda del operador = al valor del elemento dato
equivalente del objeto de la derecha del operador =.

9.3.3 DESTRUCTORES

Un destructor es una función miembro con igual nombre que la clase, pero precedido por el
carácter ~. Una clase sólo tiene una función destructora que, no tiene argumentos y no
devuelve ningún tipo. Un destructor realiza la operación opuesta de un constructor,
limpiando el almacenamiento asignado a los objetos cuando se crean. C++ permite sólo un
destructor por clase. El compilador llama automáticamente a un destructor del objeto
cuando el objeto sale fuera del ámbito. Si un destructor no se define en una clase, se creará
por defecto un destructor que no hace nada. Normalmente los destructores se declaran
public.

Considere el siguiente ejemplo en el cual se crea la clase cadena con su constructor y


destructor correspondiente.

Manual de Programación II – Fundamentos POO Página 15


class cadena {
public:
cadena(); // Constructor por defecto
~cadena(); // Destructor

void Asignar(char *dest);


char *Leer(char *c);
private:
char *cad; // Puntero a char: cadena de caracteres
};

cadena::cadena() : cad(NULL) {}

cadena::~cadena() {
delete[] cad; // Libera la memoria reservada a cad
}

void cadena::Asignar(char *dest) {


// Eliminamos la cadena actual:
delete[] cad;
// Reservamos memoria para la nueva y la almacenamos
cad = new char[strlen(dest)+1];
// Reserva memoria para la cadena
strcpy(cad, dest); // Almacena la cadena
}

char *cadena::Leer(char *c) {


strcpy(c, cad);
return c;
}

9.3.4 SOBRECARGA DE FUNCIONES Y OPERADORES

C++ proporciona las herramientas necesarias que permiten definir funciones y operadores
que utilizan el mismo nombre o símbolo que una función u operador incorporado. Esto se
conoce como sobrecarga de funciones o sobrecarga de operadores. Estas funciones y
operadores se dicen que están sobrecargados y se pueden utilizar para redefinir una
función u operador definido.

Sobrecarga de funciones

Dos funciones pueden tener el mismo nombre, pero tener una implementación y
argumentos de entrada y variables de retorno diferentes. Esta característica se conoce

Manual de Programación II – Fundamentos POO Página 16


como sobrecarga de funciones. Por consiguiente, cuando se habla de una función
sobrecargada se hace referencia a una función que tiene más de una definición.

Las funciones sobrecargadas suelen diferenciarse por el número y tipo de argumentos,


aunque también hay funciones sobrecargadas que devuelven tipos distintos.

En la programación orientada a objetos las funciones sobrecargadas suelen utilizarse para


las funciones miembro y constructora de la clase. Cuando más de una función miembro con
igual nombre se declara en una clase, se dice que el nombre de la función está
sobrecargado en esa clase.

Considere el mismo ejemplo del numeral anterior. Ahora vamos a sobrecargar la función
constructora de la clase cadena.

class cadena {
public:
cadena(); // Constructor por defecto
cadena(char *c); // Constructor desde cadena c
cadena(int n); // Constructor de cadena de n caracteres
cadena(const cadena &); // Constructor copia
~cadena(); // Destructor

void Asignar(char *dest);


char *Leer(char *c);
private:
char *cad; // Puntero a char: cadena de caracteres
};

cadena::cadena() : cad(NULL) {}

cadena::cadena(char *c) {
cad = new char[strlen(c)+1];// Reserva memoria para cadena
strcpy(cad, c); // Almacena la cadena
}

cadena::cadena(int n) {
cad = new char[n+1]; // Reserva memoria para n caracteres
cad[0] = 0; // Cadena vacía
}

cadena::cadena(const cadena &Cad) {


// Reservamos memoria para la nueva y la almacenamos
cad = new char[strlen(Cad.cad)+1];
// Reserva memoria para cadena
strcpy(cad, Cad.cad); // Almacena la cadena
}

Manual de Programación II – Fundamentos POO Página 17


cadena::~cadena() {
delete[] cad; // Libera la memoria reservada a cad
}

void cadena::Asignar(char *dest) {


// Eliminamos la cadena actual:
delete[] cad;
// Reservamos memoria para la nueva y la almacenamos
cad = new char[strlen(dest)+1];
// Reserva memoria para la cadena
strcpy(cad, dest); // Almacena la cadena
}
char *cadena::Leer(char *c) {
strcpy(c, cad);
return c;
}

Sobrecarga de operadores

De modo análogo a la sobrecarga de funciones, la sobrecarga de operadores permite al


programador dar nuevos significados a los símbolos de los operadores existentes en C++.
C++ permite a los programadores sobrecargar a los operadores para tipos abstractos de
datos.

Operadores que se pueden sobrecargar: +, -, *, /, %, ^, &, |, _, ', =, <, >, <=, >=, ++, --, <<,
>>, ==, 0, %%, ||, +=, -=, *=, /=, %=, &=, |=, <<=, >>=, [ ], ( ), ->, ->*, new, delete

Si un operador tiene formatos unitarios y binarios (tales como + y &) ambos formatos
pueden ser sobrecargados. Un operador unitario tiene un parámetro, mientras que un
operador binario tiene dos. ¿El único operador ternario, ?:, no se puede sobrecargar.

Existen una serie de operadores que no se pueden sobrecargar: ., ::, ?:, sizeof

La sobrecarga de operadores en C++ tiene una serie de restricciones que es necesario


tener presente a la hora de manejar operadores sobrecargados:

 Se pueden sobrecargar sólo los operadores definidos en C++


 La sobrecarga de operadores funciona sólo cuando se aplica a objetos de una clase
 No se puede cambiar la preferencia o asociatividad de los operadores en C++
 No se puede cambiar un operador binario para funcionar con un único objeto
 No se puede cambiar un operador unitario para funcionar con dos objetos
 No se puede sobrecargar un operador que funcione exclusivamente con punteros

La clave para la sobrecarga de un operador es una función incorporada a C++ que permite
al programador sustituir una función definida por el usuario para uno de los operadores
existentes.

Manual de Programación II – Fundamentos POO Página 18


Para sobrecargar un operador, se debe definir lo que significa la operación relativa a la
clase a la cual se aplica. Para hacer esta operación, se crea una función operador, que
define su acción. El formato general de una función operador es el siguiente: tipo
nombre_clase::operator op (lista_argumentos) {...} , en donde tipo es el tipo del valor
devuelto por la operación especificada. Los operadores sobrecargados, con frecuencia
tienen un valor de retorno que es del mismo tipo que la clase para la cual el operador se
sobrecarga.

Las funciones operador deben ser miembro o amigas de la clase que se está utilizando.

Las funciones operador tienen la misma sintaxis que cualquier otra, excepto que el nombre
de la función es operator op, donde op es el operador que se sobrecarga.

9.4 FUNCIONES AMIGA

Una función amiga es una función no miembro de una clase que puede tener acceso a las
partes privadas de una clase; se debe declarar como amiga de la clase mediante la palabra
reservada friend.

Las funciones amigas se declaran situando su prototipo de función en la clase de la que


son amiga precediéndola con la palabra reservada friend. Por ejemplo:

class cosa
{
int datos;
public:
friend void cargar (cosa& t, int x);
};

void cargar(cosa& t, int x)


{
t.datos=x;
}

Como la función cargar se declara amiga de la clase cosa puede acceder al miembro
privado datos.

Las razones fundamentales para utilizar funciones amigas es que algunas funciones
necesitan acceso privilegiado a más de una clase. Una segunda razón es que las funciones
amigas pasan todos sus argumentos a través de la lista de argumentos y cada valor de
argumento se somete a la conversión de asignación.

Por último, consideremos el siguiente ejemplo en el cual se hace uso de las funciones
amiga. Se puede ver que la clase miclase tiene una función amiga llamada factor que tiene

Manual de Programación II – Fundamentos POO Página 19


acceso inmediato a los datos miembro privados de la clase n y d. Ahí radica la importancia
de definiciones de las funciones amiga.

#include <iostream>
using namespace std;
class miclase{
int n,d;
public:
miclase(int i, int j){n=i;d=j;}
friend int factor(miclase ob);
};
int factor(miclase ob)
{
if (!(ob.n%ob.d))
return 1;
else
return 0;
}
void main()
{
miclase obj1(10,2), obj2(3,2);
if(factor(obj1))
cout << "es factor";
else
cout << "no es factor";
}

9.4.1 CLASES AMIGAS

No sólo puede ser una función, amiga de una clase, también una clase completa puede ser
amiga de otra clase. En este caso todas las funciones de la clase amiga pueden acceder a
las partes privadas de la otra clase.

Una clase amiga puede ser declarada antes de que pueda ser designada como amiga.

class animales;

class hombre
{
public:
friend class animales;
};

class animales

Manual de Programación II – Fundamentos POO Página 20


{//..

};

Cada función miembro de animales es amiga de la clase hombre. La designación de un


amigo puede estar en una sección private o public de una clase.

Resumen

Las clases permiten al programador modelar objetos con atributos y comportamientos. Se


puede utilizar el nombre de una clase como el nombre de un tipo de dato para declarar
instancias de dicha clase conocidas como objetos.

Las definiciones de la clase empiezan con la palabra reservada class. El cuerpo de la


definición se encuentro delimitado a través de llaves ({}).

Cualquier dato o función miembro de tipo public puede ser accedida y utilizada por otras
clases. Las funciones o datos de tipo private solo son accesibles a clases amigas o
miembros de la misma clase.

Los especificadores de acceso a miembros terminan con dos puntos (:).

Un constructor es una función miembro especial con el mismo nombre de la clase que se
encarga de crearla

Actividades complementarias

1. Crear una clase llamada empleado que contenga como dato miembro el nombre y
el número de empleado, y como funciones miembro Leerdatos() y Verdatos() que
lean los datos del teclado y los visualice en pantalla, respectivamente.

2. Cree una clase llamada complejo para realizar aritmética con números complejos.
Los números complejos tienen la forma: a + b – i, en donde a es la parte real y b es
la parte imaginaria.

Utilice variables double para representar los datos de tipo private de la clase, es
decir la parte real e imaginaria. Cree un constructor que permita inicializar un objeto
de esta clase cuando se declare. Proporcione funciones miembro de tipo public para
realizar lo siguiente:

 Suma de dos números complejos: las partes reales se suman juntas y las partes
imaginarias se suman juntas.

Manual de Programación II – Fundamentos POO Página 21


 Resta de dos números complejos: la parte real del operando derecho se resta a
la parte real del operando izquierdo y la parte imaginaria del operando derecho
se resta a la parte imaginaria del operando izquierdo.

 Impresión de números complejos de la forma (a , b) en donde a es la parte real


y b es la parte imaginaria.

Lecturas recomendadas

 SMITH JO ANN, C++ Programación Orientada a Objetos. Editorial Paraninfo, 1999.


Páginas 5 a 45.

 JOYANES, Luis J., Programación en C++, Algoritmos, estructuras de datos y objetos.


Editorial Mc Graw Hill, 2ª Edición 2002. Páginas 265 a 277 y 457 a 477.

Manual de Programación II – Fundamentos POO Página 22

También podría gustarte