PDF de programación - Tema 4 Clases y objetos en C++

Imágen de pdf Tema 4 Clases y objetos en C++

Tema 4 Clases y objetos en C++gráfica de visualizaciones

Publicado el 6 de Febrero del 2019
612 visualizaciones desde el 6 de Febrero del 2019
109,1 KB
20 paginas
Creado hace 18a (27/04/2006)
Tema 4

Clases y objetos en C++

4.1.

Introducción

A lo largo del curso nos hemos encontrado con varias situaciones en las que era necesa-

rio trabajar con datos para los que no existía un tipo predefinido adecuado. Por ejemplo,

programas que debían procesar números racionales, naipes en un juego de cartas, fichas

de clientes, listas de nombres, etc. La solución que hemos adoptado hasta el momento es

definir un nuevo tipo, normalmente una estructura (struct), y definir funciones y proce-

dimientos que procesaran tales estructuras. Esta solución presenta varios inconvenientes

que ilustraremos a continuación.

Supongamos que vamos a escribir un programa C++ en el que necesitamos procesar

fechas. C++ carece de un tipo predefinido adecuado para representar las fechas, de

manera que decidimos definir un tipo TFecha de la siguiente manera:

struct TFecha {

int dia;

// 1..31

int mes;

// 1..12

int anyo;

// 2000...2999

};

Además de definir la estructura TFecha, debemos definir funciones y procedimientos que

soporten operaciones básicas sobre este tipo. Por ejemplo, podemos incluir en nuestro

programa las siguientes declaraciones:

// operaciones basicas para el tipo TFecha

bool laborable(TFecha f);

bool festivo(TFecha f);

void manyana(TFecha& f);

1

E.T.S.I. Telecomunicación

Laboratorio de Programación 2

void ayer(TFecha& f);

int dias_entre(TFecha f1, TFecha f2);

Sería deseable que una vez que hemos definido el tipo TFecha y sus operaciones básicas,

este nuevo tipo se pudiera emplear como si fuera un tipo predefinido de C++. Por

desgracia, esto no es así. La solución adoptada presenta una serie de inconvenientes.

En primer lugar, no hay forma de prohibir a otros programadores el acceso a los

componentes de la estructura que implementa el tipo TFecha. Cualquier programador

puede acceder de forma directa a cualquier campo y modificar su valor. Esto puede hacer

los programas más difíciles de depurar, pues es posible que estos accesos directos a la

estructura no preserven la consistencia de los datos. Por ejemplo, un programador puede

escribir una función como la siguiente:

void pasado_manyana(TFecha& f)

{

}

f.dia= f.dia+2;

Es fácil ver que la función pasado_manyana puede dar lugar a fechas inconsistentes como

el 30 de febrero de 2002. El programador ha olvidado que “pasado mañana” puede ser “el

mes que viene” o incluso “el año que viene”. Si todos los accesos directos a los campos

de TFecha los realiza el programador que definió el tipo y nos encontramos con una fecha

inconsistente, el error debe estar necesariamente localizado en alguna de las operaciones

básicas del tipo.

Otro problema que se deriva de permitir el acceso directo a la estructura es que los

programas se vuelven más difíciles de modificar. Supongamos que decidimos alterar la

estructura interna del tipo TFecha modificando el tipo del campo mes, añadiendo un tipo

enumerado para los meses:

enum TMes {enero, febrero,..., noviembre, diciembre};

struct TFecha {

int dia;

// 1..31

TMes mes;

// enero...diciembre

int anyo;

// 2000...2999

};

Si otro programador había escrito una función como la siguiente:

2

Clases y objetos en C++

void mes_que_viene(TFecha& f)

{

}

f.mes= (f.mes % 12 ) + 1;

ésta dejará de compilar. Si todos los accesos directos a TFecha se han realizado en las

operaciones básicas, sólo éstas necesitan ser modificadas.

Finalmente, otro inconveniente de definir un nuevo tipo mediante una estructura y

una serie de operaciones básicas es la falta de cohesión. No hay forma de ver el tipo

TFecha como un todo, como un conjunto de valores y una serie de operaciones básicas

asociadas. En concreto, no hay forma de establecer explícitamente la relación entre el tipo

TFecha y sus operaciones básicas. Suponemos que la función festivo es una operación

básica del tipo TFecha simplemente porque tiene un argumento de este tipo. Pero, ¿cómo

sabemos si pasado_manyana es o no una operación básica? Y si definimos una función

que toma argumentos de diferentes tipos... ¿a cuál de esos tipos pertenece la función?,

¿de cuál de ellos es una operación básica?

El propósito de las clases en C++ es facilitar al programador una herramienta que le

permita definir un nuevo tipo que se pueda usar como un tipo predefinido de C++. En

particular, las clases de C++ facilitan un mecanismo que permite prohibir los accesos

directos a la representación interna de un tipo, así como indicar claramente cuáles son

las operaciones básicas definidas para el tipo.

4.2. Revisión de conceptos básicos

4.2.1.

Interfaz vs. Implementación

Al definir una clase deben separarse claramente por una parte los detalles del funcio-

namiento interno de la clase, y por otra la forma en que se usa la clase. Esto lo hemos

hecho en pseudo-código distinguiendo entre el interfaz y la implementación de la clase:

INTERFAZ CLASE NombreClase

METODOS

...

FIN NombreClase

IMPLEMENTACION CLASE NombreClase

ATRIBUTOS

3

E.T.S.I. Telecomunicación

Laboratorio de Programación 2

...

METODOS

...

FIN NombreClase

El interfaz puede entenderse como las instrucciones de uso de la clase, mientras que la

implementación contiene (y oculta) los detalles de funcionamiento.

4.2.2.

Implementador vs. Usuario

Es muy importante recordar que un programador puede desempeñar dos papeles di-

ferentes respecto a una clase: implementador y usuario. El programador implementador

de una clase se encarga de definir su interfaz (cabecera de los métodos) y de desarro-

llar los detalles internos de su implementación (atributos y cuerpo de los métodos). El

implementador de una clase tiene acceso total a los objetos de esa clase.

Por otro lado, el programador usuario sólo puede utilizar los objetos de una clase

aplicándoles los métodos definidos en su interfaz. El usuario no tiene acceso directo a los

detalles internos de la implementación.

En las siguientes secciones, veremos cómo definir e implementar clases en C++ (punto

de vista del implementador) y cómo usar una clase C++ (punto de vista del usuario).

4.3. Definición de clases en C++

Desgraciadamente, la división entre interfaz e implementación no es tan limpia en

C++ como en el pseudo-código. Las clases se definen en C++ mediante una construcción

class dividida en dos partes: una parte privada (private) que contiene algunos detalles

de la implementación, y una parte pública (public) que contiene todo el interfaz.

class NombreClase {

private:

// implementacion de la clase

// solamente los atributos

// interfaz de la clase

public:

};

En la parte privada de la construcción class aparecen sólo los atributos de la clase y

algunos tipos intermedios que puedan ser necesarios. En C++, la implementación de los

4

Clases y objetos en C++

métodos de la clase se facilita aparte. En la parte pública, suelen aparecer solamente las

declaraciones (cabeceras) de los métodos de la clase. Por ejemplo, la siguiente es una

definición de la clase CComplejo que representa números complejos:

class CComplejo {

private:

// atributos

double real, imag;

// los metodos se implementan aparte

public:

void asigna_real(double r);

void asigna_imag(double i);

double parte_real();

double parte_imag();

void suma(const CComplejo& a, const CComplejo& b);

};

Los campos real e imag son los atributos de la clase y codifican el estado de un objeto

de la clase CComplejo. Puesto que los atributos están declarados en la parte privada de

la clase, forman parte de la implementación y no es posible acceder a ellos desde fuera

de la clase. Su acceso está restringido: sólo se puede acceder a ellos en la implementación

de los métodos de la clase.

Los métodos que aparecen en la parte pública forman el interfaz de la clase y describen

su comportamiento; es decir, las operaciones que podemos aplicar a un objeto del tipo

CComplejo. En particular, con estos métodos podemos asignar valores a las partes real e

imaginaria, leer las partes real e imaginaria, y sumar dos numeros complejos.

4.4.

Implementación de métodos en C++

Como comentamos anteriormente, la implementación de los métodos de una clase en

C++ se realiza fuera de la construcción class {...}. La sintaxis de la definición de un

método es similar a la de la definición de una función (o procedimiento), excepto que el

nombre del método debe estar precedido por el nombre de la clase de la que forma parte:

void CComplejo::asigna_real(double r)

{

}

// cuerpo del metodo...

5

E.T.S.I. Telecomunicación

Laboratorio de Programación 2

Como puede apreciarse, el método asignar_real no recibe ningún argumento de tipo

CComplejo. ¿Cómo es posible entonces que este método sepa qué número complejo tiene

que modificar? La respuesta es que todos los métodos de la clase CComplejo reciben

como argumento de entrada/salida implícito el complejo al que se va a aplicar el método.

Surge entonces la siguiente pregunta: si este argumento es implícito y no le hemos dado

ningún nombre, ¿cómo accedemos a sus atributos? La respuesta en este caso es que

podemos referirnos a los atributos de este parámetro implícito simplemente escribiendo

los nombres de los atributos, sin referirnos a qué objeto pertenecen. C++ sobreentiende

que nos referimos a los atributos del argumento implícito. Así, el método asigna_real

se implementa como sigue:

void CComplejo::asigna_real(double r)

{

}

real= r;

donde el atributo real que aparece a la izquierda de la asignación es el atributo del

argumento implícito. Incluso un método como parte_imaginaria, que aparentemente

no tiene argumentos, recibe este argumento implícito que representa el objeto al que se

aplica el método:

double CComplejo::parte_imaginaria()

{

}

return imag; // atributo imag del argumento implicito

Por otro lado, un método puede recibir argumentos explícitos de la clase a la que per-

tenece. Por ej
  • Links de descarga
http://lwp-l.com/pdf15088

Comentarios de: Tema 4 Clases y objetos en C++ (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios...
CerrarCerrar
CerrarCerrar
Cerrar

Tienes que ser un usuario registrado para poder insertar imágenes, archivos y/o videos.

Puedes registrarte o validarte desde aquí.

Codigo
Negrita
Subrayado
Tachado
Cursiva
Insertar enlace
Imagen externa
Emoticon
Tabular
Centrar
Titulo
Linea
Disminuir
Aumentar
Vista preliminar
sonreir
dientes
lengua
guiño
enfadado
confundido
llorar
avergonzado
sorprendido
triste
sol
estrella
jarra
camara
taza de cafe
email
beso
bombilla
amor
mal
bien
Es necesario revisar y aceptar las políticas de privacidad