Вы находитесь на странице: 1из 376

C++ estndar

Apuntes de Informtica Industrial y Comunicaciones.

Miguel Hernando Gutirrez

Madrid, Junio de 2016


2 PROGRAMACIN C++ Y COMUNICACIONES.

C++ estndar
Apuntes de Informtica Industrial y Comunicaciones.

______________________________________________

MIGUEL HERNANDO GUTIRREZ

Departamento de Electrnica, Automtica e Informtica Industrial

Escuela Tcnica Superior de Ingeniera y Diseo Industrial

UNIVERSIDAD POLITCNICA DE MADRID

MADRID, JUNIO DE 2016

UPM-EUITI-2015. Miguel Hernando.


"El nico modo de hacer un gran trabajo es amar lo que haces.
Si no lo has encontrado todava, sigue buscando
No te acomodes.
Como con todo lo que es propio del corazn,
lo sabrs cuando lo encuentres."

Steve Jobs.

Copyright 2016. Miguel Hernando


Esta obra est licenciada bajo la licencia Creative Commons
Atribucin-NoComercial-SinDerivadas 3.0 Unported (CC BY-NC-ND 3.0). Para ver una copia de esta licencia, visite
http://creativecommons.org/licenses/by-nc-nd/3.0/deed.es o enve una carta a Creative Commons, 444 Castro Street, Suite
900, Mountain View, California, 94041, EE.UU.
Todas las opiniones aqu expresadas son del autor, y no reflejan necesariamente las opiniones de la Universidad
Politcnica de Madrid.
2 PROGRAMACIN C++ Y COMUNICACIONES.

Presentacin

LaasignaturadeinformticaIndustrialycomunicacionessecomponededospartes
algo diferenciadas como el propio nombre de la asignatura indica. Por un lado se pretende
que el estudiante de esta asignatura comience a programar segn una filosofa de
programacin orientada a objetos (POO), para lo cual se ha escogido el paradigma de este
tipo de lenguajes que es C++. Por otro, se pretende informar y formar al estudiante en la
programacin especfica de sistemas de comunicacin, para lo cual es necesario introducir
coneptosrelativosalossistemasdistribuidosylasredes.

Estos apuntes pretenden de forma docente exponer el lenguaje de programacin


C++ pero centrndose especialmente en los mecanismos que este dispone para abordar la
programacin orientada a objetos. De esta forma, aunque se explican muchas de las
posibilidadesadicionalesdellenguaje,secentranenexplicarcondetalleelmodoconelque
C++poneanuestradisposicinelencapsulamiento,laherenciayelpolimorfismo.
Porestemotivo,aspectoscomolasexcepcionesolasplantillassonexplicadosalfinal
delaparterelativaalaexposicindelasintaxisdellenguajeyenmenordetalle,siendopara
laasignaturaunobjetivosecundario.

UPM-EUITI-2015. Miguel Hernando.


Estosapuntesnotienenningninterscomercial,sinopuramentedocente.Parasu
elaboracinsehantomandomuchosejemploseinclusoexplicacionestextualesdeapunteso
cursos tanto escritos en papel como presentes en Internet. Salvo por error, se han ido
incluyendolasreferenciasaestasfuentes.Elordenymododeexposicinsehapensadode
formaqueseanunaherramientaeficientedecaraaexplicaroseguiruncursopresencial.

Porltimo,cualquiererratadetectadaporellectorosugerenciaconstructivaquese
considere oportuna agradecera que me fuera transmitida por correo electrnico a
miguel.hernando@upm.es.


Prof.MiguelHernando
4 PROGRAMACIN C++ Y COMUNICACIONES.

UPM-EUITI-2015. Miguel Hernando.


ndice de contenidos

PRESENTACIN .......................................................................................................... 2
NDICE DE CONTENIDOS............................................................................................ 5
1. INTRODUCCIN A C++ ..................................................................................... 13
1.1. HISTORIA DE C++ ......................................................................................... 18

1.2. LENGUAJES MS RELEVANTES EN LA ACTUALIDAD........................................... 25

1.3. PRIMERAS NOCIONES SOBRE LA PROGRAMACIN ORIENTADA A OBJETOS. ...... 27

Elementos bsicos de la POO. ........................................................................... 28

Caractersticas principales de la POO ................................................................ 29

1.4. ORGANIZACIN DE LOS APUNTES ................................................................... 31

2. MODIFICACIONES MENORES A C EN C++ .................................................... 33


2.1. EXTENSIN DE LOS FICHEROS ....................................................................... 33
6 PROGRAMACIN C++ Y COMUNICACIONES.

2.2. PALABRAS RESERVADAS ............................................................................... 34

2.2.1. Los elementos de C/C++ ....................................................................... 34

2.2.2. Nuevas palabras clave incluidas por C++ ............................................. 35

2.3. NUEVOS OPERADORES.................................................................................. 36

2.4. COMENTARIOS ............................................................................................. 39

2.5. TIPO DE DATOS BOOL .................................................................................... 39

2.6. TIPOS DE DATOS DEFINIDOS POR EL USUARIO ................................................. 40

Simplificacin en la declaracin de estructuras y uniones ................................. 40

Las enumeraciones como tipo de datos ............................................................. 41

Uniones annimas .............................................................................................. 42

2.7. FLEXIBILIDAD EN LA DECLARACIN DE VARIABLES ........................................... 43

Revisin de los tipos de almacenamiento .......................................................... 46

2.8. MODIFICACIONES A LAS FUNCIONES ............................................................... 48

Funciones inline .................................................................................................. 48

Funciones sobrecargadas................................................................................... 50

Parmetros por defecto en una funcin .............................................................. 52

2.9. VARIABLES DE TIPO REFERENCIA. .................................................................. 53

Las referencias como parmetros de una funcin.............................................. 54

La referencia como valor de retorno ................................................................... 56

2.10. RESERVA DINMICA DE MEMORIA: OPERADORES NEW Y DELETE. ..................... 58

El operador new. ................................................................................................. 60

El operador delete ............................................................................................... 62

2.11. ESPACIOS DE NOMBRES. ............................................................................... 62

2.12. OPERACIONES DE ENTRADA Y SALIDA ............................................................ 63

UPM-EUITI-2015. Miguel Hernando.


2.13. EJERCICIOS .............................................................................................. 66

3. EL CONCEPTO DE CLASE ............................................................................... 70


3.1. LAS CLASES EN C++ ..................................................................................... 71

3.2. DEFINICIN DE UNA CLASE ............................................................................ 73

Declaracin de la clase ....................................................................................... 75

Definicin o implementacin de una clase ......................................................... 76

Instanciacin de un objeto de la clase ................................................................ 77

3.3. ENCAPSULAMIENTO ...................................................................................... 77

Clases y mtodos friend ..................................................................................... 81

3.4. CONSTRUCTORES Y DESTRUCTORES ............................................................. 84

Constructores de una clase ................................................................................ 84

Inicializacin de objetos ...................................................................................... 87

El constructor de copia ....................................................................................... 89

El destructor ........................................................................................................ 90

3.5. MTODOS Y OPERADORES SOBRECARGADOS ................................................. 92

Mtodos sobrecargados ..................................................................................... 92

Operadores sobrecargados ................................................................................ 93

Sobrecarga de operadores binarios ................................................................... 95

Sobrecarga de operadores unarios .................................................................. 104

Los operadores [ ] y ( ) ...................................................................................... 108

3.6. MIEMBROS STATIC ...................................................................................... 111

Atributos static................................................................................................... 111

Metodos static ................................................................................................... 114

3.7. EJERCICIOS ................................................................................................ 116


8 PROGRAMACIN C++ Y COMUNICACIONES.

4. LA HERENCIA.................................................................................................. 121
4.1. DEFINICIN DE HERENCIA ............................................................................ 122

El nivel de acceso protected. ............................................................................ 124

Mtodos y atributos ocultos de la clase base ................................................... 127

4.2. CONSTRUCCIN Y DESTRUCCIN DE CLASES DERIVADAS: INICIALIZADOR BASE.


128

4.3. HERENCIA MLTIPLE ................................................................................... 131

4.4. CLASES BASE VIRTUALES ............................................................................ 134

4.5. CONVERSIONES ENTRE OBJETOS DE CLASES BASE Y CLASES DERIVADAS....... 136

4.6. EL CONSTRUCTOR DE COPIA Y EL OPERADOR DE ASIGNACIN ....................... 139

4.7. EJEMPLO.................................................................................................... 142

5. EL POLIMORFISMO ........................................................................................ 154


5.1. SUPERPOSICIN Y SOBRECARGA ................................................................. 154

5.2. POLIMORFISMO........................................................................................... 156

Mtodos virtuales .............................................................................................. 158

Implementacin del mecanismo de virtualidad ................................................. 164

5.3. VIRTUALIDAD EN DESTRUCTORES Y CONSTRUCTORES. ................................. 165

5.4. FUNCIONES VIRTUALES PURAS Y CLASES ABSTRACTAS ................................. 167

5.5. EJEMPLOS .................................................................................................. 170

6. PLANTILLAS .................................................................................................... 174


6.1. INTRODUCCIN ........................................................................................... 175

6.2. CONCEPTO DE PLANTILLA ............................................................................ 176

6.3. PLANTILLAS DE FUNCIONES ......................................................................... 179

Metodos genricos ............................................................................................ 184

Parmetros de la plantilla ................................................................................. 185

UPM-EUITI-2015. Miguel Hernando.


Sobrecarga de funciones genricas ................................................................. 190

6.4. CLASES GENRICAS .................................................................................... 195

Definicin de una clase genrica ...................................................................... 196

Miembros de clases genricas ......................................................................... 201

Miembros estticos ........................................................................................... 202

Mtodos genricos ............................................................................................ 203

Instanciacin de clases genricas .................................................................... 204

Argumentos de la plantilla................................................................................. 206

Punteros y referencias a clases implcitas ........................................................ 207

6.5. CLASES GENRICAS EN LA LIBRERA ESTNDAR ........................................... 208

6.6. EJEMPLO.................................................................................................... 213

7. MANEJO DE EXCEPCIONES Y TRATAMIENTO DE ERRORES .................. 220


7.1. TRATAMIENTO DE EXCEPCIONES EN C++ ..................................................... 221

El bloque "try".................................................................................................... 222

El bloque "catch" ............................................................................................... 223

Lanzamiento de una excepcin " throw " .......................................................... 224

7.2. SECUENCIA DE EJECUCIN DEL MANEJO DE EXCEPCIONES ............................ 225

Relanzar una excepcion ................................................................................... 226

8. BREVE INTRODUCCIN A LA REPRESENTACIN UML............................ 230


8.1. ELEMENTOS DE CONTRUCCIN DE LOS DIAGRAMAS UML .............................. 232

Elementos estructurales ................................................................................... 232

Elementos de comportamiento ......................................................................... 235

Elementos de agrupacin ................................................................................. 235

Elementos de anotacin ................................................................................... 235


10 PROGRAMACIN C++ Y COMUNICACIONES.

Elementos de relacin ...................................................................................... 235

8.2. MODELADO ESTRUCTURAL .......................................................................... 236

8.3. DIAGRAMAS ................................................................................................ 240

9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS ...................................... 245


9.1. FUNCIONES DE UN SISTEMA OPERATIVO ....................................................... 247

Gestin de procesos ......................................................................................... 248

Gestin de la memoria ...................................................................................... 254

Gestin de entradas y salidas........................................................................... 259

Gestin de archivos. ......................................................................................... 261

9.2. SISTEMAS OPERATIVOS DE MICROSOFT ....................................................... 267

Sistema Operativo MS-DOS ............................................................................. 267

El primer entorno grfico Windows ................................................................... 270

Sistema Operativo: Windows 98 ....................................................................... 278

Sistema Operativo: Windows Millenium ........................................................... 282

Sistema Operativo: Windows NT ...................................................................... 283

Sistema Operativo: Windows 2000 ................................................................... 288

Sistema Operativo: Windows XP ...................................................................... 290

Sistema Operativo: Windows Vista ................................................................... 291

Sistema Operativo: Windows 7 ......................................................................... 293

Sistema Operativo: Windows 8 ......................................................................... 295

Sistemas Operativos para pequeos dispositivos: CE, Mobile yPhone ........... 297

9.3. SISTEMA OPERATIVO: UNIX ......................................................................... 301

9.4. SISTEMA OPERATIVO: LINUX ....................................................................... 308

9.5. MQUINAS VIRTUALES ................................................................................. 312

UPM-EUITI-2015. Miguel Hernando.


10. SISTEMAS DISTRIBUIDOS: REDES .......................................................... 313
10.1. FUNDAMENTOS DE REDES. .......................................................................... 313

Definicin y tipos. .............................................................................................. 313

Objetivos de las redes. ..................................................................................... 314

Aplicaciones de las redes. ................................................................................ 315

Arquitecturas de redes ...................................................................................... 316

10.2. MODELO DE REFERENCIA OSI ..................................................................... 317

Capas del modelo OSI. ..................................................................................... 318

Transmisin de datos en el modelo OSI. .......................................................... 320

Terminologa y servicios del modelo OSI ......................................................... 322

Ejemplos de redes ............................................................................................ 325

10.3. PROTOCOLO TCP/IP .................................................................................. 327

10.4. ORGENES Y SERVICIOS DE INTERNET. ......................................................... 336

Origen y evolucin ............................................................................................ 336

Los servicios ms importantes de la Red ......................................................... 337

El lenguaje HTML.............................................................................................. 342

Navegadores. .................................................................................................... 345

11. COMUNICACIN POR SOCKETS.............................................................. 347


11.1. LOS SOCKETS ........................................................................................ 348

11.2. ARQUITECTURA CLIENTE SERVIDOR ................................................. 349

EL SERVIDOR .................................................................................................. 349

EL CLIENTE...................................................................................................... 350

Programa cliente ............................................................................................... 351

Servidor ............................................................................................................. 358


12 PROGRAMACIN C++ Y COMUNICACIONES.

11.3. MODELOS DE CONEXIN CLIENTE-SERVIDOR ............................................... 362

Modelo Simple Cliente-Servidor: Conexin Stream ......................................... 362

Modelo Concurrente Cliente-Servidor: Conexin Stream ................................ 363

Modelo Cliente-Servidor: Conexin Datagram ................................................. 366

ANEXO I. SOLUCIONES A LOS EJERCICIOS. ...................................................... 369


CAPTULO 2 ............................................................................................................. 369

UPM-EUITI-2015. Miguel Hernando.


1. Introduccin a C++

Para poder comprender correctamente estos apuntes de programacin en C++, se


considera que el lector ya tiene unos conocimientos previos del lenguaje C. A la hora de
disear el temario de las asignaturas de informtica de la Escuela Tcnica de Ingenieros
Industriales,seplantecomoobjetivoprincipalelqueelalumnofueracapazdeprogramaren
cualquier lenguaje al finalizar los estudios. Para ello era necesario seleccionar un lenguaje
modelo que permitiera plantear los distintos inconvenientes y tcnicas que se dan en la
programacin.PorestemotivoseseleccionellenguajeCenlasasignaturasdeprimerao
como paradigma de lenguaje procedural y como sistema de acercamiento al modo de
funcionamiento de un ordenador, y C++ como el lenguaje ms representativo de la
programacinorientadaaobjetos(POO).EsimportanteconsiderarqueelIngenieroIndustrial
Electrnico, tiene una clara orientacin al dispositivo fsico, de ah que los lenguajes que
mantienenlacercanaaloselementosconstitutivosdelordenadorseanmsrelevantespara
suformacin,queotrosqueandandounafuncionalidadmayor,sehanalejadodelcontacto
directoconelHardwareoelsistemaoperativo.Camenudoesconsideradounlenguajede
medionivelporestcaracterstica.

Departamento de Electrnica Automtica e Informtica Industrial


14 PROGRAMACIN C++ Y COMUNICACIONES.

Sin embargo, es importante reflejar el hecho de que esta asignatura, Informtica


Industrial, ha sido dividida a su vez en dos partes: una centrada en el proceso de diseo o
ingeniera del software, y otra con el enfoque esencialmente prctico de aprender un
lenguaje con filosofa de POO como es el caso de C++. Como se ver a continuacin, el
proceso de desarrollo de un programa en un lenguaje fuertemente dependiente de la
estructura como es el caso de C++, requiere de un proceso de anlisis y de diseo terico
previomuchomsimportantequeenlaprogramacinprocedural.
La programacin orientada a objetos es una de las ms modernas tcnicas de
programacin buscando como principal objetivo la reduccin del tiempo de desarrollo
aumentandolaeficienciadelprocesodegeneracindelosprogramas.Comoconsecuencia,si
eldiseoprevioescorrecto,enlaPOOlosprogramastienenmenoslneasdecdigoescritas
por el programador, menos bifurcaciones, y sobre todola facilidad de introducir elementos
deprogramaspreviosoescritosporotraspersonas,ascomosuactualizacin.

Sinembargo,paralograrestosresultadosesnecesariounesfuerzodelprogramador
en las fases anteriores a la escritura del programa propiamente dicho. Si as no fuera, los
resultados pueden ser francamente decepcionantes. As, para no llevar a engao, y con la
ideadeameneizarligeramenteunosapuntesquedeporsiprometenserdensos,seincluyea
continuacin una entrevista ficticia que durante un tiempo circulo por los foros de
programacin:

Entrevista al padre del C++
El 1 de Enero de 1998, Bjarne Stroustrup, padre del lenguaje C++, dio una entrevista a la revista
de informtica del IEEE. Naturalmente, los editores pensaron que estaba dando una visin
retrospectiva de los siete aos de diseo orientado a objetos, usando el lenguaje que el mismo haba
creado.

Al finalizar la entrevista, el entrevistador consigui ms de lo que haba pactado en un principio, y


consecuentemente, el editor decidi suprimir los contenidos 'por el bien de la industria'. Pero como
suele suceder, la informacin se filtr... Aqu esta una completa transcripcin de lo que se dijo, no
editado, no ensayado, es decir que no es como las entrevistas planeadas... Lo encontrareis
interesante...

Int: Bien, hace unos pocos aos que cambio el mundo del diseo de software, como se siente
mirando atrs?

BS: En este momento estaba pensando en aquella poca, justo antes de que llegase. La
recuerdas? Todo el mundo escriba en C y el problema era que eran demasiado buenos... Las
Universidades eran demasiado buenas ensendolo tambin. Se estaban graduando programadores
competentes a una velocidad de vrtigo. Esa era la causa del problema.

Int: Problema?

BS: Si, problema. Recuerdas cuando todos programaban en Cobol?

Int: Desde luego. Yo tambin lo hice.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO1. MODIFICACIONES MENORES A C EN C++. 15

BS: Bien, al principio, esos tipos eran como semidioses. Sus salarios eran altos, y eran tratados
como la realeza...

Int: Aquellos fueron buenos tiempos, eh?

BS: Exacto. Pero, que paso? IBM se canso de ello, e invirti millones en entrenar a
programadores, hasta el punto que podas comprar una docena por medio dlar...

Int: Eso es por lo que me fui. Los salarios bajaron en un ao hasta el punto de que el trabajo de
periodista esta mejor pagado.

BS: Exactamente. Bien, lo mismo pas con los programadores de C...

Int: Ya veo, pero adonde quiere llegar?

BS: Bien, un da, mientras estaba sentado en la oficina, pensaba en este pequeo esquema, que
podra inclinar la balanza un poquito. Pens 'Que ocurrira si existiese un lenguaje tan complicado,
tan difcil de aprender, que nadie fuese capaz de inundar el mercado de programadores?' Empec
cogiendo varias ideas del X10, ya sabes, X windows. Es una autentica pesadilla de sistemas
grficos, que solo se ejecutaba en aquellas cosas Sun 3/60... tena todos los ingredientes que yo
buscaba. Una sintaxis ridculamente compleja, funciones oscuras y estructuras pseudo-OO. Incluso
ahora nadie escribe en cdigo nativo para las X-Windows. Motif es el nico camino a seguir si
quieres mantener la cordura.

Int: Esta bromeando?

BS: Ni un pelo. De hecho, existe otro problema... Unix esta escrito en C, Lo que significa que un
programador en C puede convertirse fcilmente en un programador de sistemas. Recuerdas el
dinero que un programador de sistemas sola conseguir?

Int: Puede apostar por ello. Es lo que sola hacer yo...

BS: Ok, por lo tanto, este nuevo lenguaje tena que divorciarse por s mismo de Unix, ocultando
las llamadas al sistema. Esto podra permitir a tipos que solo conocan el DOS ganarse la vida
decentemente...

Int: No me puedo creer que haya dicho eso...

BS: Bueno, ha llovido mucho desde entonces. Ahora creo que la mayora de la gente se habr
figurado que C++ es una perdida de tiempo, pero debo decir que han tardado ms en darse cuenta
de lo que pensaba.

Int: Entonces, que hizo exactamente?

BS: Se supona que tena que ser una broma, nunca pens que la gente se tomase el libro en
serio. Cualquiera con dos dedos de frente puede ver que la programacin orientada a objetos es anti
intuitiva, ilgica e ineficiente...

Int: Qu?!?!

BS: Y como el cdigo reutilizable... cuando has odo de una compaa que reutilice su cdigo?

Int: Bien, nunca, pero...

BS: Entonces estas de acuerdo. Recuerda, algunos lo intentaron al principio. Haba esa
compaa de Oregon, creo que se llamaba Mentor Graphics, que revent intentando reescribir todo
en C++ en el 90 o 91. Lo siento realmente por ellos, pero pens que los dems aprenderan de sus
errores.

Int: Obviamente no lo hicieron, verdad?


16 PROGRAMACIN C++ Y COMUNICACIONES.

BS: Ni lo ms mnimo. El problema es que la mayora de las empresas se callaron sus mayores
disparates, y explicar 30 millones de dlares de perdidas a los accionistas podra haber sido dificil...
Dmosles el reconocimiento que merecen, finalmente consiguieron hacer que funcionase

Int: Lo hicieron? Bien eso demuestra que la OO funciona...

BS: Casi. El ejecutable era tan gigantesco que tardaba unos cinco minutos en cargar en una
estacin de trabajo de HP con 128 MB de RAM. Iba tan rpido como un triciclo. Cre que sera un
escollo insalvable pero nadie se preocupo. SUN y HP estaban demasiado alegres de vender
enormes y poderosas maquinas con gigantescos recursos para ejecutar programas triviales. Ya
sabes, cuando hicimos nuestro primer compilador de C++, en AT&T, compile el clasico 'Hello World',
y no me poda creer el tamao del ejecutable. 2.1 MB.

Int: Qu ?!?!. Bueno, los compiladores han mejorado mucho desde entonces...

BS: Lo han hecho? Intntalo en la ltima versin de C++, la diferencia no ser mayor que medio
mega. Adems existen multitud de ejemplos actuales en todo el mundo. British Telecom tuvo un
desastre mayor en sus manos, pero, afortunadamente, se deshicieron de ello y comenzaron de
nuevo. Tuvieron ms suerte que Australian Telecom. Ahora he odo que Siemens est construyendo
un dinosaurio y se empiezan a preocupar porque los recursos hardware no hacen ms que crecer
para hacer funcionar ejecutables tpicos. No es una delicia la herencia mltiple?

Int: Bien, pero C++ es un lenguaje avanzado...

BS: Realmente crees eso ?!?!?! Te has sentado alguna vez y te has puesto a trabajar en un
proyecto C++? Esto es lo que sucede: Primero he puesto las suficientes trampas para asegurarme
de que solo los proyectos ms triviales funcionen a la primera. Coge la sobrecarga de operadores. Al
final del proyecto casi todos los mdulos lo tienen, normalmente los programadores sienten que
deberan hacerlo as porque es como les ensearon en sus cursos de aprendizaje. El mismo
operador entonces significa cosas diferentes en cada modulo. Intenta poner unos cuantos juntos,
cuando tengas unos cientos de mdulos. Y para la ocultacin de datos. Dios, a veces no puedo parar
de rerme cuando oigo los problemas que algunas empresas han tenido al hacer a sus mdulos
comunicarse entre s. Creo que el trmino 'sinergetico' fue especialmente creado para retorcer un
cuchillo en las costillas del director de proyecto...

Int: Tengo que decir que me siento bastante pasmado por todo esto. Dice que consigui subir el
salario de los programadores? Eso es inmoral.

BS: No del todo. Cada uno tiene su opcin. Yo no esperaba que la cosa se me fuese tanto de las
manos. De cualquier forma acert. C++ se esta muriendo ahora, pero los programadores todava
conservan sus sueldos altos. Especialmente esos pobres diablos que tienen que mantener toda esta
majadera. Comprendes que es imposible mantener un gran modulo en C++ si no lo has escrito tu
mismo?

Int: Como?

BS: Estas fuera de juego, verdad? Recuerdas 'typedef'?

Int: Si, desde luego.

BS: Recuerdas cuanto tiempo se perda buscando a tientas en las cabeceras sola para darse
cuenta de que 'RoofRaised' era un numero de doble precisin? Bien, imagina el tiempo que te
puedes tirar para encontrar todos los typedefs implcitos en todas las clases en un gran proyecto.

Int: En que se basa para creer que ha tenido xito?

BS: Te acuerdas de la duracin media de un proyecto en C?. Unos 6 meses. No mucho para
que un tipo con una mujer e hijos pueda conseguir un nivel de vida decente. Coge el mismo

UPM-EUITI-2015. Miguel Hernando.


CAPTULO1. MODIFICACIONES MENORES A C EN C++. 17

proyecto, realzalo en C++ y que obtienes? Te lo dir. Uno o dos aos. No es grandioso? Mucha ms
seguridad laboral solo por un error de juicio. Y una cosa ms. Las universidades no han estado
enseando C desde hace mucho tiempo, lo que produce un descenso del nmero de buenos
programadores en C. Especialmente de los que saben acerca de la programacin en sistemas Unix.
Cuantos tipos sabran que hacer con un 'malloc', cuando han estado usando 'new' durante estos
aos y nunca se han preocupado de de chequear el cdigo de retorno?. De hecho la mayora de los
programadores en C++ pasan de los codigos que les devuelven las funciones. Que paso con el '-1'?
Al menos sabas que tenas un error, sin enredarte con 'throw', 'catch', 'try'...

Int: Pero seguramente la herencia salve un montn de tiempo?

BS: Lo hace? Te has fijado en la diferencia entre un proyecto en C y el mismo en C++? La etapa
en la que se desarrolla un plan en un proyecto en C++ es tres veces superior. Precisamente para
asegurarse de que todo lo que deba heredarse, lo hace, lo que no, no. Y aun as sigue dando fallos.
Quien ha odo hablar de la prdida de memoria en un programa en C? Ahora se ha creado una
autentica industria especializada en encontrarlas. Muchas empresas se rinden y sacan el producto,
sabiendo que pierde como un colador, simplemente para reducir el gasto de buscar todas esas fugas
de memoria.

Int: Hay herramientas...

BS: La mayora escritas en C++.

Int: Si publicamos esto, probablemente le lincharan. Se da cuenta?

BS: Lo dudo. Como dije, C++ esta en su fase descendente ahora y ninguna compaa en su
sano juicio comenzara un proyecto en C++ sin una prueba piloto. Eso debera convencerles de que
es un camino al desastre. Si no lo hace, entonces se merecen todo lo que les pase. Ya sabes?, yo
intente convencer a Dennis Ritchie a reescribir Unix en C++...

Int: Oh Dios. Que dijo?

BS: Afortunadamente tiene un buen sentido del humor. Creo que tanto l cmo Brian se
figuraban lo que estaba haciendo en aquellos das, y nunca empezaron el proyecto. Me dijo que me
ayudara a escribir una versin en C++ de DOS, si estaba interesado...

Int: Lo estaba?

BS: De hecho ya he escrito DOS en C++, te pasare una demo cuando pueda. Lo tengo
ejecutndose en una Sparc 20 en la sala de ordenadores. Va como un cohete en 4 CPUs, y solo
ocupa 70 megas de disco...

Int: Como se comporta en un PC?

BS: Ahora estas bromeando. No has visto Windows '95? Creo que es mi mayor xito. Casi
acaba con la partida antes de que estuviese preparado

Int: Ya sabes, la idea de Unix++ me ha hecho pensar. Quizs haya alguien ah fuera
intentndolo.

BS: No despus de leer esta entrevista.

Int: Lo siento, pero no nos veo capaces de publicar esto.

BS: Pero es la historia del siglo. Solo quiero ser recordado por mis compaeros programadores,
por lo que he hecho por ellos. Sabes cuanto puede conseguir un programador de C++ hoy da?
18 PROGRAMACIN C++ Y COMUNICACIONES.

Int: Lo ultimo que o fue algo como unos $70 - $80 la hora para uno realmente bueno...

BS: Lo ves? Y se los gana a pulso. Seguir la pista de todo lo que he puesto en C++ no es fcil.
Y como dije anteriormente, todo programador en C++ se siente impulsado por alguna promesa
mistica a usar todos los elementos del lenguaje en cada proyecto. Eso ciertamente me molesta a
veces, aunque sirva a mi propsito original. Casi me ha acabado gustando el lenguaje tras todo este
tiempo.

Int: Quiere decir que no era as antes?.

BS: Lo odiaba. Parece extrao, no estas de acuerdo? Pero cuando los beneficios del libro
empezaron a llegar... bien, te haces una idea...

Int: Solo un minuto. Que hay de las referencias?. Debe admitir que mejoro los punteros de C...

BS: Hmm... Siempre me he preguntado por eso. Originalmente cre que lo haba hecho.
Entonces, un da estaba discutiendo esto con un tipo que escribe en C++ desde el principio. Dijo que
no poda recordar cuales de sus variables estaban o no referenciadas, por lo que siempre usaba
punteros. Dijo que el pequeo asterisco se lo recordaba.

Int: Bien, llegados a este punto suelo decir 'muchas gracias' pero hoy no parece muy adecuado.

BS: Promteme que publicaras esto. Mi conciencia esta dando lo mejor de mi mismo en estos
momentos.

Int: Se lo har saber, pero creo que se lo que dir mi editor...

BS: Quien se lo creera de todas formas?... De todos modos, puedes enviarme una copia de
la cinta?.

Int: Descuide, lo har.


Sorprendido?.Nodejadesermsqueunadelasgraciasquecirculanporlaredde
cuando en cuando. Sin embargo, si que hay algo de verdad en la entrevista por lo que se
animaaquealfinalizarelcursoellectorvuelvaaleerlaparaquepuedacomprendermejorlos
riesgos de una programacin orientada a objetos mal entendida, o de las posibles
consecuenciasqueelmalusodelaspotentesherramientasdeC++puedengenerar.

1.1. Historia de C++


EllenguajeC++provienecomosupropionombreindicadellenguajeC.Estelenguaje
ya estudiado en primer curso, naci en los laboratorios Bell de AT&T de las mentes de
Kernighan y Ritchie en los 70. Su eficiencia y claridad, y la posibilidad de realizar tanto
acciones de bajo como de alto nivel han hecho de este lenguaje el principal tanto en el
mundo del desarrollo de sistemas operativos como de aplicaciones tanto industriales como
deofimtica.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO1. MODIFICACIONES MENORES A C EN C++. 19

Coneltiempoylaexperienciaellenguajefueevolucionandoparadotarlodemayor
eficiencia desde el punto de vista del programador. En 1980 se aaden al lenguaje C
caractersticascomolasclasescomoresultadodelaevolucindelasestructuras,chequeodel
tipo de los argumentos de una funcin y su conversin si es posible etc, dando como
resultadoloqueenesemomentosellamCconclases1.SuautorfueBjarneStroustrup,ya
mencionadoenlaintroduccin,ysedesarrollenlaAT&TBellLaboratories.
En 1983 este lenguaje fue rediseado y comenz a utilizarse fuera de ATT. Se
introdujeron las funciones virtuales, la sobrecarga de funciones y operadores. Tras
refinamientosymodificacionesmenores,estenuevolenguajeaparecidocumentadoylisto
parasuusobajoelnombredeC++.
Posteriormente C++ ha sido ampliamente revisado lo que ha dado lugar a aadir
nuevas caractersticas como la herencia mltiple, las funciones miembro static y const,
miembrosprotected,tiposdedatosgenricosoplantillas,ylamanipulacindeexcepciones.
Se revisaron aspectos de la sobrecarga y manejo de memoria, se incremento la
compatibilidadconC,etc.ElxitoalcanzadoporellenguajefuearrolladorporloquelaATT
sevienlanecesidaddepromoversuestandarizacininternacional.En1989seconvocel
comitdelaANSI2quemstardeentraformarpartedelaestandarizacinISO.Eltrabajo
conjuntodeestoscomitspermitipublicaren1998elestandarISOC++(ISO/IEC14882)de
forma que el lenguaje pas a ser estable y el cdigo generado utilizable por distintos
compiladoresyendistintasplataformas.

Dentro de esta estandarizacin se incluye un conjunto de clases, algoritmos y


plantillasqueconstituyenlalibreraestandardeC++3.Estalibreraintroducefacilidadespara
manejar las entradasy salidas del programa, para la gestin de listas, pilas, colas, vectores,
para tareas de bsqueda y ordenacin de elementos, para el manejo de operaciones
matemticas complejas, gestin de cadenas de caracteres, tipos de datos genricos, etc. A
este conjunto de algoritmos, contenedores y plantillas, se los denomina habitualmente por
lassiglasSTL(StandardTemplateLibrary).
En el mundo de los lenguajes de programacin, para realizar una referencia a los
distintosestndaressesigueunanomenclaturaqueintroduceelsufijodelaestandarizacin

1
Del nombre ingls C with classes.
2
American Nacional Standards Institute.
3
En su traduccin al castellano del trmino library, la palabra ms correcta es biblioteca. Sin
embargo la mayora de los programadores la han traducido por librera, por lo que en estos
apuntes se adoptar esta ltima.
20 PROGRAMACIN C++ Y COMUNICACIONES.

al nombre del lenguaje. De esta forma, al estndar resultante de la norma ISO/IEC 14882
publicadaen1998,seledenominacomoC++98.
Posteriormente existe una nueva especificacin denominada como C++03, como
consecuencia de la aprobacin de la revisin INCITS/ISO/IEC 148822003. En esta, no se
modificalasintaxisyaspectodellenguajeperosiseespecificanaspectosnecesariosparael
desarrollodecompiladores,ylibrerasparaelestndar.
En donde si se produce una variacin del lenguaje que los compiladores han
comenzado a integrar es en el estndar C++11. Aprobado y publicado en Agosto de 2011
como el nuevo estndar. En este caso si que se incluyen variaciones importantes en el
lenguaje,peroconservandocasiprcticamentelacompatibilidadtotalconelestndarC++98.

C++11 incluye varias adiciones al ncleo del lenguaje y extiende la biblioteca


estndardeC++,incorporandounascuantaslibrerascomopartedelestndar.Lasreasdel
ncleo del lenguaje que han sido significativamente mejoradas incluyen el soporte
multithreading(multihilo),elsoportedeprogramacingenrica,lainicializacinuniforme,y
mejorasdelrendimiento.
En los siguientes apuntes nos centraremos en el estndar ms extendido (C++98
C++03) aunque se anotarn algunas variaciones que se consideren relevantes introducidas
porC++11.

El resultado de todo ello es un potente lenguaje de programacin que admite la


programacin procedural (como C) y la programacin orientada a objetos. El resultado es
muchomejorqueC,soportandolaabstraccindedatos,ylaprogramacingenricagraciasa
lasplantillas.

Lostresndicesquemsseutilizanparamedirlapopularidad deunlenguajeenla
actualidad son el TIOBE Programming Community Index, el Languaje Popularity Index, y el
PYPL,esteltimosoportadoporelanlisisrealizadoporGoogleTrends.

En el siguiente grfico se incluye una captura del ndice TIOBE con fecha Enero de
2015.Estendiceestpensadoparadecidirquelenguajedebesaberunprogramadorafecha
actual, y se calcula no por el nmero de lneas de cdigo sino ms bien por el nmero de
programadores y estudiantes de programacin que en la actualidad siguen, programan o
aprendenunlenguaje.
EsimportantedestacarqueObjectiveCesunlenguajeanlogoaC++peropensado
paradesarrollaraplicacionesparadispositivosmvileseimpulsadoporApplecomomediode
programacindesusdispositivos.Sinembargoestamismaempresacomienzaapromocionar
Swiftcomolenguajebsicoycomoconsecuencia,alestartanligadoaunaplataforma,trasun
fuerteboomentornoa2012,latendenciaahoraesalabajafrenteaC++.Encualquiercasoel
mundodeC,C++,C#yObjectiveCconstituyencasiel40%delndice.Siaesoaadimosque

UPM-EUITI-2015. Miguel Hernando.


CAPTULO1. MODIFICACIONES MENORES A C EN C++. 21

un programador de C++ es rpidamente convertible en programador de JAVA por su gran


similitudencuantoamuchosaspectosdelasintaxisydelaestructuracindelprograma,se
puedededucirqueenlaactualidad,nosepuedeconsiderarseriamenteunprogramadorque
nosepaalmenosalgunodeloslenguajesdelafamiliadeC,yenconcretoalmenosunobajo
elparadigmadelaPOO.



Lasiguientegrficamuestralatendenciaqueestoslenguajeshanseguidosegneste
ndicedurantelosltimos10aos:
22 PROGRAMACIN C++ Y COMUNICACIONES.


De forma anloga se puede observar un grfico que refleja la popularidad de los
lenguajessegnelLanguajePopularityIndexcombinandoelnmeroderepositoriospblicos,
discusiones, nmero de bsquedas etc. Unos ndices detallados se pueden ver en
http://langpop.com.Elresumenqueserealizaendichapginavieneaconfirmarlomismo:

UPM-EUITI-2015. Miguel Hernando.


CAPTULO1. MODIFICACIONES MENORES A C EN C++. 23

EstosdatosdiscrepanligeramenteconelmostradoporPYPL.Encualquiercaso,de
nuevo,eltroC,C++,C#juntoconJavasonpredominantes.LadiferenciaentreTIOBEyPYPL
bsicamentesedebeaqueTIOBEcuentaelnmerodepaginaswebquehablandellenguaje
(simplificando mucho) mientras que PYPL se centra en el nmero de visitas y bsquedas
arrojadasporGoogleTrends.UncasocuriosoeseldeObjectiveCquetieneunos20millones
pginasenlawebfrentealos11millonesdeC,sinembargolaslecturasybsquedasdeCson
actualmente30vecesmsenCqueenObjectiveC.


Siesciertoquedurantelaltimapoca,sehaobservadouncrecimientoconstantey
aceptacin de Python como lenguaje de programacin pero an es pronto para saber si
realmente es un lenguaje consolidado, particularmente por el hecho de que vara un
excesivamenteentreversinyversinydequeancarecedeunaespecificacinestndar.Se
observa que es un lenguaje muy usado para el prototipado rpido y para trabajar como
sustitucin de java por su caracterstica multiplataforma y la facilidad de utilizacin de
funcionalidadesexternas.DeigualformaseobservaunimportantecrecimientodeJavaScript,
24 PROGRAMACIN C++ Y COMUNICACIONES.

bsicamente por convertirse en el lenguaje de los navegadores, permitiendo a una pgina


webejecutarautnticasaplicacionesenelentornolocaldelamquina.
Se incluye finalmente el anlisis realizado a finales de 2014 por el IEEE sobre la
popularidaddeloslenguajescombinandondicesyademsdestacandolasplataformaspara
las que fundamentalmente se utiliza el lenguaje (W: web; M: Mviles; D: Escritorio; E:
Sistemasembebidos).


Finalmente, para dar por cerrada la introduccin se reflejan algunos trminos
comnmente adoptados, pero que facilitarn la estructura de la exposicin. La parte de C
incluida en C++ es conocida como C y puede compilarse en C++ sin ningn problema. La
sintaxis y las reglas de edicin en general son iguales, por lo que a las modificaciones
introducidasporC++alaedicindecdigoprocedural(esdecir,comosisetratasedeC)se
lasdenominamodificacionesmenoresyaquesonfcilmenteasumiblesporunprogramador
deC.

Alasmodificacionesintroducidasparasoportarlaprogramacinorientadaaobjetos
ylaprogramacingenrica,selasdenominamodificacionesmayores,puestoquerequieren
parasuusodeuncambioradicalenlafilosofadeprogramacin.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO1. MODIFICACIONES MENORES A C EN C++. 25

Para terminar este captulo de introduccin, se proceder a dar unas primeras


pinceladassobrelaprogramacinorientadaaobjetosquepermitanunsimplemarcosobreel
queirvinculandolosconceptosquesevayanexplicando.

1.2. Lenguajes ms relevantes en la actualidad


JAVA: es un lenguaje basado en clases, orientado a objetos desarrollado por Sun
Microsystemsen1990.ActualmentesoportadoporOracleesunodeloslenguajes
ms demandados y se puede considerar un estndar en la empresa, en contenido
web en juegos y en aplicaciones de mviles. Basicamente ha tenido un especial
impulsoporutilizarAndroidunpseudojavacomolenguajenativo.Lomsimportante
deJavaesqueestdiseadoparatrabajarenmultiplesplatarformas,deformaque
noimportaenquesistemaoperativoseejecutaelprograma.

C: Es un leguaje de propsito general, procedural, desarrollado a comienzos de los


70,ysepuedeconsiderarelmsantiguoyextensamenteutilizado.Enelfondoesla
herramienta bsica que se utiliza para construir otros lenguajes como es Java, C#,
JavaScript o Python. Se utiliza extensamente para construir sistemas operativos y
para sistemas embebidos en donde no existe competidor. Es el lenguaje de las
mquinas.DadoqueeslabasedecasitodosloslengajesesimportanteaprenderCy
C++antesquemoverseaotrosmspopulares.

C++:AC++comoveremosseloconsideraunlenguajeintermedioconcaractersticas
de Orientacin a Objetos. De hecho, como se ver, la razn de ser del lenguaje es
impulsar C al paradigma de la programacin orientada a objetos. Muchisimo
software est construido en C++, en general todos los que requieran de una alta
eficiencia. Se usa bsicamente para software de sistemas, de aplicaciones,
videojuegosyaplicacionestantodeservidorescomodeclientesenparticularlasque
requierandealtapotencia.

C#: (csharp) es un lenguaje desarrollado por Microsoft que intenta combinar los
principiosdeC,C++yJava,yseusabsicamenteeneldesarrollodeprogramaspara
Windows. Su mayor inconveniente es precisamente el constituir un lenguaje
asociadounaplataforma.

ObjetiveC : es un lenguaje de propsito general orientado a objetos y utilizado


principalmenteporlossistemasoperativosdeApple.TantoOSXcomoiOSascomo
sus correspondientes APIs estn en este lenguaje lo cual a provocado su moda en
consonancia con el avance de iphone y los productos Apple. Es un lenguaje de la
dcadadelos80encontradeloquemuchagentepiensa,ypodradecirsequees
msprimitivoencuantoasintaxisyconceptoqueC++.Esunsuperconjuntoestricto
deCporloquees100%compatibleelcdigoCconeste.
26 PROGRAMACIN C++ Y COMUNICACIONES.

PHP: Su nombre provienedel acrnimoProcesadorde Hypertexto. Es un lenguaje


interpretado pensado para correr en el servidor, libre, que fue diseado
especficamenteparaeldesarrollodepginaswebdinmicas(esdecirgeneracinde
cdigohtmlenbaseaunoscontenidoscambiantes)ydesarrollodeaplicaciones.Es
un cdigo directamente incluible en una pgina de cdigo HTML, sin necesidad de
residirenunaseriedeficherosexternos,locuallohaconvertidoenespecialmente
popular como lenguaje de desarrollo de pginas web. Entre otros, es la base de
Wordpress,CodeacademyoFacebook.

Pythonesunlenguajedealtonivel,interpretado,enprincipiopensadoparatrabajar
enlapartedelservidordelossitiosweboenaplicacionesdemviles.Seleconsidera
un lenguaje sencillo para principiantes debido a su facil lectura y su sintaxis
compacta,detalformaqueenmuypocaslineassepuedenhacermuchascosasque
en otros de los lenguajes anteriores conllevaran mucho ms cdigo. Actualmente
destaca su uso en las webs y aplicaciones de Instagram, Pinterest, Biicode, y hay
desarrolladounpotenteyconocidoentornodedesarrollowebDjango.Esutilizado
porGoogle,YahooylaNasacomopartedesucdigo.

Ruby. Es un lenguaje dinmico, interpretado, orientado a objetos, pensado para el


desarrollo de pginas web dinmicas. Su diseo busca la sencillez y facilidad de
escritura. Es la base del entorno Ruby on Rails, que se utiliza en Spotify, Github y
Scribd.AligualquePython,esunbuenlenguajeparaaquellosquecomienzan.

JavaScript.Esunlenguajeinterpretadotantoparaelclientecomoparaelservidor,
desarrolladopor Netscapeyque deriva mucha de su sintaxis de C.En contrade lo
que indica el nombre, no es Java y su desarrollo es paralelo. Puede usarse al igual
queesteultimoparamultiplesplataformaspormediodelintrpretedelnavegador,
yseconsideraesencialparaeldesarrollodelapartemsinteractivayautnomade
lasfuncionesweb.Ultimamentehasufridounfuerteincrementodadoquepermite
por la potencia de los navegadores el desarrollo de juegos que por su naturaleza
funcionan tanto en ordenadores de escritorio como en dispositivos mviles. Est
embebidoenChrome,enSafari,yenlosintrpretesdeAdobe

UPM-EUITI-2015. Miguel Hernando.


CAPTULO1. MODIFICACIONES MENORES A C EN C++. 27

1.3. Primeras nociones sobre la Programacin Orientada a


Objetos.

Como ya se ha ido comentando, la programacin orientada objetos (POO) no
constituye un nuevo sistema de programacin en cuanto a tecnologa sino ms bien como
una nueva filosofa de programacin que posteriormente se ha visto reflejada en distintos
lenguajesydedistintasformas.
Evidentemente la razn principal de la aparicin de C++ es precisamente la
adaptacindeCaestanuevaformadeprogramacin.ElprincipalobjetivodelaPOOeslograr
un cdigo ms reutilizable por lo que se mejora notablemente la eficiencia a la hora de
programar.

Esimportantedestacarquelaaparicindeestemododeprogramacinnoresponde
a un diseo de laboratorio en el que un conjunto de cabezas pensantes se han dedicado a
disear el lenguaje de programacin perfecto, sino que proviene de la extraccin de los
modosdeprogramarquepocoapocosefueronestableciendoentrelosprogramadoresde
los lenguajes estructurados para lograr sistemas ms eficientes y robustos. Es decir, la
mayoradelosmecanismosquesevanapresentarrespondenanecesidadesespecficasdela
programacinprctica.

Antesdeprocederadescribiralgunosdelostrminosbsicosutilizadosencualquier
lenguajedeprogramacinconfilosofadePOOsevaaintroducirunpocolaideadeenque
consiste.

Enloslenguajesestrictamenteprocedurales(C,PASCAL,BASIC)comoseindicaensu
propiadescripcin,elelementoprincipalloconstituyeelalgoritmooprocedimiento.Esdecir,
dealgunamanera,losdatossonunelementoexternoalprogramaylafuncinprincipalde
este es manejarlos. As de forma natural se tiende hacia un sistema centralizado en donde
existe un motor principal dividido en distintos elementos, denominados funciones, que se
encargan de ir manejando ymodificandouna seriededatos que van pasando de unlado a
otro.

Aspodramospensarenunalibreraendondelosdatoscorrespondenaloslibros,y
elencargadodeordenarlosforrarlos,destruirlos,etc.esellibrerocontodossusayudantes.Es
claro que ni el local, ni las estanteras, ni los libros y hojas son responsables de decidir en
dondehandesituarsenideculessuprecioetc.apesardequesonloscontenedoresdela
informacin que determina estas caractersticas. Ser el librero el que al observarlo y
examinarlodecidirsuubicacin,clasificacin,precio,elforro,etc.
28 PROGRAMACIN C++ Y COMUNICACIONES.

En la programacin orientada a objetos el protagonismo pasa de residir en la


algortmica a los datos. Es decir, el elemento importante en el momento de programar lo
constituyenlasunidadesdeinformacin.Cadaunadeestasunidadesescapazderealizarpor
s misma las operaciones que se refieren precisamente a su mbito de informacin. As,
hipotticamentecadalibroescapazdeidentificarsugnero,suvalasuprecio,lacantidadde
forronecesarioparaserrecubierto,eltiempoquecadatipodelectortardarenleerlo,etc.A
su vez estos libros se encuentran en estantes que son responsables de mantener los libros
ordenados alfabticamente, o de realizar operaciones de insercin y extraccin de libros
manteniendo el orden. Un conjunto de estanteras formarn un armario que es capaz de
establecerladistribucindelibrosporestantes,etc.Finalmenteellocaldecidirelmodoen
quelaslibrerassedisponenylostiposdelibrosquealbergarcadaunadeestasestanteras.
Aunquenoesmsqueunejemplomediocre,semuestraahoraalgunadelasventajasdeeste
sistema.
Supongamosqueahoraqueremosaadirunestanteaunarmario.Enelprimercaso
(programacin procedural) habr que reprogramar a todos los empleados y al librero
para que reconozcan a este nuevo elemento. En el segundo caso bastar con agregar una
balda autoordenable a uno de los armarios. Este armario informado de que tiene una
librera ms ser el nico que tendr que reconocerla, sin que el resto de sistemas se vea
afectado.Simplementecuandolelleguenloslibrostendrencuentaestanuevaestantera.
Aadirunnuevoarmarioallocalrequierecambiarbastantescosasenelcdigoprocedural,
especialmentesiestetipodemodificacionesnoestabaprevisto.EnelcasodelaPOOsertan
sencillocomocrearunanuevavariableyasignarleeltipodelibrosquecontenerelmismo
armarioseencargardesuorganizacin.Supngasequesequieremontarahoraunasucursal
de la librera en la planta baja del Corte Ingls en el primer caso habr que modificar el
codigo del corte Ingls para albergar todos los algoritmos y estructuras de datos que
mantienenlossistemasparalagestindelalibrera.EnPOObastarconagregarunobjeto
localdelibreraqueyaseencargadeautogestionarse.
Elejemplonodamsdes,perolaPOOvamuchomslejos,puestoquesiahoraen
vezdetenerunalibreraloquesetieneesunafrutera,lacantidaddecdigoquehayque
modificar es de nuevo mnima, puesto que muchas de las operaciones de organizacin son
anlogas aunque el elemento bsico haya cambiado. Un frutero tendr que clasificar su
mercancaycuidarladeformaparecidaaunlibrero,yesoloaprovechalaPOOcomoseir
viendo.

Elementos bsicos de la POO.


Algunos de los conceptos bsicos que se manejarn a partir de ahora son los
siguientes:

UPM-EUITI-2015. Miguel Hernando.


CAPTULO1. MODIFICACIONES MENORES A C EN C++. 29

Objetos.Unobjetoesunaentidadquetieneunosatributosparticulares(datos)
y unas formas de operar sobre ellos (los mtodos o funciones miembro). Es
decir,unobjetoincluye,porunaparteunaseriedeoperacionesquedefinensu
comportamiento, y una serie de variables manipuladas por esas funciones que
definen su estado. Por ejemplo, una ventana Windows contendr operaciones
comomaximizaryvariablescomoanchoyaltodelaventana.

Clases. Una clase es la definicin de un tipo de objetos. De esta manera, una


claseEmpleadorepresentaratodoslosempleadosdeunaempresa,mientras
queunobjetodeesaclase(tambindenominadoinstancia)representaraauno
deesosempleadosenparticular.

Mtodos.Unmtodoesunafuncinimplementadadentrodeunobjetoconla
finalidadderealizarunaseriedeoperacionessobrelosdatosquecontiene.As,
en el ejemplo anterior, las ventanas de Windows tienen el mtodo maximizar,
minimizar,cerrar,etc.quemodificanelaspectodelaventanaaldibujarse.

Mensajes. Un programa basado en objetos, utiliza como mecanismo de


comunicacinentrelosmismosunaseriedemtodosquepuedenserllamados
poragentesexternosalobjeto.Alaaccindeejecutarmtodosexternamentea
un objeto se le denomina mensaje. Por ejemplo, cuando decimos a Windows
que deseamos ver el escritorio, y que por tanto todas las ventanas abiertas
debenminimizarse,Windowsseencargadeenviarmensajesdeminimizacina
todas las ventanas que en ese momento est gestionando. Cada una de estas
ventanas ejecutarcomo consecuencia sumtodode minimizacin logrndose
deestaformaelresultadobuscado.

Caractersticas principales de la POO


Las principales caractersticas de la POO son: la abstraccin, el encapsulamiento, la
herenciayelpolimorfismo:

Abstraccin.EselmecanismodediseoenlaPOO.Nospermiteextraerdeun
conjuntodeentidadesdatosycomportamientoscomunesparaalmacenarlosen
clases. El ejemplo clsico para entender estas caractersticas se realiza con los
vehculos.Fcilmentesepuedeestablecerunadefinicindevehculocomotodo
aquello que es capaz de transportar personas. En este caso tendremos que
aviones,coches,barcos,triciclosybicicletastienenalgoencomnquedebemos
poderrepresentarenunsistemadeprogramacinorientadoaobjetos.

Encapsulamiento. Mediante esta tcnica conseguiremos que cada clase de


objetosseaunacajanegra,detalmaneraquelosobjetosdeesaclasesepuedan
30 PROGRAMACIN C++ Y COMUNICACIONES.

manipular como unidades bsicas. Los detalles de la implementacin se


encuentran dentro de la clase, mientras que desde el exterior, un objeto ser
simplemente una entidad que responde a una serie de mensajes pblicos
(tambindenominadosinterfazdelaclase).Asparaelcasodelaclasevehculo,
nos interesa saber inicialmente cuantas personas caben, su autonoma, y la
posicinyvelocidadquetieneenundeterminadomomentoysumodificacin.
Nosdaigualqueestutilicegasolina,energanuclearotraccinanimal.

Herencia. Es el mecanismo que nos permite crear clases derivadas


(especializacin) a partir de clases bases (generalizacin). Es decir, podramos
tenerlaclasevehculo(clasebase)ylaclaseavinderivandodelaanterior.
Al especializarse, se agragarn caractersticas y mtodos pblicos a la clase
vehculo.Esdecir,unavin,ademsdetenerpersonasysaberdondeest,nos
puede informar del nmero de motores que tiene, de la altitud a la que se
encuentra,etc.Unalibreradeclases(comolaMFC)noesmsqueunconjunto
dedefinicionesdeclasesinterconectadaspormltiplesrelacionesdeherencia.

Polimorfismo. Esta caracterstica nos permite disponer de mltiples


implementacionesdeunmismomtododeclase,dependiendodelaclaseenla
queserealice.Esdecir,podemosaccederaunavariedaddemtodosdistintos
(conelmismonombre)medianteelmismomecanismodeacceso.Porejemplo,
podremos decirle a cualquier vehculo que se mueva sin importarnos como lo
hace.Elcochearrancarelmotor,meterunamarchaysoltandoelembrague
comenzar a moverse. El avin encender las turbinas, bajar los flaps y
proceder a realizar la operacin de despegue, etc. El caso es que para el que
estconsiderandoelavionyelcochecomovehculos,laoperacinmuvetees
lamisma,yeselobjetoelqueenfuncindeltipoespecficoalquepertenceel
quedecidircomorealizarelmovimiento.EnC++elpolimorfismoseconsigue
mediante la definicin de clases derivadas, funciones virtuales y el uso de
punterosaobjetos.

Otros dos conceptos muy importantes en la POO son relativos a la creacin y


destruccin de objetos. En lenguajes estructurados convencionales, cuando se define una
variable se le reserva espacio en memoria y, si no se inicializa expresamente, se hace por
defecto(porejemplo,enCunavariableglobalsiempreseinicializaa0,perounaautomtica
no, por lo que si no se inicializa expresamente su contenido inicial ser basura); por otra
parte, cuando se destruye una variable (por que se abandona el mbito de su definicin
scope)seliberalamemoriaqueestabaocupando.Siahorahacemoselparalelismoobligado
entre variables y objetos para los lenguajes POO nos daremos cuenta de que deben existir

UPM-EUITI-2015. Miguel Hernando.


CAPTULO1. MODIFICACIONES MENORES A C EN C++. 31

procedimientosespecialesdeconstruccinydestruccindeobjetos.Enconcreto,cadaclase
tienedosfuncionesmiembroespecialesdenominadasconstructorydestructor.

Constructor:Funcinmiembroqueesautomticamenteinvocadacadavezque
se define un objeto, su objetivo es la inicializacin del mismo. Toma el mismo
nombre que la clase, puede recibir parmetros y podemos tener varios
constructoresdefinidos.

Destructor: Funcin miembro invocada automticamente cada vez que se


destruye un objeto. Su objetivo es realizar operaciones como liberacin de
memoria, cerrar ficheros abiertos, etc. Toma el mismo nombre de la clase
comenzado primero por el carcter ~, no toma parmetros y no admite la
sobrecarga(slopuedeexistirunoencadaclase).
En muchos casos, para las clases mas sencillas, podemos encontrar clases que no
tieneconstructorodestructor,ningunodelosdos.EnC++,siempreexistenconstructoresy
destructorespordefectoquerealizanunainicializacin/liberacinestndar.

1.4. Organizacin de los apuntes


EnprimerlugarsededicaruncaptuloaintroducirlasmodificacionesmenoresdeC
que aparecen en C++. Es decir, algunas de las caractersticas que utilizables en una
programacin procedural aporta C++. Seguidamente se dedicar el resto de captulos a ir
explicando ordenadamente los distintos mecanismos que tiene C++ para realizar una
programacin orientada a objetos. Para ello se comenzar explicando en ms detalle el
concepto de clase y de objetos. Una vez establecida la base de lo que es una clase, se
dedicar un captulo a explicar el mecanismo de la herencia tan importante para lograr un
cdigoeficienteyreutilizable.Esteconceptosecompletarconeldesarrollodelpolimorfismo
en C++ que se aborda en el quinto captulo, especialmente interesante si se observa las
consecuenciasqueestetienesobreWindows.UnodelosaspectosmsdesconocidosenC++
(para los programadores nveles) se aborda en el captulo 6 al introducir el concepto de
plantilla.
HastaestepuntolosconceptosdesarrolladossoncomunesaloslenguajesdePOO.
En el captulo siete se proceder a exponer el modo en que C++ realiza las operaciones de
entrada y salida, as como algunos de los objetos y funciones bsicas disponibles en las
libreras estandar con esta finalidad. Para finalizar la parte de los apuntes dedicada a la
exposicindellenguajeC++serealizarunabrevedescripcindelmecanismoparatratarlos
errores:lasexcepciones.
32 PROGRAMACIN C++ Y COMUNICACIONES.

Alolargodelcontenidodeestecursoseirnintercalandoejemplosyaplicacionesde
los conceptos explicados que permitirn a su vez ilustrar aspectos auxiliares de C++. Un
elementoimportanteyquerequerirunaexposicindetalladaenunaasignaturaposterior,
eslarepresentacingrficadeloselementosqueintegranunsistemainformtico.Porellose
hanidointegrandodeformanaturalestosmodesderepresentargrficamenteloselementos
yseincluyeunbreveresumendelosmismosenelcaptulo8.

UPM-EUITI-2015. Miguel Hernando.


2. Modificaciones Menores a C en C++

Antes de proceder a enumerar los cambios introducidos en C al realizar


programacinproceduralenC++, es necesario destacarque algunadeestas modificaciones
estn incluidas en los compiladores actuales de C, puesto que al convivir durante su
desarrolloconlaaparicindeC++seintrodujeronparamejorarlaeficienciaylegibilidaddel
lenguaje.

2.1. Extensin de los ficheros


Elprimercambioquetienequeconocercualquierprogramadoresquelosficheros
fuente de C++ tienen la extensin *.cpp (de C plus plus, que es la forma oral de llamar al
lenguajeeningls),enlugarde*.c.Estadistincinesmuyimportante,puesdeterminanims
ni menos el que se utilice el compilador de C o el de C++. La utilizacin de nombres
incorrectosenlosficherospuededarlugaraerroresduranteelprocesodecompilacin.

En C++ los ficheros de cdigo se terminan con la extensin cpp de forma que el
entornodedesarrollopuededecidirquecompiladorvaautilizar.

Departamento de Electrnica Automtica e Informtica Industrial


34 PROGRAMACIN C++ Y COMUNICACIONES.

2.2. Palabras reservadas


2.2.1. Los elementos de C/C++


Cuandoelcompiladoranalizaunficherodetexto(cdigo)loprimeroquehacees
romperloenelementossignificativos(TOKENS),loqueenloscompiladoressedenomina
comoPARSE.Estoselementosbsicossonlossiguientes:

Punctuators:sonloscaracteresespecialesqueseutilizancomoseparadores
delasdistintasconstruccionesdeunlenguajedeprogramacin:#[]{};:*
=()
Keywords:quesonpalabrasreservadasquesolosepuedenutilizarparalo
queestprevistoporellenguajesalvoqueseanpartedeunliteral(cadena
decaracteres).
Identificators:sonpalabrasqueutilizaremosparadenominaralgodentro
delcdigo,comoporejemploelnombredeunavariable.Losidentificadores
enCyC++sonsensiblesamaysculasyminsculas4,debencomenzarpor
unaletradelalfabetoinglsoelcarcter_,yacontinuacinsepodrn
agregarletrasynmeros,incluyendolabarrabajahastaunmximode31
enANSIC.Obviamentenopodrnsernuncaigualesaunapalabra
reservada.
Literals:Sedenominaasalaespecificacindeunvalorconcretodeuntipo
dedato.
o Numeros:33.14160.314e10.314e+1.3141elf
Mediantesufijospodemosmodificareltipobsicoqueesintpara
lasconstantessinpunto,ydoubleparalasquetienen(Fparafloat)
(Lparalong)(Uparaunsigned).
Medianteprefijospodemosexpresarunmododecodificacin(0x
hexadecimal)(0paraoctal)
o Caracteres:a0\n\\\
o Cadenasdecaracteres.Lascadenasdecaracteresestn
constituidasporunvectodecaracteresexplcitosmsuncarcter
terminadorqueesel\0quecorrespondealvalor0.HolaMundo
\HolaMundoentrecomillas\

4
Case sensitive

UPM-EUITI-2015. Miguel Hernando.


CAPTULO2. MODIFICACIONES MENORES A C EN C++. 35

Operators:Igualqueenmatemticassoncombinacionesdesmbolosoun
smboloquerealizanunaaccinespecficasobreunoomsoperandosy
quehabitualmentedevuelvenunvalor:+*/%>>etc.

Decaraalaescrituradecdigosesuelenseguirunasrefcomendacionesenelusode
identificadores.Seexponenaqubrevementeantesdepasaraverlasnuevaspalabrasclavey
operadoresintroducidosenC++:
o MACROS y DEFINICIONES: todo en maysculas. Si tienen varias palabras
separarlascon_
#define RADIO 3.0F
#define MAX_NUM 3453
o Estructuras y tipos de datos definidos por el usuario: se recomienda
empezarlos con mayscula y poner en mayscula el comienzo de cada
palabraexplicativa
struct PoligonoRegular { } ;
o Funcionesymtodos:comenzarsuidentificadorconunverboenminscula
habitualmente en infinitivo o imperativo, a continuacin cada palabra en
mayscula
void imprimeContenido( )
o Variables:todoenminsculas.Sihayvariaspalabrasseparalaspor_.
int contador = 0, cuenta_cuentos = 0;

2.2.2. Nuevas palabras clave incluidas por C++


AlconjuntodepalabrasclavedeC:

if while char unsigned sizeof


auto long extern continue volatile
double switch return for do
int case union signed static
struct enum const void goto
break register float default short
else typedef

se han aadido las 42 siguientes, por lo que tampoco podrn ser utilizadas como
identificadoresenelcdigo:
36 PROGRAMACIN C++ Y COMUNICACIONES.

and and_eq asm compl new


bool catch class export or_eq
delete dynamic_cast explicit namespace static_cast
friend inline mutable or try
not not_eq operator reinterpret_cast w_char
private protected public true bitor
template this throw virtual false
typeid typename using const_cast bitand
xor xor_eq

Elsignificadodelasmismasseirviendoalolargodelcurso.

2.3. Nuevos operadores


En C++ aparecen nuevos operadores. La utilidad de los mismos se ir viendo a lo
largodelcursopuestoquemuchosdeellosrequierennocionesdelaPOO:

Operador Significado
:: Operadorderesolucindembitodeunavariableofuncinmiembrodeuna
clase.Denominadocomooperadorscope.
this Tomaelvalordeladireccindelelementodesdeelquehasidoinvocado.
& Adicionalmente a los significados en C, se utilizar para definir referencias y
alias.
new Crea un objeto del tipo indicado a continuacin. Modo habitual de reserva
dinmicadememoriaenC++
delete Destruyeunobjetocreadodinmicamenteconeloperadornew
.* Accede al miembro de una clase cuando el miembro es referenciado por un
puntero.
->* Accedealmiembrodeunaclasecuandotantoelmiembrocomolainstanciade
laclaseestnreferenciadosporunpuntero.
typeid Identificacindetipo
???_cast Conversionesforzadasdeltipodeunaexpresin.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO2. MODIFICACIONES MENORES A C EN C++. 37

Losdosmodosdeaccesonuevos(.*y>*),noaparecernmsenestosapuntespor
loqueseincluyeacontinuacinunbreveejemployexplicacindelosmismos.
#include <cstdio>
struct Complex{
float real;
float imag;
};

void main()
{
struct Complex a={0,0}, *b; //creo dos variables de tipo Complex
float Complex::*valor; //defino un puntero a floats de Complex
b=&a;
//le asigno a valor la direccion relativa de la parte real
valor= &Complex::real;
a.*valor=5.0F;
printf("\n%f + %fj",a.real, a.imag);
//le asigno a valor la direccion relativa de la parte imag
valor = &Complex::imag;
b->*valor=3.0F;
printf("\n%f + %fj",a.real, a.imag);
}

Para intentar entenderlo, pensemos que a diferencia de un puntero normal en C,


valor representar puntero relativo. Es decir contiene la direccin de un float relativo a la
direccin de un contenedor. Una estructura de tipo Complex, estar en una posicin de
memoria,digamos1000,porloqueen1000estartambinlapartereal(float)yen1004la
parteimaginaria.Unpunteroaunmiembrodeunaestructura(ymasdelantedeunaclase)se
puede entender como un desplazamiento respecto de la direccin de la estructura. As, el
valorde&Complex::realpodemosdecirquees0,mientrasqueelde&Complex::images4.
Los dos operadores nuevos, nos permitirn aplicar estos tipos de punteros que
codificandireccionesrelativas,alasinstanciasdelasestructurasoalosobjetos.
Comoconsecuenciadelaaparicindelosnuevosoperadores,esnecesariorevisarla
precedenciayasociatividaddetodosellosenC++.
La precedencia nos indica el orden de asociacin de un operador con sus
operadorandos.Deformaqueunoperadorconprecedencia(masaltoenlatablaqueotro)
sobreotro,seagruparantesconsusoperandos.Estoesloqueintuitivamentehacemosen
matemticascuandoencontramossumasyproductosmezclados:5+4*3+8lohacemosdela
formasiguiente:(5+(4*3))+8.Esdecir,elprimeroenasociarseasusoperandosesel*.
38 PROGRAMACIN C++ Y COMUNICACIONES.

Cuandodosoperadorestienenlamismaasociatividad(porejemploporquefueranel
mismo) entonces se sigue la regla de asociatividad, que es de izquierda a derecha o de
derecha a izquierda: 3+5+24+8 lo interpretaremos como (((3+5)+2)4)+8 es decir de
izquieraaderecha.

Prec. Operador Asoc.

1 ::
2 () [] . -> v++ v-- ??? cast
>>
typeid
3 -a +a ~ ! & * ++v v sizeof new
<<
delete (tipo)
4 ->* .* >>
5 a*b a/b a%b >>
6 a+b a-b >>
7 << >> >>
8 < <= > >= >>
9 == != >>
10 a&b >>
11 a^b >>
12 a|b >>
13 && >>
14 || >>
15 a?b:c <<
16 = *= /= %= += -= <<= >>= &= |=
<<
^=
17 , >>

NOTA IMPORTANTE: Tanto en C como en C++ se establece el modo en que se


interpretanlasexpresiones,sinembargonoseestableceelordendeejecucindentrodeun
operador de estas expresiones.. As en la expresin a+b , el estndar deja libertad al
compiladorparadecidirsiobtenerprimeroelvalordeayluegoeldebysumarlosoalrevs.
Lomismoseaplicaalaevaluacindelosparmetrosdeunafuncin.

Lasnicasexcepcionessonparaeloperadorternario,yenlosoperadoreslgicos&&
y||(siendoelordendeizquierdaaderecha).Todoestetemaesunpocomscomplejodado
queademshayqueanalizarsilosefectosdelaexpresinseevalanantesodespus,pero
paraelpuntoenelquenosencontramosessuficienteconestasnociones.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO2. MODIFICACIONES MENORES A C EN C++. 39

2.4. Comentarios
En el C original, la inclusin de comentarios en los ficheros de cdigo vena
delimitado por una combinacin de caracteres de comienzo (/*) y otra de finalizacin de
comentario(*/).Detalformaquetodoeltextocontenidoentreestosdosdelimitadoresera
eliminado por el preprocesador antes de proceder a realizar cualquier operacin de
interpretacin.

En C++ adicionalmente se pueden introducir comentarios de una sola lnea. As,


desdeelmomentoenqueenunalneaapareceeconjuntodecaracteres(//)hastaelfinalde
esalnea,eltextoabarcadoesconsideradocomouncomentario.
Elsiguienteejemplomuestralacombinacindeambostiposdecomentarios.
/* Este es un comentario tpico de C,
en el que se incluyen varias lneas anuladas
por los delimitadores */

void main() // y este es un comentario de C++


{
int i;
for(i=0;i<10;i++)
{
//si quisiera introducir varias lineas
//bastar con introducir la doble barra
// en cada linea, o utilizar /* */
printf("%d",i);
}
}

Es interesante destacara que los comentarios en // han sido introducidos en la


mayoradeloscompiladoresdeCdadalagrancomodidadquesuponenalahoradeanular
lineasdecdigoduranteeldesarrollo.

2.5. Tipo de datos bool



La palabra clave bool declara un nuevo tipo especial de variable, denominada
booleana(0.1)quesolopuedetenerdosvalores:cierto(true)yfalso(false).
bool val = false; // declara val variable Booleana y la inicia
val = true; // ahora se cambia su valor (nueva asignacin)
Laspalabrasclavefalseytruesonliteralesquetienenvalorespredefinidos(podemos
considerar que son objetosde tipo booleano de valor constante predefinido). false tiene el
valorfalso(numricamenteescero),truetieneelvalorcierto(numricamenteesuno).
40 PROGRAMACIN C++ Y COMUNICACIONES.

Tenga en cuenta que los bool y los int son tipos distintos. Sin embargo, cuando es
necesario, el compilador realiza una conversin automtica de forma que pueden utilizarse
librementevaloresbool(trueyfalse)juntoconvaloresintsinutilizarunaconversinexplcita.

int x = 0, y = 5;
if (x == false) printf("x falso.\n"); // Ok.
if (y == true) printf("y cierto.\n"); // Ok.
if ((bool) x == false) printf("x falso.\n"); // cast innecesario

Estasconversionesentretiposlgicosynumricos,sonsimplementeunaconcesin
delC++parapoderaprovecharlagrancantidaddecdigoCexistente.TradicionalmenteenC
sehacacorresponderfalsoconelvalorceroyciertoconelvaloruno(odistintodecero).
Paraconvertirtiposaritmticos(enumeraciones,punterosopunterosamiembrosde
clases)auntipobool,lareglaesquecualquiervalorcero;punteronulo,opunteroamiembro
de clase nulo, se convierte a false. Cualquier otro valor se convierte a true. En principio el
estndar establece que solo los valores enteros son convertidos automticamente siendo
necesariounaconversinexplcitaenotrocaso,sinembargo,amenudo,loscompiladoresno
requierendeestecastporcomodidad.

2.6. Tipos de datos definidos por el usuario

Simplificacin en la declaracin de estructuras y uniones


En C las palabras struct y union forman parte del identificador del tipo de datos
definidoporelusuario.EnC++estosesimplificaeliminandoestaspalabrasenelmomentode
declararlasvariablesoreferirsealtipodedatosdefinido.
ElsiguienteextractodecdigoestescritoenC:
/*declaracin del patrn de la estructura complejo*/
struct complejo
{
float x;
float y;
};

void main()
{
/*peticin de variables*/
int j;
struct complejo micomplejo;
/*cdigo*/

UPM-EUITI-2015. Miguel Hernando.


CAPTULO2. MODIFICACIONES MENORES A C EN C++. 41

j=sizeof(struct complejo);
}

ElmismocdigoenC++quedara:
//declaracin del patrn de la estructura complejo
struct complejo
{
float x;
float y;
};

void main()
{
//peticin de variables
int j;
complejo micomplejo;
//cdigo
j=sizeof(complejo);
}

Seobservacomodesdeelpuntodevistadelcdigo,quedamsclaroycmodo.

Las enumeraciones como tipo de datos


EnC++eltipodedatosenumesunnuevotipopuestoqueenClasenumeraciones
erandetipodedatosint.Adiferenciadeloqueocurraentonces,enC++nosepodrasignar
directamenteunenteroaunavariabledetimoenum.Parapoderrealizarestaasignacinser
necesarioindicarlaconversinexplcitamente.

Por otro lado, al igual que ocurra con las estructuras y las uniones, en las
enumeracionessesimplificalaindicacindeltipodurantesuusoprescindiendodelapalabra
enum.

ElsiguienteextractodecdigomuestraunejemplodeunaenumeracinenC++:
enum notas {suspenso, aprobado, bien, notable, sobresaliente};
notas nota1 = bien;
notas nota2;
nota2 = notas(2); //conversin explcita.
// nota2 = 2; sera en C pero que en C++ es incorrecto

Sin embargo, si es posible realizar la asignacin contraria. Es decir, una variable
entera puede recibir el valor de una variable de tipo enumeracin. Por defecto, el nmero
42 PROGRAMACIN C++ Y COMUNICACIONES.

entero asignado a cada uno de los posibles valores de una variable enum van por orden
comenzandodesde0.Deestaforma,suspensovale0,aprobadovale1,bienvale2,etc.Sin
embargo,elprogramadorpuedeestablecerestosvaloresenladefinicindelaenumeracin.
Elsiguientecdigomuestraestasdoscaractersticas:
enum colores {rojo=3,verde=5, azul, amarillo=8};
int i = verde;

Enestecaso,rojovale3,verdevale5,azulvale6yamarillovale8.Esdecir,cuando
explcitamentenosedaunvalor,sesiguelanumeracindelvaloranterior.
Paraayudaraentenderelniveldefuerzaqueestetipodedatostiene,lassiguientes
propiedadessecumplenalahoradeevaluarexpresionescontiposenum:
Nohabrerrorsiaunavariabledetipoenumleasigno(indicandolaconversin)un
valornodefinido:nota2=notas(100)seraunaexpresinvlida.

Se puede asignar el mismo valor numrico a dos elementos de la enumeracin


distintos.

Una enumeracin es promocionable directamente a entero en las expresiones


aritmticas pero realmente no hay definida una aritmtica especfica. Por eso ser posible
utilizar expresiones del tipo entero=entero+enum , entero = enum+entero, o entero =
enum+enum.Puestoquelaoperacinsumanoestdefinidaparalasenumeraciones,ynoes
posible asignar a una enumeracin un valor entero de forma directa, el resultado de estas
operaciones nunca puede ser directamente recibido por una variable de tipo enum sin una
conversinexplcita.

Uniones annimas
Aunque su aplicacin ms inmediata se da en el interior de estructuras ms
complejas,esconvenientemencionaryaqueC++admiteladefinicindeunionesannimas.
Sufinalidadesladedefinirunconjuntodecampos(miembrosenelcasodeclases)ubicados
en la misma zona de memoria. Simplifica el acceso a estos campos evitando el tener que
utilizar, como ocurre en C, el indicador del tipo de acceso sobre la unin. Para visualizar la
variacin,semostrarelmismosegmentodeprogramaescritoenCyenC++:

ElsiguienteprogramaenC:
struct datos /*definicin del patrn de estructuras*/
{
int tipo;
union _dato /*union dentro de la estructura*/
{
char caracter;

UPM-EUITI-2015. Miguel Hernando.


CAPTULO2. MODIFICACIONES MENORES A C EN C++. 43

int entero;
float decimal;
}dato;
};
int main()
{
struct datos midato;
midato.tipo=2;
midato.dato.entero=5;
}

EstemismocdigoescritoenC++quedaracomosigue:
struct datos /*definicin del patrn de estructuras*/
{
int tipo;
union /*union dentro de la estructura*/
{
char caracter;
int entero;
float decimal;
};
};
int main()
{
datos midato;
midato.tipo=2;
midato.entero=5;
}

2.7. Flexibilidad en la declaracin de variables


Las variables locales en C deban ser declaradas al comienzo del bloque de una
funcin,deformaqueelcdigoquedabasiembreestructuradoendoszonas:lapeticinde
variablesyelconjuntodesentenciasejecutablesdecdigo.

En C++ se permite la declaracin de variables en cualquier lugar de un bloque,


entendindosecomobloqueelconjuntodesentenciasencerradasentrellaves{}.

Estoincluyelaposibilidaddedeclararvariablesenelinteriordeunasentenciacomo
semostrarenlosejemplossiguientes:
void funcion(void)
{
int i=8;
44 PROGRAMACIN C++ Y COMUNICACIONES.

for(int j=0;j<i;j++)
{
printf(Hola mundo);
int k=3;
printf(valor de k %d,k);
}
if(--i==0)return;
}

EnCquedabaclarocualeraelmbitodeunavariable,puestoqueunavariablelocal
eravisibledesdetodoelcuerpodelafuncinenlaqueestabadefinida,yunavariableglobal
loeradesdeelpuntoenelqueestabaenelcdigoenadelante.

En C++, el mbito de una variable es desde el punto en el que esta est declarada
hastaelfinaldelbloqueenelqueseencuentra.

En el caso de las variables globales el criterio es el mismo que en C. El siguiente


ejemplopuedeaclararesto:
int val=2;
printf(%d,val); //se imprime 2
for(int i=0;i<10;i++)
{
printf(%d,val); //se imprime 2
int val=3;
printf(%d,val); //se imprime 3
}
printf(%d,val); // se imprime 2

UnavariablelocalocultaaligualqueenCaunavariablemsglobalrelativamente.


Es decir, bajo un mismo nombre, las variable que se considerar ser la ms local
entrelasvisibles.

C++ dispone del operador (::), llamado operador de resolucin de visibilidad. Este
operador,antepuestoalnombredeunavariableglobalqueestocultaporunavariablelocal
delmismonombre,permiteaccederalvalordelavariableglobal.Noesposible,sinembargo,
acceder a una variable local que est oculta por otra variable local. El siguiente ejemplo
muestraelmododeusodeeloperadorscope.

int i=0;

UPM-EUITI-2015. Miguel Hernando.


CAPTULO2. MODIFICACIONES MENORES A C EN C++. 45

void main()
{
int i;
while(::i<10)
{
++::i;
for(i=0;i<10;i++)
printf(%d : %d\n,::i,i);
}
return 1;
}

Enesteprogramaseharealizadolaanidacindedosbuclescondositeradoresdel
mismonombre,unoglobalyotrolocal.

Portimo,laduracindelasvariableslocales(auto)serelbloqueenelqueestn
definidas.Esdecir,quelavariableesdestruidaenelmomentoenquesefinalizalaejecucin
delbloqueenelqueseencuentrasudeclaracin.Esposibledefinirvariablesestticasaligual
que en C, de forma que una variable local definida como esttica (static) no es destruida
hastaelfinaldelprograma,yportantosloescreadalaprimeravezqueseejecutaelbloque
enelqueseencuentrasudeclaracin.

Hay que tener precaucin a la hora de utilizar declaraciones de variables en el


interiordeunswitch,puestoqueenestecasonoexistenbloquesdiferenciadossinodistintos
puntosdeacceso.Estoprovocaelquenoserealicelainicializacindeunavariabledentrode
un bloque, o que se produzca una doble definicin de una variable. El siguiente ejemplo
muestraunadeclaracinerrnea,ysusolucin:

int main()
{
int i=2;
float v;
switch (i)
{
case 3:
int i=5;
break;
case 2:
v=3.5F;
for(int i=0;i<10;i++)v=1.0F;
default:
v=3.0F;
break;
46 PROGRAMACIN C++ Y COMUNICACIONES.

}
}

Elcompiladorarrojalossiguienteserrores:

1. Lainicializacindeiesevitadaporlasetiquetascase.
2. Lainicializacindeiesevitadaporlasetiquetadefault.
3. Redefinicindei.
La forma ms sencilla de evitar este error sin modificar el nmero de variables
localesdelprograma,esestablecerenelinteriordecadacasounbloque:
int main()
{
int i=2;
float v;
switch (i)
{
case 3:
{int i=5;}
break;
case 2:
{
v=3.5F;
for(int i=0;i<10;i++)v=1.0F;
}
default:
v=3.0F;
break;
}
}

Revisin de los tipos de almacenamiento5


C++ dispone de los siguientes especificadores de tipo de almacenamiento: auto,
extern,staticyregister.Ademsalgunosmodificadores:const,volatileymutable.Comoya
sehavisto,todosellossonpalabrasclavedellenguaje.

5
Este apartado ha sido extraido y reformateado de la siguiente pgina web:
http://c.conclase.net/curso/index.php. Los cursos de C y C++ con clase son altamente
recomendados por lo bien que estn explicados y el carcter docente de esta pgina
web.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO2. MODIFICACIONES MENORES A C EN C++. 47

Almacenamiento automtico: Por defecto las variables locales son auto. Estas
variablessecreandurantelaejecucin,yseeligeeltipodememoriaautilizarenfuncindel
mbitotemporaldelavariable.Unavezcumplidoelmbito,lavariableesdestruida.Esdecir,
unavariableautomticalocaldeunafuncinsecrearcuandoseadeclarada,ysedestruiral
terminarlafuncin.Unavariablelocalautomticadeunbucleserdestruidacuandoelbucle
termine.
Almacenamientoesttico:Elespecificadorstaticseutilizatantoparavariablescomo
parafunciones:
static <tipo> <nombre_variable>;
static <tipo> <nombre_de_funcin>(<lista_parmetros>);

Cuandoseusaenlapeticindeunavariable,esteespecificadorhacequeseasigne
una direccin de memoria fija para el objeto mientras el programa se est ejecutando. Es
decir,suduracinesladelprograma.Encuantolavisibilidadconservaelquelecorresponde
segnelpuntodelcdigoenqueaparezcaladeclaracin.Debidoaquetieneunaposicinde
memoriafija,suvalorpermanece,aunquesetratedeunavariabledeclaradadeformalocal,
entre distintas reentradas en el mbito del objeto. Los objetos estticos no inicializados
tomanpordefectounvalornulo,aunqueconvienesiempreindicarelinicializadorcombuena
practicaalahoradeprogramar.
Estainicializacinsloafectaralmomentodecreacindelavariable.

Curiosamentesiutilizamoselmodificadorstaticsobreunavariableglobal(fuerade
cualquier bloque) estaremos indicando que esa variable no debe ser accesible desde otros
ficherosdelprograma,sinosolodesdeelficheroquelasestdeclarando.

Almacenamientoexterno:paraindicarlosehaceusodelapalabraclaveexternyes
aplicabletantoavariablescomoafunciones:


extern <tipo> <nombre_variable>;
[extern] <tipo> <nombre_de_funcin>(<lista_parmetros>);

Esteespecificadorseusaparaindicarqueelalmacenamientoyvalordeunavariable
oladefinicindeunafuncinestndefinidosenotromdulooficherofuente.Lasfunciones
declaradasconexternsonvisiblesportodoslosficherosfuentedelprograma,salvoquese
definalafuncincomostatic.
Elespecificadorexternslopuedeusarseconobjetosyfuncionesglobales.
48 PROGRAMACIN C++ Y COMUNICACIONES.

Lasdeclaracionesdeprototipossondeclaracionesexternaspordefecto,deahqueal
igualqueocurraconlaespecificacinauto,normalmentenoveamosestapalabraclaveenlas
declaraciones de funciones. Se puede usar extern "c" con el fin de prevenir que algn
nombre de funcin escrita en C pueda ser ocultado por funciones de programas C++. Este
especificador no se refiere al tipo de almacenamiento, ya que sabemos que en el caso de
prototiposdefuncioneseselespecificadorpordefecto.Enrealidadesunadirectivaqueest
destinadaalenlazador,yleinstruyeparaquehagaunenlazado"C",distintodelqueseusa
parafuncionesenC++.
Lgicamente,esteespecificadorlousaremosconprogramasqueusenvariosficheros
fuente,queserlomsnormalconaplicacionesquenoseanejemplosoaplicacionessimples.
Almacenamientoenregistro:Paraespecificarestetipodealmacenamientoseusael
especificadorregister.

register <tipo> <nombre_variable>;

Indicaalcompiladorunapreferenciaparaquelavariablesealmaceneenunregistro
delaCPU,siesposible,conelfindeoptimizarsuacceso,consiguiendounamayorvelocidad
deejecucin.Losdatosdeclaradosconelespecificadorregistertienenelmismombitoque
las automticas. De hecho, slo se puede usar este especificador con parmetros y con
objetoslocales.

El compilador puede ignorar la peticin de almacenamiento en registro, que se


acepte o no estar basado en el anlisis que realice el compilador sobre cmo se usa la
variable. Una variable de este tipo no reside en memoria, y por lo tanto no tiene una
direccindememoria,esdecir,noesposibleobtenerladireccinaunobjetodeclaradocon
eltipodealmacenamientoregister.
Sepuedeusarunregistroparaalmacenarobjetosdetipochar,int,float,ypunteros.
Engeneral,objetosquequepanenunregistro

2.8. Modificaciones a las funciones

Funciones inline
C++permiteintroducirelmodificadorinlineenladeclaracindelasfunciones.Con
este modificador indicamos al compilador que consideramos conveniente que las llamadas

UPM-EUITI-2015. Miguel Hernando.


CAPTULO2. MODIFICACIONES MENORES A C EN C++. 49

realizadas a esta funcin sean sustituidas por el cuerpo de cdigo de la funcin. El efecto
respecto de la funcionalidad del programa es el mismo en ambos casos, pero en caso de
realizarse esta sustitucin, el programa resultante es ms rpido, al evitarse el salto a la
funcin,acostadeuncdigoejecutablemsextenso.
Es recomendable utilizar el modificador inline en funciones pequeas, que son
llamadasenpocoslugares(queesdiferenteaqueseanllamadaspocasveces).
Para poder asignar el modificador inline a una funcin, dicha funcin debe estar
definidaantesdequeseainvocada,delocontrarioelcompiladornolotendrencuenta.Por
este motivo, las funciones inline son normalmente definidas en los ficheros de cabecera.
Modificar una funcin para que sea de este tipo implica anteponer inline al tipo del valor
retornadoporlafuncin.

inline int maximo(int a, int b)
{
return((a>b)?a:b);
}
int main()
{
int a,b;
scanf(%d%d,&a,&b);
printf(El mximo de %d y %d es %d,a,b,maximo(a,b));
}

ElcomportamientodelasfuncionesinlinerecuerdaalasmacrosdeC.Sinembargo
las macros de C definidas por medio de la directiva al preprocesador #define, pueden
fcilmente llevar a errores de cdigo debido a que se realiza una sustitucin textual de los
parmetros. Esto queda perfectamente resuelto con esta nueva herramienta aportada por
C++.
Por ejemplo, en C, la macro correspondiente a la funcin anterior, se escribira
correctamentedelaformasiguiente:
#define MAXIMO(a,b) (((a)>(b))?(a):(b))

Enelsiguientecdigo,seobservaunefectonodeseadoenelvalordelasvariables
paraelcasodeusodelasmacros:
void main()
{
int a=2,b=4,max;
50 PROGRAMACIN C++ Y COMUNICACIONES.

max=MAXIMO(++a,--b);
printf(el mximo de %d y %d es %d,a,b,max);
}

Elmensajedesalidadelejemplosera:

Elmximode3y2es2
Esto es debido a que a ha sido incrementada una vez y b dos veces, una en la
evaluacin de la expresin de la condicin, y otra en la evaluacin de la expresin del
resultado.Estetipodeerrores,ascomolasprecaucionesclsicastomadaspormediodelos
parntesisquedansolventadaspormediodelusodelasfuncionesinline.

Adicionalmente, cualquier funcin definida en la declaracin en el interior de una


clase,seasumecomofuncininline.

As,enelficherodecabecerasepodraincluirlasiguientelnea,siendoentoncesla
funcinmximoconsideradacomoinline:
//cabecera.h
class MiClase
{
int maximo(int a,int b){return((a>b)?a:b);};
};
A diferencia de lo habitual, el modificador inline se asocia con la definicin de la
funcinenvezdeconsudeclaracin.Enelfondoestoesporqueunafuncindefinidacomo
inlinenoserutilizadaenlafasedeenlazadoyportantopodremostenerdistintasversiones
deunafuncinenlasdistintasunidadesdecompilacin.

Funciones sobrecargadas
LasobrecargadefuncionesesunacaractersticadeC++quehacequelosprogramas
seanmslegibles.
Consiste en declarar y definir varias funciones distintas que tienen un mismo
nombre. En el momento de la compilacin se decide si se llama a una u otra funcin
dependiendodelnmeroy/otipodelosargumentosactualesdelallamadaalafuncin.

Lasobrecargadefuncionesnoadmitefuncionesquedifieransloeneltipodelvalor
deretorno,peroconelmismonmeroytipodeargumentos.

De hecho, el valor de retorno no influye en la determinacin de la funcin que es


llamada;sloinfluyenelnmeroytipodelosargumentos.

Elsiguienteejemplomuestracomosobrecargarlafuncinsumaparanmerosreales
ynmeroscomplejos:

UPM-EUITI-2015. Miguel Hernando.


CAPTULO2. MODIFICACIONES MENORES A C EN C++. 51

struct complejo
{
float real, imaginario;
}
float suma(float a, float b)
{
return (a+b);
}
complejo suma(complejo a, complejo b)
{
complejo c;
c.real=a.real+b.real;
c.imaginario=a.imaginario+b.imaginario;
return c;
}
void main()
{
complejo a={1.0F,1.5F},b={0.0F,1.1F},c;
float d=3.0F,e=8.2F,f;
c=suma(a,b); //utiliza la funcion suma de complejos
f=suma(d,e); //utiliza la funcion suma de enteros
}

Enelusodelasobrecargadefuncioneshayquetenercuidadoconlaposibilidadde
queseproduzcanambigedadesenladecisindequfuncinvaaserejecutada.

En caso de que pueda darse esta ambigedad por ser los tipos de datos
promocionables o equivalentes se puede romper la ambigedad mediante una conversin
explcita.Porejemplo:
void imprime(double a);
void imprime(long a);
void main()
{
int b=8;
imprime(b);
imprime(static_cast<long>(b));
imprime((double)b);
}
Enesteejemplo,laprimerallamadaalafuncinimprimeesambiguapuestoqueb
puedeserpromocionadotantoadoublecomoalong.Estaambigedadesresueltaenlosdos
casossiguientes.EnlasegundallamadasehautilizadounodelosnuevosoperadoresdeC++
que es la conversin esttica al tipo indicado entre llaves. Este nuevo operador aparece
especialmenteporlaposibilidadderealizarconversionesconverificacindetipodurantela
52 PROGRAMACIN C++ Y COMUNICACIONES.

ejecucinpormediodesudualdynamic_cast.Elmatizentrelosditintostiposdeconversin
severmsadelante,basteahoraconmencionarlos.

Parmetros por defecto en una funcin


UnadelasprimerascosasqueunoaprendeenelmanejodefuncionesenCesqueel
nmero de argumentos formales de una funcin (parmetros establecidos en la definicin)
debe coincidir con el nmero de argumentos actuales (parmetros introducidos en la
ejecucin).EnC++ esto ya no es as,puesto que es posible definir valores por defecto para
cadaunodelosargumentos,deformaquesienelusodeunafuncinnosonindicadosporel
programador,dichosparmetrostomaranelvalorprevisto.
Es decir, en la declaracin de una funcin, o en su definicin se especificarn los
valoresquedebernasumirlosparmetroscuandoseproduzcaunallamadaalafunciny
estosseomitan.Elsiguienteejemplo,muestraunafuncinqueimprimeelcontenidodeun
vectorconunindicadordetamaoquepordefectovale3,yunindicadordesihaycambiode
lneaquevalepordefectofalse.
void imprimeVector(float v[], int tam=3,bool linea=false)
{
printf(();
for(int i=0;i<tam;i++)printf( %f,v[i]);
if(linea)printf( )\n);
else printf( ) );
}
void main()
{
float vector[5]={1.0F,2.0F,3.0F,4.0F,5.0F};
imprimeVector(vector);
imprimeVector(vector,5);
imprimeVector(vector,5,true);
}

Esimportantedestacarqueunavezomitidounargumentoenunallamada,hayque
omitirtodoslosposteriors.Esdecir,noesposibleescogeromitirunparmetrosyotrono,
sloesposibleomitirlosparmetrosdesdeunpuntodeterminado.
Otroaspectointeresanteatenerencuentaparaevitarerroresenlacompilacin,es
queencasodeexistirunprototipodedefinicindelafuncin(bienenelficherodecdigoo
en una cabecera), los parmetros por defecto deben situarse en el prototipo y no en la
definicin.As,elejemploanteriorquedaracomosigue:
void imprimeVector(float v[], int tam=3,bool linea=false);

UPM-EUITI-2015. Miguel Hernando.


CAPTULO2. MODIFICACIONES MENORES A C EN C++. 53

void main()
{
float vector[5]={1.0F,2.0F,3.0F,4.0F,5.0F};
imprimeVector(vector);
imprimeVector(vector,5);
imprimeVector(vector,5,true);
}
void imprimeVector(float v[], int tam,bool linea)
{
printf(();
for(int i=0;i<tam;i++)printf( %f,v[i]);
if(linea)printf( )\n);
else printf( ) );
}

2.9. Variables de tipo referencia.


Si se recuerda la entrevista al padre del C++ incluida en la introduccin de los
apuntes,unodelosaspectosqueelentrevistadordestacabacomoimportanteaportacindel
lenguajeC++eraeste.Quespuesunareferencia?.

Unareferenciaesunnombrealternativooaliasparaunavariable.

Segn esta definicin, una referencia no es una copia de la variable referenciada,


sinoqueeslamismavariableconunnombrediferente.Suprincipalaplicacinestenelpaso
deparmetrosporvariablealasfunciones,ascomolaposibilidaddeencadenarresultados
deoperacionescomoseveracontinuacin.

Antesdecomenzarsinembargocontodaslasposiblesaplicacionesypeculiaridades
de este nuevo tipo de variables, la regla prctica para no terminar lindose es la ya
expuestaantes.Unareferencianoesunpunterooalgoexternoalavariablereferenciadaes
lamismavariableconunnombredistinto.
Severahoralaaplicacinmssencillaperoconmenosutilidad:lacreacindeun
aliasdeunavariable.
Laformadedeclararunareferenciaaunobjetoengenerales:
tipo &alias = variable
Al igual que en los punteros, en caso de tener varias declaraciones seguidas, se
adjuntarel&alidentificadordelareferenciaenvezdealtipobsico.
int a,b;
int &c=a,d,&e=b;

54 PROGRAMACIN C++ Y COMUNICACIONES.

Todareferencia,exceptolasdeclaradascomoparmetrosformalesenunafuncin,
debe ser siempre inicializada. Adems una referencia no puede alterar el objeto al que se
refiereunavezinicializadadeigualformaquenoesposiblemoverunavariabledeunsitioa
otrodelamemoria,sinoqueunavezcreadapermaneceenelmismositio.
Elsiguienteejemplomuestralacreacindeunaliasdeotravariable:
void main()
{
int i;
int& j=i; //j es un alias de i
for(i=0;i<3;i++)printf(%d,j); //imprime 012
for(j=0;j<3;j++)printf(%d,i); //imprime 012
for(j=0;i<3;j++)printf(%d,j); //imprime 012
}

Elefectoeselmismoquesisustituimostodaslasjpori,sonlamismavariable!,y
por tanto los tres bucles for hacen exactamente lo mismo. Se observa por tanto, que la
aplicacindelasreferenciasdentrodeunmismobloquetienepocautilidad.Elhechodeque
sehayamencionadoestaaplicacinesqueayudaalentendimientodelmododeprocederde
lasreferencias.

La importancia de este nuevo mecanismo aportado por C++ reside


fundamentalmenteenlasfunciones,tantoenelpasodeparmetroscomoenlosvaloresde
retorno.

Las referencias como parmetros de una funcin.


Una de las reglas bsicas que se establecen en C en parte para diferenciarlo de
conceptosderivadosdelPASCAL,esquelosparmetrosdelasfuncionessonsiemprepasos
por valor. Es decir, al ejecutarse una funcin, los argumentos actuales de la llamada son
copiadossobrelosargumentosformales,deformaqueunafuncinsiempretrabajaconuna
copiadelosvaloresconlosquefuellamada.
Elefectoprcticoderivadodeestareglaeraquecadavezquesequerarealizaruna
funcin que tena que modificar alguna de las variables introducidas como argumento, era
necesariopasarladireccinfsicadelavariableenvezdesuvalor.Elclsicoejemploquese
suele utilizar es el de la funcin permutar, que lo que tiene que realizar es intercambiar el
contenidodedosvariables.ElcdigoenCdeestafuncin,ascomosuaplicacinpodraser
elsiguiente:
void permutar(int *a,int *b)
{
int c;

UPM-EUITI-2015. Miguel Hernando.


CAPTULO2. MODIFICACIONES MENORES A C EN C++. 55

c=*a;
*a=*b;
*b=c;
}
void main()
{
int x=1,y=2;
printf(contenido de x e y: %d, %d\n,x,y); /*imprime 1, 2 */
permutar(&x,&y); /*llamada a la funcin con la direccin de
las variables x e y*/
printf(contenido de x e y: %d, %d\n,x,y); /*imprime 2, 1 */
}

Aunquedesdeelpuntodevistadelmododefuncionamientorealdelordenador,es
mucho ms correcto el modo en que este cdigo se escribe en C, en C++ las referencias
permiten realizar esta operacin mediante la creacin de alias de los argumentos actuales,
consiguiendodesdeelpuntodevistadelprogramadorunanotacinmuchomscmoda:
void permutar(int &a, int &b)
{
int c;
c=a;
a=b;
b=c;
}
void main()
{
int x=1,y=2;
printf(contenido de x e y: %d, %d\n,x,y); //imprime 1, 2
permutar(x,y); //llamada a la funcin directamente con
//las variables x e y
printf(contenido de x e y: %d, %d\n,x,y); /*imprime 2, 1 */
}

Lo que ocurre es que indicamos que las referencias argumentos formales de la


funcinseinicializanconlosargumentosactualesdelallamadaalafuncin,porloquelas
referencias pasan a ser las mismas variables pero con un nombre y mbito local a la
funcin.Elefectoesequivalenteapasarestosargumentosporvariableenvezdeporvalor.
Evidentemente,paralosprogramadoresannoexperimentadosestoesunsoplode
airefresco.Sinembargohayquetenerciertaprecaucinenelusodelasreferencias,puesto
que se estn utilizando indistintamente variables de un mbito superior a una funcin y
variables propias de la funcin como si fueran iguales. Esto puede provocar peligrosas
confusiones.
56 PROGRAMACIN C++ Y COMUNICACIONES.

Internamente, el compilador transforma las llamadas a funciones con parmetros


por referencia a la utilizacin de punteros y contenidos propia de C. Por este motivo, las
reglasquellevabanautilizarpunterosenvezdevaloresenCsesiguenaplicandoparaelcaso
delasreferencias.Esdecir,enelcasodequeestemosmanejandovariablesdegrantamao
(estruturas o clases de tamao mediano o grande), es conveniente utilizar bien el paso por
direccinoporreferencia,puestoqueelcdigoesmuchomseficiente.

La referencia como valor de retorno


Cuando en C se establece el tipo del valor de retorno de una funcin, lo que
realmenteestamosdiciendoesdequetipoeslafuncin,oaquetipodedatosesequivalente
unallamadaaunafuncin.Estopermitaintroducirlallamadaaunafuncinencualquiersitio
endondeseacepteunvalordeltipodedatosdedichafuncin.Elsiguienteejemplomuestra
estaidea:
struct vector2D
{
double x,y;
};
vector2D *normaliza(vector2D *a)
{
double modulo;
modulo=sqrt((a->x)*(a->x)+(a->y)*(a->y));
a->x/=modulo;
a->y/=modulo;
return a;
}
void main()
{
vector2D vector={3.0,4.0};
printf(la x normalizada es %d,normaliza(&vector)->x);
}

Pues bien, en C++ se pueden utilizar las referencias como valor de retorno para
realizar anidaciones de este tipo con notacin ms cmoda, o incluso para poder realizar
asignaciones a una variable retornada por referencia tras la llamada de la funcin!. Esto ya
comienzaasonarachinoparaunexpertoprogramadordeC,perolaideaeslamismaque
antesconunareferenciapodemosutilizarunnombredistintoparaunavariable.Ahoraese
nombredistintoserlallamadaalafuncin.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO2. MODIFICACIONES MENORES A C EN C++. 57

Se muestra a continuacin las dos aplicaciones ms inmediatas utilizando la


estructuravectoranteriormentedefinida:laconcatenacindeoperaciones,ylaasignacinde
valoresalasvariablesretornadasporreferenciaporunafuncin:

vector2D& normaliza(vector2D& a)
{
double modulo;
modulo=sqrt((a.x)*(a.x)+(a.y)*(a.y));
a.x/=modulo;
a.y/=modulo;
return a;
}

double& componenteX(vector2D& a)
{
return (a.x);
}

void main()
{
vector2D vector={3.0,4.0};
printf(la x normalizada es %d,normaliza(vector).x);
componenteX(vector)=8.0;
...
}

Ntese que gracias a las referencias, ahora es posible utilizar la llamada a una
funcinenelladoizquierdodeunaasignacin.Noasignamosalafuncinelvalorsituadoala
derecha,sinoqueasignamosdichovaloralavariableretornadaporreferenciaporlafuncin,
puesto que la expresin de llamar a la funcin se ha convertido en un alias de la variable
retornada.
Es importante considerar que slo es posible retornar referencias a variables cuya
vida supere a la duracin de la funcin, por el mismo motivo que en C no se retornan
punterosavariablesdeclaradasenelinteriordelafuncin:cuandoseterminalaejecucinde
lafuncin,lasvariablesautodefinidasensuinteriorsondestruidas.
Elsiguientecdigoseraportantoerrneo:
vector2D& normaliza(vector2D a)
{
double modulo;
modulo=sqrt((a.x)*(a.x)+(a.y)*(a.y));
a.x/=modulo;
58 PROGRAMACIN C++ Y COMUNICACIONES.

a.y/=modulo;
return a;
}
void main()
{
vector2D vector={3.0,4.0;
printf(la x normalizada es %d,normaliza(vector).x);
}

Elcompiladorgeneraraelsiguienteerror:

Returningaddressoflocalvariableortemporary
Esto es debido a que los argumentos formales son variables locales de la funcin
inicializadasconelvalordelosargumentosactuales.Comoconsecuencia,lavariablequese
retornaporreferenciaesunavariablelocalcopiadelaintroducidacomoparmetro.
Por ltimo, cabe destacar en el mensaje de error, que se seala que se est
retornando la direccin de una variable local. Hasta este punto se ha evitado mencionar la
relacin existente entre punteros y referencias para evitar confusiones en su uso. Sin
embargo hay que destacar que en el fondo las referencias no son ms que triquiuelas del
compiladorparahacerelcdigomslegible,siendoenverdaddireccionesdelasvariables(es
decirpunteros)loquesepasatantoenlosargumentoscomoenelretorno.

2.10. Reserva dinmica de memoria: operadores new y delete.


CualquierprogramadordeCsabequeexisteunadiferenciacualitativaimportanteen
elmomentoenquesecomienzaaprogramarconvariablescreadasdinmicamente.Esdecir,
lugaresdelamemoriaparaalmacenardatosquesonsolicitadosalsistemaoperativodurante
laejecucindeunprogramaenfuncindelasnecesidadesdelmismo.Puestoquelamemoria
es unode losprincipales recursos gestionados por el sistema operativo, para obtener estas
variablesdurantelaejecucin,enANSICeranecesariorealizarlapeticingeneralmentepor
mediodelafuncinmallocdefinidaenlalibreraestndarstdlib.
Esta memoria solicitada durante la ejecucin, puesto que haba sido directamente
solicitada al sistema, permaneca reservada para su uso por parte del programa de forma
indefinida. Si se quera dejar libre una zona anteriormente reservada, entonces haba que
realizarlacorrespondientepeticinalsistemaoperativopormediodelafuncinfreetambin
definidaenstdlib.

Existenmuchasaplicacionesdirectasenlareservadinmicadememoria,talescomo
la generacin de listas, pilas, rboles, vectores de tamao variable, etc. Simplemente para
ayudar a recordar estas ideas, se expone a continuacin un programa en C que permite
almacenartantosnmerosdistintosdecerocomoquepanenlamemoria(realmente50%de

UPM-EUITI-2015. Miguel Hernando.


CAPTULO2. MODIFICACIONES MENORES A C EN C++. 59

la memoria libre que actualmente es mucho) por medio de un vector de caracteres de


tamaovariable:

#include <stdlib.h>
#include <stdio.h>
#include <memory.h> /*necesario para usar memcpy*/
int main()
{
long tamanio=0,capacidad=10,i;
int valor;
int *vector,*aux;
vector=(int *)malloc(capacidad*sizeof(int));
while(scanf("%d",&valor)&&(valor!=0))
{
vector[tamanio++]=valor;
if(tamanio==capacidad)
{
capacidad+=10;
aux=(int *)malloc(capacidad*sizeof(int));
if(aux==NULL)
{
printf("Error en la reserva de memoria");
free(vector);
return -1;
}
memcpy(aux,vector,tamanio*sizeof(int));
free(vector);
vector=aux;
}
}
printf("nmero de nmeros almacenado: %d\n",tamanio);
for(i=0;i<tamanio;i++)printf("%d, ",vector[i]);
free(vector);
return 1;
}

Ciertamente este ejemplo no es muy didctico, puesto que se ha optado por una
programacincompacta.Lafinalidaddelmismoesladeconcienciarallectordequeapartir
de ahora se requerirn al menos los conocimientos de C reflejados en este ejercicio. Si no
fueraelcaso,serecomiendarepasarCantesdecontinuar.Portanto:

No es conveniente seguir sin tener los conocimientos de C necesarios para


comprenderelejercicioanterior.
60 PROGRAMACIN C++ Y COMUNICACIONES.

En C++ se introducen dos operadores ms completos que realizan la reserva y


liberacindememoriadinmica:losoperadoresnewydelete.

El operador new.
Eloperadornewessemejantealafuncinmallocaunquecomoseveralolargodel
cursonoselimitaexclusivamentearealizarlareservadememoria.Porahoraseconsiderar
quepermiteasignarmemoriapertenecientealreadealmacenamientolibreparaunobjeto
oparaunamatrizdeobjetosdemomentoentindaseporobjetounavariable.

Cuando se reserva memoria para un solo objeto, el tamao de memoria necesario


pararealizardichoalmacenamientosedeterminadirectamenteenfuncindeltipodedicho
objeto.Porestemotivo,lasintaxiseslasiguiente:
int *a,*b;
a=new int;
b=new (int);

El ejemplo muestra dos posibles sintaxis para la misma operacin. Ambas son
equivalentes.Esposible,comosehavisto,realizarladeclaracindeunpunteroylareserva
dememoriaenlamismasentencia:
int *a = new int;

Lallamadaaloperadornewdevuelveunpunteroalespaciodememoriareservado,
siendoelpunterodeltipoespecificado.Porestemotivo,adiferenciadelafuncinmallocno
esnecesariorealizarelcast(conversinforzada)alpunteroretornado.Sinohubieraespacio
para la reserva de memoria, el operador devuelve un puntero NULL si no se utilizan las
excepciones(severmsadelante).
Cuando el operador new reserva memoria para una matriz, el tipo de datos que
devuelveesdeltipodeladireccinalprimerelementodelamatriz.Sesueleconsiderarpor
este motivo como un operador distinto, aunque en el fondo es el mismo modo de
funcionamientoqueenlainstruccinmallocdeC.
As,lossiguientesejemplosmuestrancomocrearvectoresymatricesdinmicamente
coneloperadornew:
1 int num=6,i;
2 int *a = new int;
3 int *b = new int[num];
4 int (*c)[3] = new int[8][3];
5 int *d[3];
6 for(i=0;i<3;i++)d[i]=new int[8];

UPM-EUITI-2015. Miguel Hernando.


CAPTULO2. MODIFICACIONES MENORES A C EN C++. 61


Enesteejemplosehaestablecidolacomparacinentrelareservadememoriapara
un solo objeto o variable (lnea 2), y la reserva de memoria de vectores. En el caso de los
vectoreselmododeprocederesexactamenteigualqueenC.Unvectoralfinalesunpuntero
queapuntaaunazonadememoriaendondecomienzanasituarseloselementosdelvector
deformaordenada.Detalforma,queladireccincorrespondeconladelprimerelementoy
tiene por tanto este tipo. Recordemos, que la razn principal para proceder as, esta en la
aritmticadepunterosyenlossistemasdeindireccin,lograndodeestaformaqueunode
los mecanismos bsicos del lenguaje tenga correspondencia directa con el modo de
funcionamientodeunmicroprocesador.
Obsrvese a su vez como al igual que en C internamente no existen matrices de
elementosdemsdeunadimensin,sinoquetodoseconsideracomovector.Enelcasode
unamatrizdedosdimensionesenCyC++seconsiderancomounvectordevectores.Estoes
loqueaparecereflejadoenlalnea4.Aunquealaderechalapeticinaparececonelaspecto
deunamatrizde8por3,loqueentiendeC(yesoesloquesereflejaalaizquierda)esquese
estsolicitandounvectordevectoresdetresenteros,porloqueladireccinderetornoesla
de vector de tres enteros. Este modo de lectura, ampliamente recomendado, se logra si se
siguen las reglas de asociatividad de los corchetes. El operador new, considera slo los
primeroscorchetes,lodemscorrespondealtipobsicodelvector.
Puestoqueloscorchetestienenpreferenciasobreeloperador*,esnecesarioponer
losparntesis,paraqueelcompiladorentiendaqueclnea4esunpuntero(primeroselee
loquehayentreparntesis)avectoresdetresenteros.

Por el contrario, en la lnea 5, el compilador entiende que d es un vector tienen


preferencialoscorchetesfrentealasteriscodetrespunterosaentero.Queevidentemente
esdistintoalcasoanterior.
Para finalizar este operador al que ms adelante se ir haciendo referencia, se
comentarnparadarleunaformamscompleta,losaspectosquelohacendiferenteymejor
a la funcin estndar malloc de C. Las dos ltimas caractersticas, corresponden a aspectos
msrelacionadosconlaPOO:
Eloperadornewnonecesitadelaconversinforzada.
En la generacin de un objeto, se realiza una llamada al constructor, e incluso se
permitelainicializacin.
Lagestindeerroresesmuchomejor,puestoquelanzaunaexcepcin(bad_alloc)
cuando hay error, o incluso permite la gestin de los errores de reserva de memoria por
mediodelafuncinset_new_handle.
62 PROGRAMACIN C++ Y COMUNICACIONES.

El operador delete
El operador delete destruye un objeto creado por el operador new, liuberando el
sistemaoperativolamemoriaocupadapordichoobjeto.AdiferenciadeloqueocurraenC
conlafuncinfree,deletepuedeserutilizadosobreunpunteronulo(apuntaacero)encuyo
caso no realiza ninguna operacin. Es importante recordar que nunca se puede pedir la
liberacindeunamemoriaquenohasidoreservadadinmicamente.Ocomoreglaprctica,

Eloperadordeletesolopuedeseraplicadoazonasdememoriareservadasmediante
unnew.

A diferencia de C, en caso de querer eliminar un vector, se utilizara una sintaxis


distintadeloperadordelete.Larazndequeseprocedadeestaformavienedelusoonode
losdestructoresdeltipodedatosbsicoyaseverelsignificadodedestructor.Enelcasode
losvectores,serealizalallamadaaldestructordeltipodedatosdelpunteroporcadaunode
loselementoseliminados.Evidentementeparaelcasodeunsoloobjetotambinserealizala
llamada.Esimportanteconsiderarqueelvalordelavariablepunteroutilizadoparaeliminar
el/losobjetos,noesmodificado.Deformaquelohabitualesqueunavezrealizadalallamada
adeleteseprocedaacontinuacinaasignarceroalpunteroutilizado.

Segn lo indicado, las operaciones que hay que realizar para eliminar los objetos
reservadosparaelanteriorejemploson:
1 delete a;
3 delete [] b;
4 delete [] c; //observese que se considera c como vector
5 for(i=0;i<3;i++)delete [] d[i]; //para cada new un delete

Dondeseobservaenlalnea1elmodoenelquedeleteesutilizadoenlaeliminacin
deunsoloobjeto.Yenlaslneassiguientes,elformatoenlallamadaadeleteparaprocedera
laliberacindelamemoriareservadaparadistintosvectoresdeelementos.

2.11. Espacios de nombres.


Unespaciodenombres(namespace)esunconceptosencillo,similaraldembito.
La idea es que para evitar conflictos de nombres durante la fase de enlazado, se puedan
definir subconjuntos o mbitos de identificadores. Se pueden agrupar declaraciones,
declaraciones, y en general identificadores en un mbito con una etiqueta de forma que
posteriormenteesposiblediferenciarlos.
Para entender el concepto, supongamos que queremos crear una variable llamada
"Pepe", y que el cdigo que estamos integrando con ms gente tambin contiene
posiblemente la variable "Pepe" distinta. As que lo que decidimos es que yo voy a utilizar
"Pepe"delmbito"Almera"ymicompaero"Pepe"delmbitode"Toledo".Dentrodeun

UPM-EUITI-2015. Miguel Hernando.


CAPTULO2. MODIFICACIONES MENORES A C EN C++. 63

mbito,siemprequeindique"Pepe"seharreferenciaimplcitaal"Pepe"dedichombito,
perodesdefuerasiempresepodrdecir"PepeeldeAlmera"o"PepeeldeToledo".
Adems se pude indicar, por medio de la palabra clave using el uso de un mbito
externo por defecto. Esto nos permite subdibidir el espacio globald e nombres en espacios
personalizadosevitandolasredefinicionesoelagotacmientodeidentificadoresenproyectos
grandes.
Por ltimo, es interesante aclarar que puedo aadir elementos a un espacio de
nombresencualquierparte,yenmuchosficherosdistintos.Lohabitualesqueunalibreraen
C++porejemplotengatodossuselementosdefinidosenunnamespaceespecfico.
namespace Almeria{
int Pepe;
void foo(){
Pepe=73;
}
}
namespace Toledo{
int Pepe;
}
void foo(){
Almeria::Pepe=3;
Toledo::Pepe=5;
}

void foo2()
{
using namespace Almeria;
Pepe=8;
Toledo::Pepe=3;
Almeria::foo(); //hay foo() y Almera::foo() es necesario
}

2.12. Operaciones de entrada y salida


En la mayora de los programas expuestos anteriormente se ha hecho uso de las
funciones printf y scanf ya utilizadas en C. Mediante dichas funciones perfectamente
utilizablesenC++logramosqueelprogramaenveyrecibadatosdeperifricosdelsistema.
(lapantallayelteclado).EnC++estaoperacinsesimplificaygeneralizaintroducindoseel
concepto de flujo. Es decir, dado que es muy habitual tener que realizar operaciones de
transmisin y recepcin de datos desde o hacia ficheros, impresoras, escneres, sitios de
internet,etc.Loquesehahechoesunificarysimplificarestascomunicacionespormediode
loquesellamanflujos.As,unflujodesalidaseraelenvodedatosdesdeelprogramahacia
64 PROGRAMACIN C++ Y COMUNICACIONES.

lapantalla(mostrarunmensajeounosvalores)yunflujodeentradapuedeserelconjunto
deteclaspulsadasenunteclado.
Por tanto, un flujo es un objeto que hace de intermedio entre el programa y el
destino u origen de la informacin. En la mayora de los casos no es relevante para el
programa la naturaleza fsica del sistema que enva o recibe los datos, sino que lo que
interesaeselcarctersecuencialdelosdatosenviadosorecibidos.
Dehecho,aligualqueenC,lasoperacionesdeentradaysalida(lecturayescritura)
siguenengeneralsiempreelmismoesquema:inicialmenteseabreelcanaldecomunicacin
oflujo(aperturadeunficheroounpuerto),seenvaorecibeinformacinduranteeltiempo
que sea necesario, y finalmente, cuando ya no es necesario este canal, se cierra para no
sobrecargaralsistemaoperativo.
Sepuedeobjetaraloanteriorqueparaelusodeprintfnohasidonuncanecesario
realizarlaaperturadelcanal.Escierto,peroesqueenC,todaslasoperacionesdeentraday
salida estndar se realizan por medio de ficheros que en algunos casos estn ocultos. Al
comenzarcualquierprogramaenCseproducelaaperturaautomticadetresficheros:stdin,
stdout, y stderr, que constituyen respectivamente la entrada estndar de datos, la salida
estndar y la salida para mensajes de error estndar. De forma que es el sistema el que
realiza la apertura de ficheros por nosotros. Cuando uno escribe una intruccin printf()
realmenteestescribiendofprintf(stdout,).
VolviendoentoncesaC++,elcomportamientoesanlogo,peromuchomscmodo.
Cuando un programa en C++ se ejecuta, se crean automticamente tres flujos identificados
porlossiguientesobjetos:
1. Unflujodeentradaestndar(normalmenteelteclado):cin.

2. Unflujodesalidaestndar(habitualmentelapantalla):cout.

3. Dosflujoshacialasalidaestndardeerror(pantalla):cerr,yclog.
Aunque segn avance el curso, se irn viendo aspectos ms avanzados sobre los
flujos de datos, a continuacin se muestra el modo en que se realizan las operaciones de
entradaysalidaenC++.
Losflujoscinycout.
Enprimerlugar,parapoderutilizarlosflujosanteriormenteexpuestos,esnecesario
incluirlalibreraestndariostream.h.
La gran ventaja o comodidad del uso de flujos, reside en que cada dato sabe
inicialmentecomosedebetransmitir(esdecir,eljuegodecaracteresquelorepresenta),yen
caso de ser un tipo de datos definido por el usuario, es posible indicar como se realiza su
escrituraosulecturagraciasalaposibilidaddesobrecargarlosoperadores>>y<<.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO2. MODIFICACIONES MENORES A C EN C++. 65

El siguiente ejemplo ilustra como se imprimen una serie de datos por pantalla
medianteelusodelflujoestndarcout.
#include<iostream.h>
int main()
{
int i=2,j=3;
double dato=5.3;
char a=a,b[]=hola;

cout << i;
cout << i << j << endl;
cout << el valor de dato es << dato << endl;
cout << el carcter a= << a << y la cadena b << b << endl;
}

La primera lnea indica que se imprima i siendo el compilador el encargado de


convertirelvalordeiasurepresentacincomounacadenadecaracteres.Esdecir,yanoes
necesarioindicarelformatoconelqueundatodebeserimpreso,sinoqueelpropiosistema
puedehacerloatendiendoaltipodeesedato.
Si se desean escribir varios datos seguidos, bastar conconcatenar lasoperaciones
unadetrsdeotratalycomoaprecereflejadoenlaslneassiguientes.Elidentificadorendles
equivalenteaimprimirporpantallaelcarcter\n,esdeciruncambiodelnea.
Siporcualquiermotivosedeseaseimprimirundatoconunformatodistintoaldesu
tipo,bastarconrealizarunaconversinforzadaalformatoconelquesedeseaimprimit:
cout << static_cast<int>(A);
EnestecasoseimprimeelvalorenterocorrespondientealcharacterA,esdecirsu
cdigoASCII.
Aloperador<<seledenominacomooperadorinsercin.
Lasoperacionesdeentradaserealizandeformaanloga,perocambiandocoutpor
cinyeloperador<<poreloperador>>.Aloperador>>seledenominacomooperadorde
extraccin. El modo de funcionamiento es equivalente al de scanf pero en este caso no es
necesarionilaespecificacindetiposnielpasodedirecciones:
double b;
int i;
char c, d[50];
cout << introduzca un nmero real :;
cin >> b; //al teclear 3.5, en b se almacena este valor
cout << el valor introducido es: << b << endl;
cout << introduzca un real seguido de un entero y un char:;
66 PROGRAMACIN C++ Y COMUNICACIONES.

cin >> b >> i >> c;


cout << introduzca su nombre:;
cin >> d;

Aligualqueenscanflaseparacinentrecadavalorintroducidoserealizapormedio
deelespacioenblancosegnellenguajeC(espacio,tabulador,cambiodelnea,).
Un aspecto importante que se abordar en el captulo correspondiente es el de la
gestin de errores y el estado de los flujos, as como la especificacin de formatos (por
ejemplo, el nmero de decimales que se utilizarn en la impresin de un double). De
momento se mencionar que son operaciones fcilmente realizables pero que escapan al
enfoquedeestecaptulo.

Es interesante considerar que la operacin de insertar en un flujo tanto si es una


pantallacomosiesunficheroeslamisma.Aunqueyaseveralolargodellibro,elaccesoa
estos elementos est realizado mediante el uso de una clase base comn, por lo que ser
realmenteequivalentehacerunaoperacinuotrasalvoqueespecifiquemoslocontrario.A
continuacindemodoilustrativoseincluyeunbreveejemplodeescrituradeuntextoenun
fichero de datos. No se realizan las comprobaciones oportunas ni se cierra el fichero para
ilustrarlaequivalencia.Enprincipio,elficheroaldestruirsuobjeto,cerrarcorrectamenteel
recursodelsistema(perolomascorrectoescomprobarlaaperturaeindicarelcierre).
#include <iostream>
#include <fstream>
using namespace std;
void main()
{
ofstream miFichero("example.txt");
miFichero<<"Hola Mundo!"<<endl;
}

2.13. EJERCICIOS

EJERCICIO2.1

Dadalasiguienteestructuradedatos:
***********************************/
#define MAX_CADENA 100

//valores posibles de las cosas


enum TipoCosa {T_complejo, T_libro};

UPM-EUITI-2015. Miguel Hernando.


CAPTULO2. MODIFICACIONES MENORES A C EN C++. 67

//datos para un complejo


struct Complejo{
double real;
double imag;
};
//datos para un libro
struct Libro{
char Titulo[MAX_CADENA];
char Autor[MAX_CADENA];
};
//datos para cualquier cosa
struct Cosa{
TipoCosa tipo;
union{
Complejo complejo;
Libro libro;
};
};
Escribir un programa que permita almacenar una lista de hasta diez cosas, tanto
libroscomocomplejos.Apartedeintroducirlosdatos,elprogramapermiteimprimirtantola
listadecomplejos,comolalistadelibrosolalistadecosasenelmismoordenenquefueron
introducidas.

EJERCICIO2.2
Disear e implementar una funcin de nombre norma que permita obtener la norma
de un vector de float de dimensin n y que en funcin del parmetro adicional
bnormalizadetipoboolpermitanormalizar(true)ono(false)elvectorentrante.Ademspor
defecto,seconsiderarquelosvectoressondedimensin3yquenosedeseamodificarel
vectorintroducido.
EJERCICIO2.3
Una funcin contiene las siguientes sentencias de C++. Indquese la impresin por pantalla
quedichasinstruccionesprovocan.
int a,b,c=1;
a=3,2+3;
b=(3,2+3);
c+=c+=2;
printf("a=%d b=%d c=%d",a,b,c);

EJERCICIO2.4
Indqueselaimpresinporpantalladelsiguienteprograma:
68 PROGRAMACIN C++ Y COMUNICACIONES.

#include <stdio.h>
void main()
{

int i=0;
for(i=0;i<30;i++){
if(!(i%2)||!(i%3))continue;
printf("%d ", i);
}
}

EJERCICIO2.5

Indquecualdelassiguienteslneasmarcadasconunrectnculoescorrecta(elcompiladorla
acepta):
enum notas {suspenso, aprobado, bien, notable, sobresaliente};

int var;
notas nota1, nota2;

nota1=bien;
nota1=1;
nota1=(notas)1;
nota1=suspenso+1;
nota1=suspenso+aprobado;
var=5+bien;
var=bien+5;
var=notable+bien;
var=nota1+bien;
nota1++;
for(var=suspenso;var<sobresaliente;var++)
printf(%d,var);
for(nota2=suspenso;nota2<sobresaliente;nota2++)
printf(%d,(int)nota2);
EJERCICIO2.6

Indiquelaimpresinporpantalladelcdigosiguiente,silasecuenciadenmerosintroducida
porelusuarioeslasiguiente:12,13,14,15,16,17,18,12,13y14.
#include stdio.h

int &menor(int *vector, int num){

UPM-EUITI-2015. Miguel Hernando.


CAPTULO2. MODIFICACIONES MENORES A C EN C++. 69

int j=0;
for(int i=0;i<num;i++)if(vector[i]<vector[j])j=I;
return vector[j];
}
void main(){
int lista[3]={0,0,0};
for(int i=0;i<10;i++)scanf(%d,&menor(lista,3));
printf(Valores: %d %d %d,lista[0],lista[1],lista[2]);
}

3. El Concepto de Clase

Desdeelcomienzodeestosapuntes,sehadestacadolaimportanciadelcambiode
mentalidad o filosofa a la hora de programar que introduce el lenguaje C++. Sin embargo,
hastaestecaptulo,apenasseharealizadoningunavariacinsobreelmododeprogramarde
C.Bien,laparteintroductoriaodesituacinseterminenelcaptuloanterioryportanto,
con elconcepto de clase, objeto y encapsulamiento se comienza a trabajar en la idea de la
ProgramacinOrientadaaObjetos,precisamenteconlaintroduccindelelementobsicoel
objeto.
Como ya sehaba comentado en elcaptulo introductorio un objetoes unaunidad
que engloba en s mismo datos y procedimientos necesarios para el tratamiento de esos
datos.Hastaahorasehanrealizadoprogramasenlosquelosdatosylasfuncionesestaban
perfectamente separados. Cuando se programa con objetos esto no es as, cada objeto
contiene datos y funciones. Y un programa se construye como un conjunto de objetos, o
inclusocomounnicoobjeto.Losobjetosseagrupabanenclases,delamismaformaqueen
la realidad, existiendo muchas mesas distintas (la de mi cuarto, la del comedor, la del

Departamento de Electrnica Automtica e Informtica Industrial


CAPTULO 3. EL CONCEPTO DE CLASE 71

laboratorio,ladelcompaeroolama)agrupamostodosesosobjetosrealesenunconcepto
msabstractodenominadomesa.Detalformaquepodemosdecirqueunobjetoespecfico
esunarealizacinoinstanciadeunadeterminadaclase.
Porejemplo,enlosprogramasdeWindows,cadabotnclsicodeunainterfazesun
objeto.Todoslosbotonesson instancias orealizacionesdelaclaseCButton deWindows.
Luegoloquerealmenteexistesonlosobjetos,mientrasquelasclasessepuedenconsiderar
comopatronesparacrearobjetos.Peroadems,estosbotonespertenecenaunobjetoms
grandequeeseltapizsobreelqueestnpintados.Esteobjetodewindowshabitualmenteno
esmsqueunainstanciadelaclaseCDialogquepermitecrearobjetosquecontienenobjetos
que soncapaces de interaccionar con el usuario de forma grfica.Muchas de las interfaces
queestamosacostumbradosamenejarenwindowssoninstanciasdeestaclasedeobjetos.

Por qu se trabaja de esta forma?Que ventajas tiene?... al programar basndose


enobjetos,esposibleutilizarconfacilidadelcdigorealizadoporotraspersonas.As,cuando
creamosunbotnenWindowsprcticamentelonicodeloquenostenemosquepreocupar
esdeindicarelttulootextoqueapareceenelcentrodelbotn.Sinembargo,todalagestin
dedibujarelrectngulo,lasombra,dereaccionaranteunclicdelratn,etcnoesnecesario
que lo programemos puesto que ya lo ha hecho alguien por nosotros al constituir
caractersticascomunesatodoslosbotones.

3.1. Las clases en C++


Enelfondo,sepuededecirqueunaclaseenC++esunmecanismoquepermiteal
programador definir sus propios tipos de objetos. Un ejemplo clsico es el de los nmeros
complejos.EsbienconocidoqueenCnoexisteuntipodedatosparadefinirvariablesdetipo
complejo. Por ello lo que se haca era definir estructuras que contuviesen un campo que
representaralaparterealcomounnmerodetipofloat,yunaparteimaginariatambinde
tipo float que representara la parte imaginaria. De esta forma se poda agrupar bajo un
mismoidentificadorelconjuntodedatosnecesariosparadefiniruncomplejo.
EnC,estoserealizabapormediodelusodeestructurasconestosdoscampos:
typedef struct _complex{
float real;
float imag;
}complex;
void main()
{
complex a;
a.real=5.0F;
a.imag=3.0F;
}

72 PROGRAMACIN C++ Y COMUNICACIONES.

Posteriormente,sisequisieratrabajarcmodamenteconestenuevotipodedatos
se definan una serie de funciones pensadas para manipular o extraer informacin de los
mismos.As,seraposibledefinirunafuncinquepermitieraextraerelmdulodecualquier
complejomedianteelsiguientecdigo:
float moduloComplejo(complex a)
{
float m;
m=sqrt(a.real*a.real+a.imag*a.imag);
return m;
}

Se observa que mediante este sistema por un lado estn los datos y por otro las
funciones,aunqueestasfuncionesestndefinidasexclusivamenteparatrabajarconeltipode
datoscomplex.
Las clases en C++ se pueden considerar como la evolucin de las estructuras. Las
clasespermitennosloagruparlosdatoscomoocurreenlasestructurassinoqueadems
nospermitenincluirlasfuncionesqueoperanconestosdatos.
LasclasesenC++tienenlossiguienteselementosoatributos:

Unconjuntodedatosmiembro.Enelcasodeloscomplejos,elnmeroreal
que representa la parte real y el nmero real que representa la parte
imaginaria, sern datos miembro de la clase complex. La informacin
guardadaenestosdatossonloqueharndistintounobjetodeotrodentro
deunamismaclase.Aunquenormalmentesiempretenemosdatosenuna
clase,noesnecesarioqueexistan.

Un conjunto de mtodos o funciones miembro. Como se ha mencionado


antes,sernunconjuntodefuncionesqueoperarnconobjetosdelaclase.
Puede haber desde cero hasta tantos mtodos como se consideren
necesarios.

Unosnivelesdeaccesoalosdatosymtodosdelaclase.Supongamosque
sehacreadounaclasequepermitealmacenarunconjuntodenmeros,de
tal forma que es como una especie de saco, en donde se van agregando
nmeros, y despus se pueden ir extrayendo de uno en uno o se puede
preguntarcuantosnmeroshayalmacenados.Enlaclaseexistirnportanto
un conjunto de datos que permitir ir almacenando los nmeros que se
introducen (data)yun datoquenospermite conocer cuntosnmeros se
han introducido hasta ese momento (num). No sera conveniente que en
esta clase, el programador pudiera modificar libremente el valor de num,

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 73

puestoqueestevalorindicaelnmerodeobjetosquesehanintroducidoy
nounvalorarbitrario.PorelloenC++sepuedeestablecerquealgunosde
losdatosyfuncionesmiembrodeunaclasenopuedanserutilizadosporel
programador,sinoqueestnprotegidososondatosprivadosdelaclaseya
quesirvenparasufuncionamientointerno,mientrasqueotrossonpblicos
ototalmenteaccesiblesalprogramador.Estacualidadaplicablealosdatos
oalasfuncionesmiembroesloquesedenominacomoniveldeacceso.

Un identificador o nombre asociado a la clase. Al igual que en las


estructuras, ser necesario asignar un nombre genrico a la clase para
poder hacer referencia a ella. Las palabras CButton, CDialog, complex
utilizadas en los ejemplos anteriores sern los identificadores de las clases
quepermitencrearobjetosdetipobotn,dilogoocomplejo.

3.2. Definicin de una clase


Esbozado el concepto de lo que se entiende en C++ por clase, se procede ahora a
establecerlaformaconquesecreanlasclases,yseutilizan.
Inicialmenteconsideraremosqueexistentresmomentosenladefinicinyutilizacin
deunaclase:ladeclaracin,ladefinicinylainstanciacin.Esposiblerealizarladeclaraciny
la definicin en el mismo segmento de cdigo, sin embargo de momento se realizarn
siempredeformaseparadaparafacilitarsucomprensin.

Ladeclaracindeunaclaseloconstituyeladescripcindelosdatosyfuncionesque
pertenecenalaclase.Enladeclaracinnoesnecesarioindicarelcdigocorrespondientea
losmtodosdelaclase,sinoquebastaconindicarelnombredelmtodoysusparmetrosde
entradaysalida.ElconceptoesanlogoaldeladeclaracindefuncionesenC,endondelo
queinteresaescomunicaralcompiladorlaexistenciadeunafuncin,elmodoenqueestase
debeusar(argumentosyvalorderetorno),ynoseescribeelcdigo.
Ladefinicindeunaclase,eslaparteopartesdelprogramaquedescribenelcdigo
contenidoenlosmtodosdelaclase.LaideaesanlogaaladefinicindelasfuncionesenC.
Lainstanciacin,eselprocesoporelcualsecreaunobjetodeunaclase.
Estos tres conceptos quedan ilustrados en una primera versin y utilizacin de la
clasecomplexparalosobjetosquerepresentannmeroscomplejos.

74 PROGRAMACIN C++ Y COMUNICACIONES.


//comienzo de la declaracin
class complex
{
private:
double real;
double imag;
public:
void estableceValor(float re,float im) ;
float obtenModulo(void) ;
void imprime() ;
};
//fin de la declaracin

//comienzo de las definiciones


void complex::estableceValor(double re, double im)
{
real=re ;
imag=im ;
}
double complex::obtenModulo(void)
{
return (sqrt(real*real+imag*imag)) ;
}
void complex::imprime(void)
{
cout<<real<<`+`<<imag<<`i` ;
}
//fin de las definiciones

//comienzo del programa de ejemplo


void main()
{
complex micomplejo; //creacin de un objeto de la clase complex
//asigno a micomplejo el valor 3.2+1.8i
micomplejo.estableceValor(3.2,1.8);
//imprimo el modulo
cout<<El modulo de ;
micomplejo.imprime();
cout<< es <<micomplejo.obtenModulo();
}

Severcondetalleelsignificadoquetienentodasestasnuevaspalabrasyporquese
usandelaformaenlaquesehanutilizado:

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 75

Declaracin de la clase
La sintaxis ms simple de declaracin de una clase es igual que la utilizada para la
declaracindelasestructurasenC,perocambiandolapalabraclavestructporclassyconla
posibilidaddeintroducirfuncionesynivelesdeaccesoentrelasllaves:

class <identificador>
{
[<nivel de acceso a>:]
<lista de miembros de la clase>
[<nivel de acceso b>:
<lista de miembros de la clase>]
[<>]
}[lista de objetos];

Son mltiples las posibilidades en la declaracin de una clase, sin embargo de


momentosecomienzaconelformatomssencillo.Aligualqueenlasestructurasesposible
lacreacindeobjetosdeunaclaseensumismadeclaracin,aunquenoeslomshabitual.
Sinembargohayquedestacarqueestaposibilidadnosobligaaintroducirunpuntoycoma(;)
alfinaldeladeclaracindelaclasetantosisecreanobjetoscomosino,encontradeloque
ocurrehabitualmenteconlasllavesenC.

La primera lnea establece el nombre con el que vamos a identificar la clase por
mediodelapalabraintroducidaenelcampo<identificador>.Enelejemplo,elidentificadores
lapalabracomplex.
Una vez establecido el nombre se procede a indicar los datos y los mtodos de la
clase.Aunquenoexisteunaespecificacinenelordenenquelosdatosyfuncionesdebenser
declarados, es habitual proceder a introducir en primer lugar los datos miembro con sus
nivelesdeaccesoydespuselconjuntodemtodostantopblicoscomoprivados.
En el ejemplo se indica en primer lugar que los elementos que se van a declarar
posteriormenteserndecarcterprivado.Estodeharealizadopormediodelapalabraclave
private.Deestaforma,losdatosrealeimagdetipodoubleslopodrnsermodificadosy
consultadospormediodemtodosdelaclase.Veremosconmsdetallelautilidaddetodo
estoalhablardelconceptodeencapsulamientoenelsiguienteapartado.
Despus se indica que a partir del punto en el que parece la palabra public se
declaranlasfuncionesydatosmiembrodelaclasequesonaccesiblesdesdefueradelaclase,
y que por tanto constituyen la interfaz. En el ejemplo, tres funciones tienen este nivel de
acceso: estableceValor, obtenModulo e imprime. Con esto se finaliza la declaracin de la
claseporloqueseprocedeadefinirla.
76 PROGRAMACIN C++ Y COMUNICACIONES.

Definicin o implementacin de una clase


AligualqueocurreconlosprototiposenC,enladeclaracinslohemosinformado
alcompiladorsobreelmododeusoyespecionecesarioparaeltipodeobjetosdefinidospor
laclase.Enladefinicinseprocederaexplicitarlafuncionalidaddecadaunodelosmtodos
pormediodecdigoC++.
Ladefinicinpuedesituarseenunficherodistintodehechoeslomshabitualala
declaracindelaclase.Inclusoesposiblequevariasdefinicionesdedistintasclasesestnen
un mismo fichero para el compilador es indiferente. Sin embargo, es importante indicar
cuandosedefineelcontenidodeunmtododeunaclase,laclasealaquesehacereferencia.
Para definir un mtodo fuera del cuerpo de declaracin de una clase, es necesario indicar
siempreaquclasepertenecedichomtodo.Paraellohayqueespecificarelnombredela
claseantesdelnombredelmtodo,separadodelmismopormediodeloperadordembito
(::).
Lasintaxisserlasiguiente:

<tipo> <iden_clase>::<iden_metodo>(<argumentos>)
{
[cdigo del mtodo]
}

Seobservaqueyanoesnecesarioindicarsielmtodoespblicooprivado,puesto
queestainformacinsehabaestablecidoyaenladeclaracin.
Tambinhayquedestacarquelosmtodosdeunaclase,accedendirectamentealos
datosymtodosdelapropiaclase,mientrasquedesdefueracomoenelcasodelafuncin
main,esnecesarioutilizareloperador.parapoderejecutarlos.

Elpunteroimplcitothis.
Loquehacedistintoadosobjetosdeunamismaclaseesprecisamentelosdatosque
contienen. Por ello, los datos miembro o atributos de un objeto son distintos para cada
objeto,sinembargolasfuncionesomtodossoncomunesatodoslosobjetosdeunamisma
clase.Esdecir,cadaobjetoalmacenasuspropiosdatos,peroparaaccederyoperarconellos,
todoscompartenlosmismosmtodosdefinidosensuclase.Porlotanto,Paraqueunmtodo
conozcalaidentidaddelobjetoenparticularparaelquehasidoinvocado,C++proporciona
un puntero al objeto denominado this. De hecho, el compilador reescribe el cdigo de los
mtodosquehemosdefinido,anteponiendoantetodoslosidentificadoresdelosatributosla
expresin(this>).Implcitamente,todoslosmtodosnoestticosdeunaclasetienencomo
argumentoimplcitounpunteroalobjetoquellamaalmtodo,yesteesaccesiblepormedio
delapalabrathis.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 77

Porejemplo,lafuncionestableceValorpodrareescribirsedelaformasiguiente:
void complex::estableceValor(float re, float im)
{
this->real=re ;
this->imag=im ;
}

AligualqueocurreenC,paraaccederalosmiembrosdeunaestructuraapartirde
unpunteroaunavariabledeestetipo,seutilizaeloperadorflecha.

Instanciacin de un objeto de la clase


Unavezdefinidountipodeobjetospormediodeunaclase,lacreacinyutilizacin
de objetos de esta clase es muy sencilla. Se realiza de forma anloga a como se construye
cualquierotravariabledeuntipopredefinido.As,enlafuncinmaindelejemplo,paracrear
unobjetodetipocomplexbastaconescribirlalnea:
complex micomplejo;

Yparaejecutarlosdistintosmtodosquesehandefinido,seutilizaeloperador.
queindicaquesetratardeunmiembrodelobjetoqueloantecede.Atravsdeloperador
punto, slo se podr acceder a los atributos y mtodos pblicos, quedando los elementos
privadosprotegidosporelcompilador.Deestaforma,lasiguienteexpresindaraunerrorde
compilacin:
micomplejo.real=2.0;

Porloqueparaestablecerelvalordelnmerocomplejoslosepuedehacerusodel
mtodoprevistoestableceValorqueobligaaintroducirtantolaparterealcomolaimaginaria.

Todoestotienemuchoqueverconelconceptodeencapsulamientoquesevera
continuacin.

3.3. Encapsulamiento
Ya se ha comentado que para una clase, los nicos elementos accesibles desde el
exterior son aquellos que han sido declarados como pblicos. Por tanto, los miembros
privadosdeunaclasenosonaccesiblesparafuncionesyclasesexterioresadichaclase.
EnlaprogramacinorientadaaObjetos,losnivelesdeaccesosonelmedioquese
utilizaparalograrelencapsulamientoquenoesmsquecadaobjetosecomportedeforma
78 PROGRAMACIN C++ Y COMUNICACIONES.

autnomayloquepaseensuinteriorseainvisibleparaelrestodeobjetos.Cadaobjetoslo
respondeaciertosmensajesyproporcionadeterminadassalidas.
El siguiente ejemplo ilustra como este concepto es muy importante de cara a
obtener uncdigo reutilizable y seguro que es laprincipal finalidad de la POO. La siguiente
clase lista de nmeros, nos permite almacenar un mximo determinado de nmeros en
memoriaesttica.Dichaclase,evitaqueelusuariocometaerroresdeejecucintalescomo
acceder a un nmero que no existe o introducir un conjunto de nmeros que supere la
capacidaddealmacenamientodeestalistaesttica.
Elprecioquehayquepagarporestaproteccineseltenerqueutilizarparatodaslas
operacionesmtodosyportantofunciones,aunqueestasoperacionesseanmuysencillas.Sin
embargo,elresultadoesrobusto,yfcilmentetrasladableavariosprogramas.
class listaNumeros
{
private:
int num;
int lista[100];
public:
int agregarNumero(int val);
int extraerNumero(int ind);
int numeroNumeros(void);
listaNumeros(void);
};
//constructor de la clase en breve se ver su utilidad
listaNumeros::listaNumeros(void){
num=0;
}
int listaNumeros::agregarNumero(int val){
if(num<100)lista[num++]=val;
else return -1;
return num;
}
int listaNumeros::extraerNumero(int ind){
if((ind<num)&&(ind>=0))return lista[ind];
return 0;
}
int listaNumeros::numeroNumeros(){
return num;
}

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 79

#include <iostream.h>
void main()
{
listaNumeros milista;
int i,val=1;
while(val!=0)
{
cout<<"introduzca un numero (finalizar con 0):";
cin>>val;
if(val!=0)val=milista.agregarNumero(val);
}
cout<<"\nLa lista de nmeros es la siguiente:\n";
for(i=0;i<milista.numeroNumeros();i++)
cout<<milista.extraerNumero(i)<<" ";
cout<<"\n*********FIN DEL PROGRAMA**********\n";
}

Las funciones diseadas exclusivamente para servir de interfaz de la parte privada
sonhabitualmentepequeas,yocupanmuypoquitaslneas.Dehechoesmuyhabitualque
existanunaseriedemtodoscuyanicafuncinesdevolverelvalordeunatributo,yquepor
tantosolocontienenunasentencia:returndelatributo.

Enestecasoeshabitualescribirelcontenidodeestasfuncionesdirectamenteenla
declaracin de la clase. Cuando un mtodo se define en la declaracin de una clase este
mtodopasaserdetipoinline.Loquesignificaquecuandoseallamadoporcualquierparte
delprograma,envezderealizarelprocesodellamadaaunmtodo,elcompiladorrealizauna
sustitucindelasentenciadellamadaporelcontenidointerpretadodelmtodo.Portanto,
ser un proceso rapidsimo en ser ejecutado, a costa de que el cdigo de la funcin se
repetirtantasvecescomollamadasexplcitasseescribenenelcdigo.

Por ello, aunque cualquier funcin puede ser definida como inline, slo se utiliza
paraaquellasfuncionespequeasenlasqueelprocesodeejecucindeunmtodoesmayor
quelaejecucindelmtodoens.Estoesloqueocurrircontodaslasfuncionesdeconsulta
omodificacindeatributosnopblicosdeunaclase.
Elcdigoanteriorpodraserreescritoentoncesdelasiguienteforma:
class listaNumeros
{
private:
int num;
int lista[100];
public:
int agregarNumero(int val);
int extraerNumero(int ind)
80 PROGRAMACIN C++ Y COMUNICACIONES.

{
if((ind<100)&&(ind>=0))return lista[ind];
return 0;
}
int numeroNumeros(void){return num;};
listaNumeros(void){num=0;};
};

int listaNumeros::agregarNumero(int val)


{
if(num<100)lista[num++]=val;
else return -1;
return num;
}

Aunque el mtodo agregarNumero podra perfectamente haberse definido en la
declaracindelaclase,yportantohabersedeclaradocomoinline,sehapreferidodejarlode
laformainicialmentedescritaparamostrarcomoenunaclaselonormalesmezclarambos
modosdedefinirlosmtodos.

Cuandoelmtodoestanbrevequepuedeserescritoenlamismalneadelapropia
declaracin del mtodo, se opta por la brevedad para evitar declaraciones de clase
excesivamenteextensas.

Laimportanciadelaencapsulacinpuedeponersedemanifiestoenestapequeay
poco til clase. Tal y como est diseada, no es posible que exista incoherencia entre el
contenido del vector de enteros (lista) y el indicador del nmero de enteros introducido
(num),puestoquelosvaloresalmacenadosenambos,sonmodificadosporlosmtodosdela
clase, los cuales se aseguran de que los valores introducidos son vlidos. Al impedir que el
usuario modifique directamente el valor de estos atributos, se evita la aparicin de
incoherenciasyportantoseeliminaunadelasmayoresfuentesdeerror.
Laclaseademsgestionalapropiacapacidaddealmacenamiento,deformaquese
aseguradequenuncaseintroduzcanmsdeciennmeros.Aunqueelusuariopidaintroducir
doscientos nmeros slo se almacenaran cien, puesto que slo se dispone de espacio para
cien.
Por todo esto es muy interesante que los atributos que afectan al funcionamiento
interno de una clase se declaren protegidos ante posibles modificaciones externas y que
siempre se compruebe la validez de los valores solicitados por medio de las distintas
funcionesdeinterfaz.
Sinembargo,enciertasocasiones,sequerrteneraccesoadeterminadosmiembros
privadosdeunobjetodeunaclasedesdeotrosobjetosdeclasesdiferentes.Paraesoscasos

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 81

(quedeberanserexcepcionales)C++proporcionaunmecanismoparasortearelsistemade
proteccin. Ms adelante se ver la utilidad de esta tcnica, ahora se limitar a explicar en
queconsiste.ElmecanismodelquesedisponeenC++eseldenominadodeamistad(friend).

Clases y mtodos friend


Lapalabraclavefriendesunmodificadorquepuedeaplicarsetantoaclasescomoa
funcionesparainhibirelsistemadeproteccindeatributosyfuncionesdeunaclase.Laidea
generalesquelaparteprivadadeunaclasesolopuedesermodificadaoconsultadaporla
propiaclaseoporlosamigosdelaclase(tantomtodoscomofunciones).
Se puede establecer un cierto paralelismo con el concepto de amistad entre
personas para facilitar algunas ideas bsicas sobre como funciona este mecanismo en C++.
Algunasdeestasideassepuedenresumirenlassiguientesafirmaciones:

La amistad no puede transferirse: si A es amigo de B, y B es amigo de C,


estonoimplicaqueAseaamigodeC.(Lafamosafrase:losamigosdemis
amigossonmisamigosesfalsaenC++yenlavidareal,puestoqueesfcil
deducir entonces que todos somos amigos de todos y menuda amistad es
esaenlaquemueretantagenteamanosdeotragente).

Laamistadnopuedeheredarseyaveremoselconceptodeherencia.SiA
esmigodeB,yCesunaclasehijadeB,AnotienequeseramigodeC.(Los
hijosdemisamigos,notienenporquseramigosmos.Denuevo,elsmiles
casiperfectohaycadahijodemisamigos).

Laamistadnoessimtrica.SiAesamigodeB,Bnotieneporqueseramigo
deA.(EnlavidarealunasituacincomoestaharpeligrarlaamistaddeA
con B, pero de nuevo y por desgracia se trata de una situacin muy
frecuenteenlaqueAnosabeloqueBpiensadelbastaconobservarlo
quealgunossoncapacesdedecirdesusamig@sasuespalda).

Funciones amigas de una clase


Elsiguienteejemploilustraelconceptodeamistad,aunqueenesteprogramanoes
funcionalmentetil.Paraqueunafuncinseaamigadeunaclase,yportantotengaaccesoa
laparteprivadadelosobjetosdedichaclase,sabeserdefinidacomoamiga(anteponiendola
palabra friend al prototipo) en la declaracin de la clase. Lgicamente, es la clase la que
define quin es amiga suya. Se observa que la funcin Ver no tiene que indicar en ningn
momento quien la considera amiga, de tal forma que podramos tener millares de clases
amigas de dicha funcin sin que por ello esta vea afectada su definicin. Cada una de las
82 PROGRAMACIN C++ Y COMUNICACIONES.

clasessinembargodeberincluirdentrodesudeclaracinlacopiadelprototipodelafuncin
precedidadelapalabrafriend.
#include <iostream>
class A
{
public:
A(int i) {a=i;};
void Ver() { cout << a << endl; }
private:
int a;
friend void Visualiza(A); //Visualiza es amiga de la clase A
};

// La funcin Visualiza puede acceder a miembros privados


// de la clase A, ya que ha sido declarada "amiga" de A
void Visualiza(A Xa)
{
cout << Xa.a << endl;
}

void main()
{
A Na(10);
Visualiza(Na); // imprime el valor de Na.a
Na.Ver(); // Equivalente a la anterior
}

Seobservacomolafuncinvisualizaescapazdeaccederdirectamentealmiembro
privadoa,delobjetoNagraciasasucondicindefuncinamigadelaclase.Sienestemismo
ejemplo eliminsemos la lnea de la declaracin de la clase A en la que se define Visualiza
comofuncinamiga,elcompiladordaraunerrorporintentaraccederaunmiembroprivado
delobjetopasadoenXa.
Alfinaldeestecaptuloseintroduceuncdigoextensoqueilustralautilidaddeeste
mecanismo.
Es importante destacar para finalizar que una funcin amiga de una clase, no es
miembrodeesaclase.

Mtodos de una clase amigos de otra clase


Enestecasoseprecisaqueunmtododeunaclaseseacapazdeaccederalosdatos
ymtodosprivadosdeotraclase.
#include <iostream>
class A; // Declaracin previa (forward)

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 83

class B
{
public:
B(int i){b=i;};
void ver() { cout << b << endl; };
bool esMayor(A Xa); // Compara b con a
private:
int b;
};
class A
{
public:
A(int i=0) : a(i) {}
void ver() { cout << a << endl; }
private:
// Funcin amiga tiene acceso
// a miembros privados de la clase A
friend bool B::esMayor(A Xa);
int a;
};
bool B::esMayor(A Xa)
{
return (b > Xa.a);
}
void main(void)
{
A Na(10);
B Nb(12);
Na.ver();
Nb.ver();
if(Nb.esMayor(Na)) cout << "Nb es mayor que Na" << endl;
else cout << "Nb no es mayor que Na" << endl;
}

La funcin EsMayor pertenece a la clase B, pero en la declaracin de la clase A se


indicaquedichomtodoescapazdeaccederalaparteprivadadeA.Porello,esindiferente
el lugar dentro de la declaracin de A en el que se incluye la declaracin de amistad del
mtododelaclaseB.Enelejemplo,sehaintroducidoenlaparteprivadadeladeclaracin,
pero podra haberse situado en cualquier otra parte de la declaracin. Puesto que ambas
clasesdebenhacersereferenciaentres,esnecesariorealizarunadeclaracinanticipadade
laexistenciadelaclasesituadaensegundolugardeformaqueelcompiladornodeunerror
durantelainterpretacin.Estaeslafinalidaddelasegundalnea.
84 PROGRAMACIN C++ Y COMUNICACIONES.

Desde el punto de vista sintctico se observa que la declaracin de amistad de un


mtodoyunafuncinsonprcticamenteequivalentes,puestoquelainclusindeB::indica
quesetratadeunafuncinmiembrodeB.
Estemecanismoesbastantemsutilizadoqueelanteriordebidoaquelosmtodos
amigosdeunaclasesoncapacesdeaccederalaparteprivadadesupropiaclaseydelaclase
respectodelacualtienenunarelacindeamistad.

Clase amiga de otra clase


Cuandoloquesedeseaesquetodoslosmtodosdeunaclasetenganlacapacidad
deaccederalaparteprivadadeotra,entonces,envexdeirdefiniendolarelacindeamistad
paracadaunodelosmtodosdelaclase,bastarcondefinirquetodalaclaseesamiga.
As,porejemplo,sisequierequetodoslosmtodosdelaclaseC1seanamigosdela
claseC2,yportantotenganaccesoalaparteprivadadelosobjetosdelaclaseC2,entonces
esquemticamenteestadeclaracinserealizaradelaformasiguiente:
class C1
{

};
class C2
{

friend class C1;

};

3.4. Constructores y destructores


Existen dos tipos de funciones miembro de una clase especiales cuya funcin es
asegurar que la creacin y destruccin de los objetos se realiza de forma correcta. Estas
funciones que tienen una sintaxis especfica se denominan como constructores los
encargadosdelacreacindelobjetoyeldestructorencargadodesudestruccin.

Constructores de una clase


Los constructores son funciones miembro especiales que sirven para inicializar un
objetodeunadeterminadaclasealmismotiempoquesedeclara.

Losconstructorestienenelmismonombrequelaclase,noretornanningnvalory
no pueden ser heredados. Adems suelen ser pblicos, dado que habitualmente se usan
desdeelexteriordelaclase.Algunospatronesmsavanzadosdelovistoenestecurso,como
elsingletonhacenusoamenudodeconstructoresprivadosoprotegidos,peroennuestro
casoengenerallosdeclararemoscomopblicos.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 85

Losconstructoressuelenserpblicos.

La siguiente clase es puramente ilustrativa, y sirve para almacenar parejas de


nmeros. Para la misma se ha definido un constructor y se ha utilizado en el cuerpo del
programa:
#include <iostream>
class pareja
{
public:
// Constructor
pareja(int a2, int b2);
// Funciones miembro de la clase "pareja"
void lee(int &a2, int &b2);
void guarda(int a2, int b2);
private:
// Datos miembro de la clase "pareja"
int a, b;
};
//definicin del constructor
pareja::pareja(int a2, int b2)
{
a = a2;
b = b2;
}
void pareja::lee(int &a2, int &b2) {
a2 = a;
b2 = b;
}
void pareja::guarda(int a2, int b2) {
a = a2;
b = b2;
}
void main(void)
{
pareja par1(12, 32);
int x, y;
par1.lee(x, y);
cout << "Valor de par1.a: " << x << endl;
cout << "Valor de par1.b: " << y << endl;
}

86 PROGRAMACIN C++ Y COMUNICACIONES.

Siunaclaseposeeconstructor,serllamadosiemprequesedeclareunobjetodeesa
clase, y si requiere argumentos, es obligatorio suministrarlos. Por ejemplo, las siguientes
declaracionessonilegales:
pareja par1;
pareja par1();

La primera porque el constructor de "pareja" requiere dos parmetros, y no se
suministran. La segunda es ilegal por otro motivo ms complejo. Aunque existiese un
constructor sin parmetros, no se debe usar esta forma para declarar el objeto, ya que el
compiladorloconsideracomoladeclaracindeunprototipodeunafuncinquedevuelveun
objetodetipo"pareja"ynoadmiteparmetros.Cuandoseuseunconstructorsinparmetros
paradeclararunobjetonosedebenescribirlosparntesis.
Lassiguientesdeclaracionessonvlidas:
pareja par1(12,43);
pareja par2(45,34);

Cuandonoseespecificaunconstructorparaunaclase,elcompiladorcreaunopor
defectosinargumentosalquesedenominacomoconstructordeoficio.Poresolosejemplos
anterioresfuncionabancorrectamente.Cuandosecreanobjetoslocales,losdatosmiembros
no se inicializan si el programador no se preocupa de hacerlo. Contendran la "basura" que
hubieseenlamemoriaasignadaalobjeto.Curiosamente,sisetratadeobjetosglobales,los
datos miembros se inicializan a cero. Esto se realiza de esta forma porque el proceso de
inicializacin lleva un tiempo. Los objetos locales son por propia definicin temporales y
puedensercreadosmuchasvecesdurantelaejecucindeunprograma,porloquealfinal,el
tiempo de inicializacin puede ser significativo. Por el contrario, los objetos globales son
inicializados al comenzar la ejecucin del programa, por lo que esto se hace una sla vez y
durantelapreparacindelaejecucindelcdigo.
Paradeclararobjetosusandoelconstructorpordefectoounconstructorquesehaya
declaradosinparmetrosnosedebeusarelparntesis:
pareja par2();

Se trata de un error frecuente cuando se empiezan a usar clases, lo correcto es


declararelobjetosinusarlosparntesis:


pareja par2;

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 87

Inicializacin de objetos
Existe un modo simplificado de inicializar los datos miembros de los objetos en los
constructores. Se basa en la idea de que en C++ todo son objetos, incluso las variables de
tiposbsicoscomoint,charofloat.
Segn esto, cualquier variable (u objeto) tiene un constructor por defecto, incluso
aquellos que son de un tipo bsico. Slo los constructores admiten inicializadores. Cada
inicializador consiste en el nombre de la variable miembro a inicializar, seguida de la
expresin que se usar para inicializarla entre parntesis. Los inicializadores se aadirn a
continuacindelparntesiscerradoqueencierraalosparmetrosdelconstructor,antesdel
cuerpodelconstructoryseparadodelparntesispordospuntos":".
Porejemplo,enelcasoanteriordelaclasepareja:
pareja::pareja(int a2, int b2)
{
a = a2;
b = b2;
}
Sepuedesustituirelconstructorpor:
pareja::pareja(int a2, int b2) : a(a2), b(b2) {}

Por supuesto, tambin pueden usarse inicializadores en lnea, dentro de la


declaracindelaclase.Ciertosmiembrosesobligatorioinicializarlos,yaquenopuedenser
asignados. Este es el caso de las constantes y las referencias. Es muy recomendable usar la
inicializacinsiemprequeseaposibleenlugardeasignaciones,yaquesedesdeelpuntode
vistadeC++esmuchomsseguro.

Aligualqueocurreconlasfuncionesglobales,ycomoyaveremosconlosmtodosy
operadores,esposiblesobrecargarelconstructor.Recurdesequelasobrecargasignificaque
bajounmismoidentificadorseejecutancdigosdistintosenfuncindelosargumentosque
se pasen parala ejecucin. Por eso, lanica restriccin en la sobrecarga es que no pueden
definirsedosconstuctoresquenosediferencienenelnmeroytipodelosargumentosque
utilizan.

Paralaclasepalabra,enelsiguienteejemplo,seaadendosnuevosconstructores,el
primerosinargumentosqueinicializalaparejaacero,alquesedenominaconstructorpor
defecto. El segundo, inicializar la pareja por medio de un nmero real del cual extrae el
primerdgitodelapartedecimalylaparteentera.


class pareja
88 PROGRAMACIN C++ Y COMUNICACIONES.

{
public:
// Constructor anterior
pareja(int a2, int b2) : a(a2), b(b2) {}
//contructor por defecto
pareja() : a(0), b(0) {}
//otro constructor
pareja(double num);
// Funciones miembro de la clase "pareja"
void Lee(int &a2, int &b2);
void Guarda(int a2, int b2);
private:
// Datos miembro de la clase "pareja"
int a, b;
};
pareja::pareja(double num)
{
a=(int)num;
b=((int)(num*10))%10;
}
void main()
{
pareja p1,p2(12,3),p3(2.8);

}

Laparejap1serentoncesinicializadaconlosvalores(a=0,b=0),p2con(a=12,b=3)y
p3con(a=2,b=8).Deestemodosepuedendefinirmuchasmanerasdeinicializarlosobjetos
deunaclase.
Al igual que cualquier funcin, es posible definir valores por defecto para los
parmetros.Elinconvenienteesquesiexistendosfuncionesquetienendefinidosvalorespor
defectodetodossusargumentos,seproducirunaambigedadalahoradedefinircualde
lasdossetienequeejecutar.Elcompiladorinformardeestasituacin,yencasodequesea
necesario utilizar el constructor por defecto en alguna parte del cdigo es posible que
aunquesehayadefinidonosehagausodelentoncesgenerarunerrordecompilacin.
Porejemplo,elcompiladornopermitiralaejecucindelsiguienteprograma:
#include <iostream.h>
#include <math.h>
class pareja
{
public:
// Constructor anterior con valores por defecto
pareja(int a2=0, int b2=0) : a(a2), b(b2) {}

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 89

//contructor por defecto


pareja() : a(0), b(0) {}
void Lee(int &a2, int &b2);
void Guarda(int a2, int b2);
private:
int a, b;
};

void main()
{
pareja p1;
pareja p2(12,3),p3(2.8);
int a,b;
p1.Lee(a,b);
cout<<a<<','<<b;
}

eindicaraelsiguienteerrorenlalneadedeclaracindep1:

pareja::pareja':ambiguouscalltooverloadedfunction

El constructor de copia
Existeotrotipodeconstructorespecialqueencasodequelprogramadornodefina
el compilador asigna uno de oficio. Este es el llamado constructor de copia, y que como su
propionombreindicasirveparainicializarunobjetocomocopiadeotro.

El constructor de copia de oficio actuar de la misma forma que una igualdad no


sobrecargada.Realizarunacopialiteraldelosatributosodatosmiembrodeunobjetosobre
el otro. Habitualmente esto ser suficiente, pero hay algunos casos en el que esto no es
conveniente. La misma razn y ejemplo que se utilizar para explicar la necesidad de
sobrecargarlaoperacindeigualdadservirparailustrarlanecesidaddedefinirenalgunos
casosunconstructordecopianodeoficio.
Lasintaxisdelconstructordecopiaserhabitualmentelasiguiente:

ident_clase::ident_clase(const tipo_clase &obj);

Paraelejemploparejasepodraescribirlosiguiente:
class pareja
90 PROGRAMACIN C++ Y COMUNICACIONES.

{

pareja(const pareja &p):a(p.a),b(p.b){}

}
void main(void)
{
pareja p1(12,32);
pareja p2(p1); //Uso del constructor de copia

}

El destructor
El complemento a los constructores de una clase es el destructor. As como el
constructorsellamaaldeclararocrearunobjeto,eldestructoresllamadocuandoelobjeto
vaadejardeexistirporhaberllegadoalfinaldesuvida.Enelcasodequeunobjetolocal
haya sido definido dentro de un bloque {}, el destructor es llamado cuando el programa
llegaalfinaldeesebloque.
Si el objeto es global o static su duracin es la misma que la del programa, y por
tantoeldestructoresllamadoalterminarlaejecucindelprograma.Losobjetoscreadoscon
reserva dinmica de memoria (en general, los creados con el operador new) no estn
sometidos a las reglas de duracin habituales, y existen hasta que el programa termina o
hasta que son explcitamente destruidos con el operador delete. En este caso la
responsabilidadesdelprogramador,ynodelcompiladorodelsistemaoperativo.Eloperador
delete llama al destructor del objeto eliminado antes de proceder a liberar la memoria
ocupadaporelmismo.
A diferencia del constructor, el destructor es siempre nico (no puede estar
sobrecargado) y no tiene argumentos en ningn caso. Tampoco tiene valor de retorno. Su
nombre es el mismo que el de la clase precedido por el carcter tilde (~), carcter que se
consigueconAlt+126eneltecladodelPComedianteelusodelosdenominadostrigrafos(??
).Lostrigrafossonconjuntosdecaracteresprecedidospor??queelpreprocesadorconvierte
auncarcteravecesnopresenteenalgunostecladosoidiomas.Portanto,paraelordenador
eslomismollegaraescribirelcarcter~queelconjuntodecaracteres??.

En el caso de que el programador no defina un destructor, el compilador de C++


proporcionaundestructordeoficio,queescasisiempreplenamenteadecuado(exceptopara
liberarmemoriadevectoresymatrices).

Enelcasodequelaclaseparejanecesitaseundestructor,ladeclaracinseraas:
~pareja();

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 91

Elsiguienteejemplomuestrauncasoenelqueesnecesarioalmacenarunacadena
decaracteresdetamaovariable,porloquealsereliminadoelobjetoesnecesarioliberarla
memoriareservadadeformadinmica:

class persona
{
public:
persona(const char *nom, long dni);
persona():nombre(NULL),DNI(0){};
??-persona(); //podra haberse escrito ~persona();
void mostrar();
private:
char *nombre;
long DNI;
};
persona::persona(const char *nom,long dni)
{
nombre=new char[strlen(nom)+1];
strcpy(nombre,nom);
DNI=dni;
cout<<"Construyendo "<<nombre<<endl;
}

persona::~persona() // ??- y ~ son lo mismo


{
cout<<"Destruyendo "<<nombre<<endl;
delete [] nombre;
}
void persona::mostrar()
{
cout<<"almacenado:"<<nombre<<" DNI:"<<DNI<<endl;
}
void main(void)
{
persona p1("dura todo el main",10);
for(int i=0;i<2;i++)
{
persona p2("Dura el ciclo del for ",i);
p2.mostrar();
}
}

92 PROGRAMACIN C++ Y COMUNICACIONES.

Elresultadodeejecutaresteprogramaeselsiguiente:
Construyendo dura todo el main
Construyendo Dura el ciclo del for
almacenado:Dura el ciclo del for DNI:0
Destruyendo Dura el ciclo del for
Construyendo Dura el ciclo del for
almacenado:Dura el ciclo del for DNI:1
Destruyendo Dura el ciclo del for
Destruyendo dura todo el main

Loquepermitevisualizarcomohansidollamadoslosconstructoresydestructoresde
losobjetosquesehancreado.

3.5. Mtodos y operadores sobrecargados

Mtodos sobrecargados
En el captulo de modificaciones menores a C, uno se los puntos que se vio era la
posibilidadqueofreceC++paraescribirvariasfuncionesqueteniendoelmismoidentificador
eran diferenciadas por el tipo de parmetros utilizado. De esta forma se facilitaba la
comprensindelcdigoylafacilidaddeprogramacinalevitareltenerqueutilizarnombres
distintosparatiposdeargumentosdistintoscuandolafuncionalidadesparecida.
Bueno, pues este mismo concepto es aplicable a los mtodos de una clase. Baste
parailustrarloelsiguienteejemplo:
#include <iostream>
struct punto3D
{
float x, y, z;
};
class punto
{
public:
void Asignar(float xi, float yi, float zi)
{
x = xi;
y = yi;
z = zi;
}
void Asignar(punto3D p)
{
Asignar(p.x, p.y, p.z);
}

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 93

void Ver()
{
cout << "(" << x << "," << y
<< "," << z << ")" << endl;
}
private:
float x, y, z;
};
void main(void)
{
punto3D p3d = {32,45,74};
P.Asignar(p3d);
P.Ver();
P.Asignar(12,35,12);
P.Ver();
}

Operadores sobrecargados
En C++ los operadores pasan a ser unas funciones como otra cualquiera, pero que
permiten para su ejecucin una notacin especial. Todos ellos tienen asignada una funcin
pordefectoqueeslaquehastaahorahabamosutilizadoenC.Porejemplo,eloperador+
realizarlasumaaritmticaolasumadepunterosdelosoperandosquepongamosaambos
lados.
Apartirdeahora,podremoshacerqueeloperador+realiceaccionesdistintasen
funcin de la naturaleza de los operandos sobre los que trabaja. De hecho, en realidad, la
mayora de los operandos en C++ estn sobrecargados. El ordenador realiza operaciones
distintas cuando divide enteros que cuando divide nmeros en coma flotante. Un ejemplo
ms claro sera eldel operador *,que enunoscasos trabaja como multiplicadory en otros
realizalooperacindeindireccin.

EnC++elprogramadorpuedesobrecargarcasitodoslosoperadoresparaadaptarlos
asuspropiosusos.Paraellodisponemosdeunasintaxisespecficaquenospermitedefinirlos
odeclararlosaligualqueocurreconlasfunciones:

Prototipo para los operadores:


<tipo> operator <operador> (<argumentos>);

Definicin para los operadores:


<tipo> operator <operador> (<argumentos>)
{
<sentencias>;
94 PROGRAMACIN C++ Y COMUNICACIONES.

Antes de ver lo interesante de su aplicacin como operadores miembros de una


clase,esnecesariomostraralgunaslimitacionesenlasobrecargadeoperadores,ascomosu
usocomofuncionesexternasaunaclase.
Limitaciones:

Sepuedensobrecargartodoslosoperadoresexcepto.,.*,::,?:.

Los operadores =,[ ],>,new y delete, slo pueden ser


sobrecargadoscuandosedefinencomomiembrosdeunaclase.

Al menos uno de los argumentos para los operadores externos deben ser
tiposenumeradosoestructurados:struct,enum,unionoclass.

No se pueden cambiar la precedencia, asociatividad o el nmero de


operandos de un operador, pero s el velor de retorno salvo para los
conversoresdetipo.

La sobrecarga de &&, || y , hacen que pierdan sus propiedades


especiales de evaluacin ordenada con efecto colateral. Pasarn a
comportasecomocualquierotrooperadorofuncin.

Eloperador>deberetornarunpunterosobreelquesepuedaaplicarel
accesoalcampocorrespondiente.

Para ilustrar cmo se pueden sobrecargarlos operadores en C++, se va a definir la


operacinsumaparalasestructurasdecomplejosquesepusieroncomoejemploalcomienzo
delcaptulo:
typedef struct _complex{
float real;
float imag;
}complex;

complex operator +(complex x,complex y)


{
complex z;
z.real=x.real+y.real;
z.imag=x.imag+y.imag;
return z;
}
#include <iostream.h>

void main()

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 95

{
complex a={5.0F,3.0F},b={3.0F,1.2F},c;
c=a+b;
cout<<c.real<<"+"<<c.imag<<"i"<<endl;
}

Puesto que lo que se ha sobrecargado es el operador suma con dos operandos, es
necesarioqueaparezcantantoenelprototipocomoenladefinicinestosdosoperandoscon
sutipo.Esfcildeducirqueconestasintaxissepodrngeneraroperadoressumaquesean
capacesdesumarvectoresycomplejosyquesuresultadoseaunamatriz.Comosiempre,C++
nosdaunaherramientaqueclarificaelcdigo,perosiguedependiendodelprogramadorque
suusosealgico.

Sin embargo, donde ms aplicacin y uso tiene la sobrecarga de operadores es


cuandoeloperadoresmiembrodeunaclase.Sevaadistinguiracontinuacinlosoperadores
binarios(trabajancondosoperandos)delosunarios(trabajanconunosolo).

Sobrecarga de operadores binarios


Comosupropionombreindica,losoperadoresbinariossonaquellosquerequieren
de dos operandos para calcular el valor de la operacin. Esto aparece muy claro en los
operadoresdefinidosenelexteriordeunaclase.

Sin embargo, cuando un operador binario es a su vez miembro de una clase, se


asumequeelprimeroperandodelaoperacineselpropioobjetodelaclasedondesedefine
eloperador.Porello,enlasobrecargadeoperadoresbinariosslosernecesarioespecificar
unoperando,puestoqueelotroeselpropioobjeto.

Portanto,enladeclaracindelaclaseseincluirunalneaconlasiguientesintaxis:

<tipo> operator<operador binario>(<tipo> <identificador>);

Habitualmente<tipo>serparaunobjetodelamismaclase,peronoesnecesario.
Aselcasomshabitualesquesiestamossumandocomplejos,elprimerysegundooperador
seandetipocomplejoyelresultadouncomplejo.

Sinembargonotieneporqueserdeestamanera.Porejemploenelcasodeoperar
conmatrices,esperfectamentevlidodefinirunaoperacinproductoentreunamatrizyun
vector,objetosdedosclasesdistintas,ycuyoresultadoesunvector.Silaoperacinproducto
96 PROGRAMACIN C++ Y COMUNICACIONES.

estdefinidaenelinteriordelaclasematriz,elargumentoserdetipovectoryelvalorde
retornotambin.
Semostrarunejemplosencillo,quepermiteoperarconvaloresdetiempodeforma
sencilla. En esta clase se definir el operador suma de tal forma que se puedan sumar
periodosdeduracinmedidosenhorasyminutos.
#include <iostream.h>
class Tiempo
{
public:
Tiempo(int h=0, int m=0) : hora(h), minuto(m) {}
void Mostrar(){cout << hora << ":" << minuto << endl;};
Tiempo operator+(Tiempo h);
private:
int hora;
int minuto;
};

Tiempo Tiempo::operator+(Tiempo h)
{
Tiempo temp;
temp.minuto = minuto + h.minuto;
temp.hora = hora + h.hora;
if(temp.minuto >= 60){
temp.minuto -= 60;
temp.hora++;
}
return temp;
}
void main(void)
{
Tiempo Ahora(12,24), T1(4,45);
T1 = Ahora + T1;
T1.Mostrar();
(Ahora + Tiempo(4,45)).Mostrar(); //(1)
}

En este ejemplo se ha introducido una de las posibilidades que ofrece C++ hasta
ahora no comentada ni utilizada. En el punto del cdigo marcado con (1), se utiliza una
instanciadelaclasesinhaberledadounnombre.Esdecir,Tiempo(4,5)creaunobjetoqueno
podremosreferenciarposteriormenteunavezejecutadalasentenciapuestoquenolehemos
asignadoningnidentificador.Sinembargoelobjetoexistirypodrserutilizado,deforma
queen(1)seestdiciendoquesesumealtiempoguardadoenAhorauntotalde4horasy45
minutos.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 97

Igualesmuchodegolpe,peroesmomentodecomenzarairviendocdigomsreal.
Acontinuacinserealizarunasobrecargadeloperadorsumadetalformaqueala
horalevamosasumarslominutos.Enesecaso,eloperadorsumarecibircomosegundo
operandounvalorentero,ydarcomoresultadounobjetoTiempo.
#include <iostream.h>
class Tiempo
{
public:
Tiempo(int h=0, int m=0) : hora(h), minuto(m) {};
void Mostrar(){cout << hora << ":" << minuto << endl;};
Tiempo operator+(Tiempo h);
Tiempo operator+(int mins);
private:
int hora;
int minuto;
};

Tiempo Tiempo::operator+(Tiempo h)
{
Tiempo temp;
temp.minuto = minuto + h.minuto;
temp.hora = hora + h.hora;
if(temp.minuto >= 60)
{
temp.minuto -= 60;
temp.hora++;
}
return temp;
}
Tiempo Tiempo::operator +(int mins)
{
Tiempo temp;
temp.minuto=minuto+mins;
temp.hora=hora+temp.minuto/60;
temp.minuto=temp.minuto%60;
return temp;
}

void main(void)
{
Tiempo Ahora(12,24), T1(4,45);
T1 = Ahora + T1;
T1.Mostrar();
(Ahora+45).Mostrar();
}
98 PROGRAMACIN C++ Y COMUNICACIONES.


Denuevosehautilizadounobjetotemporalqueeselretornadoporeloperador+.El
compilador diferencia a cual de las dos operaciones suma hacemos referencia gracias al
distinto tipo de operandos utilizado en cada caso. As, en la primera suma se ejecuta el
operadorparasumardostiempo,mientrasqueenlasegundaseejecutareloperadorque
permitelasumadeuntiempoyunosminutos.
ObsrveseaunqueestoestemadeCcmoseaprovechaelmodoenqueCopera
distintoconlosnmerosencomaflotanteylosenterosparapodertransformarlosminutos
enlashorasyminutoscorrespondientes.

Sobrecargadeloperadorigual.
Unoperadorqueamenudoesnecesariosobrecargareseloperadorigual.Sinose
sobrecarga este operador, el compilador asignar uno por defecto (como en el caso del
ejemplo) querealizar unacopia literal de lo que hay enla memoria de un objeto sobre el
otro. Este operador por defecto es vlido siempre que no se est utilizando memoria
dinmica,peropuedecrearautnticosquebraderosdecabezaencasocontrario.
Unejemplotpicodeestasituacineseldeunaclaseconcapacidaddealmacenar
frases tan largas como se quiera: la clase cadena. El siguiente cdigo no funcionar como
deseamos,yposiblementenosdemuchosproblemas:
class Cadena
{
public:
Cadena(char *cad);
Cadena() { cadena=NULL;} ;
~Cadena() { delete[] cadena; };
void Mostrar(){cout << cadena << endl;};
void RellenarDeGuiones();
private:
char *cadena;
};
Cadena::Cadena(char *cad)
{
cadena = new char[strlen(cad)+1];
strcpy(cadena, cad);
}
void Cadena::RellenarDeGuiones()
{
for(int i=0;i<strlen(cadena);i++)
cadena[i]=-;
}

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 99

Siejecutamoselsiguienteprograma,seobservaqueelresultadodistamuchodeser
elesperadoademsdegenerarunerroralfinalizarselaejecucin:
void main(void)
{
Cadena C1(Hola Mundo), C2(Qu tal?); //(1)
C1.Mostrar();
C2.Mostrar();
C1=C2; //(2)
C2.RellenarDeGuines(); //(3)
C1.Mostrar();
C2.Mostrar();
}

Encontradeloquepuedaparecer,enlaimpresinsegundaimpresindeC1yC2,en
pantalla aparecen solo guiones para ambas cadenas Por qu, si en el cdigo solo se ha
indicadoelrellenodeguionesparaC2?PorquesmodificadoC1?.
Las tres columnas siguientes muestran el estado de C1 y C2 en (1), (2), y (3) en la
memoria, en donde como es habitual el contenido del puntero es representado por una
flecha.

COPIA
1000 1000 1000
C1 C1 C1
Cadena = 1050 Cadena = 1150 Cadena = 1150

1020 1020 1020


C2 C2 C2
Cadena = 1150 Cadena = 1150 Cadena = 1150

1050 1050 1050


Hola Mundo Hola Mundo Hola Mundo

1150 1150 1150


Qu tal? Qu tal? -------

SITUACION 1 SITUACION 2 SITUACION 3


100 PROGRAMACIN C++ Y COMUNICACIONES.

Al hacer la asignacin no se ha copiado el contenido de la cadena, sino que se ha


copiado el valor almacenado en el puntero. Ese puntero era el que sealaba la zona de la
memoriaendondepormediodeloperadornewelsistemahabareservadoelespaciopara
almacenar la frase. Tras la asignacin, tanto C1 como C2 tienen un puntero que apunta al
mismo sitio (el lugar que originalmente se haba reservado para C2), mientras que hay una
zonadememoriaquesehabareservadoyquenoquedaapuntadaporningunodelosdos.
PoresoalmodificartantoC1comoC2,elresultadoseobservaenambos,puestoque
ambos estn apuntando el mismo sitio. Adems se produce un error en la ejecucin del
programa, puesto que al eliminarse C1 se eliminar la memoria apuntada por su puntero
cadena,yelsistema,alintentareliminarC2,seencontrarconqueelsitioapuntadoyano
pertenece al programa pues ha sido liberado. Recurdese que no se puede llamar a delete
sobreunadireccinquenonospertenece.
Paraevitaresteproblemasepuedesobrecargareloperadordeasignacin,deforma
que al hacer el igual lo que se realiza en la memoria es una duplicacin del espacio y una
copiacarcteracarcterdeunacadenasobrelaotra.

Elcdigopararealizaresteoperadorseraelsiguiente:
Cadena &Cadena::operator=(const Cadena &c)
{
if(this != &c)
{
delete[] cadena;
if(c.cadena)
{
cadena = new char[strlen(c.cadena)+1];
strcpy(cadena, c.cadena);
}
else cadena = NULL;
}
return *this;
}
Al manejar punteros hay que tener una serie de precauciones que aparecen de
manifiesto en este ejemplo. Por ejemplo, inicialmente se comprueba que no se est
realizandounaasignacindeunaCadenasobresmisma.Secompruebaantessiexisteuna
cadena en el objeto cadena pasado, y no hubiera estado de ms comprobar que existe un
espacioreservadoenlamismacadenaantesdeprocederaeliminarla.Graciasalpunterothis
estasoperacionessehanpodidorealizarsinproblema.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 101

Es muy habitual que el operador = retorne una referencia al propio objeto para
permitir realizar asignaciones concatenadas sin necesidad de crear un objeto temporal.
Gracias a esta referencia ser posible escribir sentencias del estilo: C1=C2=C3 tal y como
sucedeconlasasignacionesenlostiposbsicos.
Ademsdeloperador+puedensobrecargarseprcticamentetodoslosoperadores:
+, -, *, /, %, ^, &, |, (,), <, >, <=, >=, <<, >>, ==,
!=, &&, ||, =, +=. -=, *=, /=, %=, ^=, &=, |=, <<=,>>=, [ ],
(),->, new y delete.

Los operadores =, [], () y -> slo pueden sobrecargarse en el interior de


clases.
Porejemplo,eloperador>paralaclaseTiempopodradeclararseydefinirseas:
class Tiempo
{
...
bool operator>(Tiempo h);
...
};
bool Tiempo::operator>(Tiempo h)
{
return (hora > h.hora ||
(hora == h.hora && minuto > h.minuto));
}
void main(void)
{
...
if(Tiempo(1,32) > Tiempo(1,12))
cout << "1:32 es mayor que 1:12" << endl;
else cout << "1:32 es menor o igual que 1:12" << endl;
...
}

Lgicamente,losoperadoresdecomparacinsuelenretornarunvalorbool,yaque
estamoscomprobandosialgoesciertoofalso.

OtroejemploparalaclaseTiemposeraeldeloperador+=,quealigualqueconlos
tiposbsicosrealizarlasumasobreelprimeroperandodelsegundo.
class Tiempo
{
...
void operator+=(Tiempo h);
...
102 PROGRAMACIN C++ Y COMUNICACIONES.

};
void Tiempo::operator+=(Tiempo h)
{
minuto += h.minuto;
hora += h.hora;
while(minuto >= 60)
{
minuto -= 60;
hora++;
}
}
void main(void)
{
...
Ahora += Tiempo(1,32);
Ahora.Mostrar();
...
}
Noesimprescindiblemantenerelsignificadodelosoperadores.Porejemplo,parala
claseTiemponotienesentidosobrecargareloperadores>>,<<,*/,perosepuededetodos
modos,yolvidarelsignificadoquetenganhabitualmente.

Deigualmodosepodrahabersobrecargadoeloperador+yhacerquenosumara
lostiempossinoque,porejemplo,losrestara.Enltimainstancia,eselprogramadorelque
decideelsignificadodelosoperadores.

Sinembargo,comonormageneral,esconvenientedecaraaobteneruncdigoms
legiblequelafuncionalidaddeloperadorseaanlogaasusignificado.

Sobrecargadeloperador>>y<<.

Porsuaplicacinmshabitualseconsiderarbrevementeelcasodelosoperadores
binariosdedesplazamientoodeinsercinyextraccinenunflujodedatos.Enprimerlugar
hayqueaclararquenosetratadeunoperadornuevo,sinoqueeselquesehaescogidopara
insertarinformacinenlosiostream.Portantosepuedeutilizarparacualquierotraoperacin
queconsideremosoportuna.Sinembargolomshabitualesrespetaresteusorealizadopor
lalibreraestndar,yademsenmuchoscasosadherirnosaestemododetransmitirorecibir
lainformacindeunobjeto.

Cuando insertamos un objeto en un flujo de datos normalmente lo hacemos de la


formasiguiente:
cout<<miObjeto;
Lo cual implica que a la izquierda del operador esta cout y a las derecha nuestro
objeto.Portantosisobrecargamoseloperadordentrodeunaclase,obligatoriamentedebera
ser dentro de la clase del tipo de cout. Lgicamente esta clase no la podemos modificar

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 103

puesto que pertenece a la STL. Por ello, la sobrecarga del operador de insercin se realiza
comounafuncinexterna,yadems,comohabitualmentesernecesarioaccederalaparte
provadadelobjetoparapoderimprimirlo,sedeclaracomofuncinamigadelaclase.
El aspecto que tiene la sobrecarga tanto del operador >> como <<, siguiendo la
formamscomnderealizarseeselsiguiente:
ostream & operator<< (ostream &os, const MI_CLASE &obj)
istream & operator>> (istream &is, MI_CLASE &obj)
Los flujos de salida, gracias a la herencia, podremos agruparlos de forma genrica
dentro del concepto ostream. Por tanto cout, es un objeto de tipo ostream. Los flujos de
entradaserndeltipoistream.Parapoderconcatenarinsercionesyextracciones,elresultado
de la operacin es el mismo flujo sobre el que se ha extraido o insertado. Pongamos como
ejemploestosoperadoresparalaclaseTiempo:
class Tiempo
{
...
friend ostream & operator<< (ostream &os, const Tiempo &t)
friend istream & operator>> (istream &is, Tirmpo &t)
...
};
ostream & operator<< (ostream &os, const Tiempo &t)
{
os<<t.hora<<:<<t.minuto;
return os;
}
istream & operator>> (istream &is, Tiempo &t)
{
string a;
is>>a;
int index=a.find_first_of(:);
if(index!=string::nppos){
t.hora=stoi(a.substring(0,index);
t.minuto=stoi(a.substring(index+1));
}
return is;
}

void main()
{
Tiempo t1;
cin>>t1;
cout<<Tiempo ledo = <<t1<<endl;
}
104 PROGRAMACIN C++ Y COMUNICACIONES.

Sobrecarga de operadores unarios


Como su propio nombre indica, los operadores unarios son aquellos que requieren
de un solo operando para calcular su valor. Tal es el caso del operador incremento o el
operadornegacin.
Cuandosesobrecarganoperadoresunitariosenunaclaseeloperandoeselpropio
objetodelaclasedondesedefineeloperador.Porlotantolosoperadoresunitariosdentro
delasclasesenunprincipionorequierendeoperandos.Deahquelasintaxissesimplifique
respectodelosoperadoresbinariosyquedecomosigue:

<tipo> operator<operador unitario>();

Normalmenteel<tipo>eslaclaseparalaqueestamossobrecargandoeloperador,
pero al igual que ocurra con los operadores binarios, esto es algo que queda a la libre
eleccindelprogramador.

ComoejemploserealizareloperadordeincrementoparalaclaseTiempoqueseha
venidodefiniendohastaahora.
class Tiempo
{
...
Tiempo operator++();
...
};
Tiempo Tiempo::operator++(){
minuto++;
while(minuto >= 60)
{
minuto -= 60;
hora++;
}
return *this;
}
void main(void){
...
T1.Mostrar();
++T1;
T1.Mostrar();
...
}

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 105


Sinembargo,existendosversionesparaeloperadorincremento,elpreincrementoy
elpostincremento.Elejemplomostradoeslasobrecargadeloperadorpreincrementopara
laclaseTiempo,cmosesobrecargaeloperadordepostincremento?
En realidad no hay forma de decirle al compilador cul de las dos modalidades del
operador se est sobrecargando, as que los compiladores usan una regla: si se declara un
parmetroparaunoperador++sesobrecargarlaformasufijadeloperador.
Elparmetroseignorar,asquebastarconindicareltipo.

Tambintenemosquetenerencuentaelpeculiarfuncionamientodelosoperadores
sufijos, cuando se sobrecarguen, al menos si se quiere mantener el comportamiento que
tienennormalmente.

Cuandoseusaunoperadorenlaformasufijodentrodeunaexpresin,primerose
usa el valor actual del objeto, y una vez evaluada la expresin, se aplica el operador. Si se
quierequeeloperadoracteigualsedebeusarunobjetotemporal,yasignarleelvaloractual
del objeto. Seguidamente se aplica el operador al objeto actual y finalmente se retorna el
objetotemporal.
class Tiempo
{
...
Tiempo operator++(); // Forma prefija
Tiempo operator++(int); // Forma sufija
...
};
Tiempo Tiempo::operator++()
{
minuto++;
while(minuto >= 60)
{
minuto -= 60;
hora++;
}
return *this;
}
Tiempo Tiempo::operator++(int)
{
Tiempo temp(*this); // Constructor copia
minuto++;
while(minuto >= 60)
{
minuto -= 60;
106 PROGRAMACIN C++ Y COMUNICACIONES.

hora++;
}
return temp;
}
void main(void)
{

T1.Mostrar();
(T1++).Mostrar();
T1.Mostrar();
(++T1).Mostrar();
T1.Mostrar();

}
Elresultadodeejecutarestapartedelprogramaser

17:9 (Valorinicial)

17:9 (Operadorsufijo,elvalornocambiahastadespusdemostrarelvalor)

17:10(Resultadodeaplicareloperador)

17:11(Operadorprefijo,elvalorcambiaantesdemostrarelvalor)

17:11 (Resultadodeaplicareloperador)

Adems del operador ++ y pueden sobrecargarse prcticamente todos los


operadoresunitarios:

+, -, ++, --, *,&y!.


Uncasoparticulardelosoperadoresunarioseseldelasconversionesdetipo.Para
ilustrar su utilidad y cuando aparecen se continuar con el ejemplo de la clase Tiempo.
Supongasequesequiererealizarunaoperacincomolasiguiente:

Tiempo T1(12,23);
unsigned int minutos = 432;
T1 += minutos;

Elvalordeseado,queserasumarlosminutosindicadosaltiempoalmacenadoenT1,
no se calcular correctamente. Lo que ocurre cuando se ejecuta la tima sentencia es lo
siguiente.EnC++serealizanconversionesimplcitasentrelostiposbsicosantesdeoperar
con ellos. Por ejemplo, para sumar un int y un float se promociona (convierte) el entero a

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 107

floatydespusserealizalaoperacinentredosnmerosdelmismotipo,siendoentoncesel
resultadodelamismaunfloat.
Estoesloqueocurrirconlaexpresindelejemplo.Elvalordeminutosseintentar
convertiraunobjetoTiempo,puestoqueeloperador+=definidoesperaunobjetodeeste
tipo como operando. Para ello se utilizar el constructor diseado. Como slo hay un
parmetro,yambos tienendefinidos valores por defecto, entonces elparmetro h toma el
valor de minutos, y el valor de m toma el de por defecto (o sea 0). El tipo de h es de tipo
entero,porloqueseconvierteelvalorunsignedintaintyseejecutaelconstructor.
Elresultadoesquesesuman432horas,ycuandoloquesedeseabaerasumar432
minutos. Esto se soluciona creando un nuevo constructor que tome como parmetro un
unsigned int, de forma que el compilador diferencia la operacin que tiene que realizar
graciasaltipodelargumento:
Tiempo(unsigned int m) : hora(0), minuto(m)
{
while(minuto >= 60)
{
minuto -= 60;
hora++;
}
}

En general se podrn realizar conversiones de tipo desde cualquier objeto a un


objetodelaclasequeseestdefiniendomediantelasobrecargadelconstructor.

Dado que esto puede provocar muchas ambigedades en C++ se incluye el


modificador de constructores explicit. De tal forma que un constructor declarado como
explicit nunca se ejecutar de forma implcita, en estas o en otro tipo de conversiones
decididas por el compilador. Ser necesario especificar que queremos realizar esta
conversin. En C++11 este modificador se permitir usar tambin como modificador de las
conversionesdetipoqueveremosacontinuacin.

La palabra clave explicit sirve para evitar que el compilador realice conversiones
implcitasmedianteunconstructorespecfico.

Sinembargo,esinteresantevercomosetrabajaenelcasoinverso.Esdecir,ahoralo
que se deseaes dotar a C++ de mecanismos para convertir una instancia de la clase a otro
tipo.Porejemplo,sedeseaahoraasignaraunenteroelvalorcontenidoenTiempo.Laideaes
quesedeseatransformarlashorasyminutoseneltotaldeminutosquerepresentan:

108 PROGRAMACIN C++ Y COMUNICACIONES.


Tiempo T1(12,23);
int minutos;
minutos = T1;


En este caso se obtendra un error de compilacin, ya que el compilador no sabe
convertirunobjetoTiempoaentero.Parapoderrealizarestaoperacinsedeberdisearun
operadordeconversindetipoqueilustrealcompiladordequeoperacionesdeberrealizar
paraobtenerelenteroequivalenteaunobjetoTiempo.
Losoperadoresdeconversindetipotienenelsiguienteformato:
operador <tipo>();
No necesitan que se especifique el tipo del valor de retorno, ya que este es
precisamente <tipo>. Adems, al ser operadores unitarios, tampoco requieren argumentos,
puestoqueseaplicanalpropioobjeto.
class Tiempo
{
...
operator int();
...
}
Tiempo::operator int()
{
return hora*60+minuto;
}
Por supuesto, el tipo no tiene por qu ser un tipo bsico, puede tratarse de una
estructuraounaclase.

Los operadores [ ] y ( )

El operador de indexacin
El operador [ ] se usa para acceder a valores de objetos de una determinada clase
como si se tratasen de arrays. Los ndices no tienen por qu ser de un tipo entero o
enumerado,ahoranoexisteesalimitacin.
Dondemstilresultaesteoperadorescuandoseusaconestructurasdinmicasde
datos:listas,rboles,vectoresdinmicos,etc.Perotambinpuedeservirparacreararrays
asociativos,dondelosndicesseanporejemplo,palabras.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 109

Denuevoseexplicarelusodeesteoperadorusandounejemplo.Lasiguienteclase
permite obtener el valor resultante de interpolar entre los valores de un vector de n
componentes,enfuncindeunindicequeenvezdeserenteroesreal:

#include <iostream.h>
#include <math.h>
class vector
{
public:
vector(int n=0,double *v=NULL);
double operator[](double ind);
~vector(){delete [] valores;}
private:
int num;
double *valores;
};
vector::vector(int n,double *v)
{
valores = new double[n];
num=n;
for(int i=0;i<n;i++)valores[i]=v[i];
}
double vector::operator [](double ind)
{
double temp;
int sup,inf;
inf=(int)floor(ind); //entero redondeado abajo
sup=(int)ceil(ind); //entero redondeado arriba
if(inf>num-1)inf=num-1;
if(sup>num-1)sup=num-1;
if(inf<0)inf=0;
if(sup<0)sup=0;
if(inf<sup)
temp=(sup-ind)*valores[inf]+(ind-inf)*valores[sup];
else temp=valores[inf];
return temp;
}

void main(void)
{
double val[4]={1.0,4.0,-1.0,2.0};
110 PROGRAMACIN C++ Y COMUNICACIONES.

vector mivector(4,val);
for(int i=0;i<31;i++)
cout<<mivector[i*0.1]<<endl;

}

Elprogramamostrarlosvaloresintermediosde0.1en0.1.Sehautilizadounvalor
doublecomondice,perodeigualformasepodrahaberutilizadounacadenadecaracteres
ounobjeto.
Cuando se combina el operador de indexacin con estructuras dinmicas de datos
comolaslistas,sepuedetrabajarconellascomosisetratadadearraysdeobjetos,estodar
unagranpotenciayclaridadalcdigodelosprogramas.

El operador llamada
El operador llamada ( ) funciona exactamente igual que el operador [], aunque
admite ms parmetros. Este operador permite usar un objeto de la clase para el que est
definidocomosifueraunafuncin.

Portantoelnmerodeparmetrosyelvalorderetornodependerntotalmentede
loquedecidaelprogramador.Paraelejemploanteriorsevaaampliareloperadorindexacin
definido,deformaquesiseutilizaeloperadorllamadasepudeescogersisedesearealizarla
interpolacinono:
class vector
{

double operator()(double ind,bool interpolar=true);

}
double vector::operator ()(double ind,bool interpolar)
{
if(interpolar)return (*this)[ind];
else return valores[(int)ind];
}
void main(void)
{
double val[4]={1.0,4.0,-1.0,2.0};
vector mivector(4,val);
for(int i=0;i<31;i++)
{
cout<<mivector[i*0.1]<< ;

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 111

cout<<mivector(i*0.1,false)<<endl;
}
}

3.6. Miembros static

Atributos static
En ocasiones se hace necesario de disponer de una variable comn a todos los
objetos de una clase. Por ejemplo, si se quisiera llevar cuenta de cuantos objetos se han
creadodeunaclasedeterminada,sedeberateneruncontadorquefueracomnatodoslos
objetos.EstafuncionalidadesproporcionadaenC++pormediodelosmiembrosestticosde
unaclase.
Para ilustrar esto se va a definir una clase libro sencilla, que permitir asignar un
identificadornicoacadalibrocreado.
#include <iostream.h>
#include <string.h>

class libro
{
public:
libro (const char *tit, const char *aut);
~libro();
void mostrar();
static int contador; //(1)
private:
char *titulo;
char *autor;
int ID;

};

int libro::contador=0; //(2)

libro::libro(const char *tit,const char *aut)


{
titulo=new char[strlen(tit)+1];
autor=new char[strlen(aut)+1];
strcpy(titulo,tit);
strcpy(autor,aut);
ID=++contador; //(3)
112 PROGRAMACIN C++ Y COMUNICACIONES.

libro::~libro()
{
delete [] titulo;
delete [] autor;
}

void libro::mostrar()
{
cout<<"Libro "<<ID<<": \t"<<titulo<<endl;
cout<<"\t\t"<<autor<<endl<<endl;
}

void main(void)
{
libro l1("Cucho","Olaizola");
libro l2("Tuareg","Vazquez Figueroa");
libro l3("El Quijote","Cervantes");
l1.mostrar();
l2.mostrar();
l3.mostrar();
}

Elresultadodeejecutarestecdigoeselsiguiente:
Libro 1: Cucho
Olaizola
Libro 2: Tuareg
Vazquez Figueroa
Libro 3: El Quijote
Cervantes
Unatributostaticnoesunatributoespecficodeunobjeto(comoeselcasodelos
atributosautor,titulooID)sinoquemsbienesunatributodelaclase;estoes,unatributo
delqueslohayunacopiaquecompartentodoslosobjetosdelaclase.Porestemotivo,un
atributostaticexisteypuedeserutilizadoaunquenoexistaningunobjetodelaclase.
Se observa como para declarar un atributo static basta con anteponer static a la
declaracindentrodelaclase.Dehechoelniveldeacceso(privado,pblicooprotegido)se
mantiene vlido para los atributo y mtodos de tipo esttico. En el ejemplo, la declaracin
puedeverseen(1).

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 113

Sinembargoesnecesarioinicializar(yportantocrear)lavariableestticaenalgn
momentoyademsslounavez.Esdecir,tienequeserinicializadoanivelglobalyhayque
asegurarse de que esta inicializacin no se realiza ms veces. Es por ello que es necesario
escribirlalnea(2),enlaquesedicequeelatributodelaclaselibrollamadocontadordetipo
enterovalecuandoescreado0.

Lainicializacindeunatributoestticosecolocageneralmenteenelficherofuente
.cppquecontienelasdefinicionesdelosmtodosdelaclase,puestoqueelcompiladorlee
este fichero una sola vez, mientras que el fichero de cabecera (.h) de definicin de la clase
puede ser incluido multitud de veces, lo que provocara multitud de inicializaciones con el
consiguienteerrordeinicializacin.
Porlodems,unatributoestticonosediferenciadelrestodeatributosyesposible
accederalmismodeigualformaqueocurreconlosatributosnormales(3).
Sin embargo, al ser un atributo que pertenece a la clase y no a un objeto en
particular, es una variable que existe desde el principio del programa No sera posible
accederasuvalorsinnecesidaddecrearunobjeto?.Larespuestaesques.
Porejemplo,elsiguientemainseraperfectamentevlido:
void imprimirLibros()
{
libro l1("Cucho","Olaizola");
libro l2("Tuareg","Vazquez Figueroa");
libro l3("El Quijote","Cervantes");
l1.mostrar();
l2.mostrar();
l3.mostrar();
}

void main(void)
{
cout<<"Numero inicial de libros:";
cout<<libro::contador<<endl;
imprimirLibros();
cout<<"Libros creados:";
cout<<libro::contador<<endl;
}


Obsrvese que una traduccin literal de lo escrito es totalmente coherente con lo
explicado.Laexpresinlibro::contadorsignificaelatributocontadorpertenecientealaclase
libro. Ntese que en el cuerpo del main no existe ninguna variable de tipo libro con la que
114 PROGRAMACIN C++ Y COMUNICACIONES.

acceder al atributo, pero como esta es global y existe para todos los objetos, es posible
obtenerydarleunvalordesdecualquiersitio.
Evidentemente,hasidoposibleaccederalvalordelatributocontadorporseresteun
atributopblico.Sinembargoparecelgicoquedichoatributofueraunatributoprivado.Si
reescribiramos la clase libro con el atributo contador como miembro privado esttico,
entonceselcompiladornopermitiralaconsultadelmismofueradeunobjetodelaclase.
Siempre nos queda la opcin de crear un mtodo de interfaz que a travs de un
objetodelaclasenosremitieraelvalordelcontador.SinembargoC++nosdalaposibilidad
deconsultarestetipodeatributosydemodificarsuvaloraunsiendoprivadospormediode
losmtodosestticoscomoseveracontinuacin.

Metodos static
Unmtododeclaradocomostaticcarecedelpunterothisporloquenopuedeser
invocado para un objeto de su clase, sino que se invoca en general all donde se necesite
utilizarparalaoperacinparalaquehasidoescrito.Desdeestepuntodevistaesimposible
queunmtodostaticpuedaaccederaunmiembronostaticdesuclase;porlamismarazon,
si puede acceder a un miembro static. Luego si un objeto llama a un mtodo static de su
clase,hayquetenerencuentaquenopodraccederaningunodesusatributosparticulares,
apesardequesumododeusonodifieredecualquierotromtododelaclase.
Si reescribimos la clase libro con las modificaciones indicadas al final del anterior
epgrafe,seranecesariounmtodostaticparapoderconsultarelvalordelatributocontador
queahoraesprivado.Aligualqueocurraconlosatributos,unmtodosedeclaraestticoen
ladeclaracindelaclase,peronoesnecesario(dehechonohayquehacerlo)enelmomento
enelquesedefineelmtodo.

Elsiguienteejemploilustraestosaspectosascomoelmododellamaraunmtodo
static sin necesidad de crear un objeto de la clase. Antes de transcribir el mismo hay que
destacar que la utilidad de los miembros static de una clase, no es fcil descubrirla en la
primeraimpresin,peroamedidaquesevaaprendiendoaprogramarenC++secomprueba
la gran utilidad y la facilidad con que se resuelven muchos problemas gracias a esta
herramienta.
#include <iostream.h>
#include <string.h>

class libro
{
public:
libro (const char *tit, const char *aut);
~libro();

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 115

void mostrar();
static int getContador(){return contador;};
private:
char *titulo;
char *autor;
int ID;
static int contador;
};

int libro::contador=0;

libro::libro(const char *tit,const char *aut)


{
titulo=new char[strlen(tit)+1];
autor=new char[strlen(aut)+1];
strcpy(titulo,tit);
strcpy(autor,aut);
ID=++contador;
}

libro::~libro()
{
delete [] titulo;
delete [] autor;
}

void libro::mostrar()
{

cout<<"Libro "<<ID<<": \t"<<titulo<<endl;


cout<<"\t\t"<<autor<<endl<<endl;
}
void imprimirLibros()
{
libro l1("Cucho","Olaizola");
libro l2("Tuareg","Vazquez Figueroa");
libro l3("El Quijote","Cervantes");
l1.mostrar();
l2.mostrar();
l3.mostrar();
}
void main(void)
{
cout<<"Numero inicial de libros:";
cout<<libro::getContador()<<endl;
116 PROGRAMACIN C++ Y COMUNICACIONES.

imprimirLibros();
cout<<"Libros creados:";
cout<<libro::getContador()<<endl;
}

3.7. Ejercicios
Elsiguientecdigoextradodelaredrealizaunaclaseparaoperarcmodamentecon
nmeroscomplejos.Algunasdelassolucionesadoptadastienenfinalidadpuramentedocente
paramostrarcasitodoslosaspectosdeestecaptulo:
/******************** fichero Complejo.h**************************/

// fichero Complejo.h
// declaracin de la clase Complejo
#ifndef __COMPLEJO_H__
#define __COMPLEJO_H__
#include <iostream.h>
class Complejo
{
private:
double real;
double imag;
public:
// Constructores
Complejo(void);
explicit Complejo(double, double im=0.0);
Complejo(const Complejo&);
// Set Cosas
void SetData(void);
void SetReal(double);
void SetImag(double);
// Get Cosas
double GetReal(void){return real;}
double GetImag(void){return imag;}
// Sobrecarga de operadores aritmticos
Complejo operator+ (const Complejo&);
Complejo operator- (const Complejo&);
Complejo operator* (const Complejo&);
Complejo operator/ (const Complejo&);
// Sobrecarga del operador de asignacin
Complejo& operator= (const Complejo&);
// Sobrecarga de operadores de comparacin
friend int operator== (const Complejo&, const Complejo&);
friend int operator!= (const Complejo&, const Complejo&);
// Sobrecarga del operador de insercin en el flujo de salida
friend ostream& operator<< (ostream&, const Complejo&);

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 117

};
#endif

/******************** fichero
Complejo.cpp**************************/

#include "Complejo.h"
// constructor por defecto
Complejo::Complejo(void)
{
real = 0.0;
imag = 0.0;
}
// constructor general
Complejo::Complejo(double re, double im)
{
real = re;
imag = im;
}
// constructor de copia
Complejo::Complejo(const Complejo& c)
{
real = c.real;
imag = c.imag;
}
// funcin miembro SetData()
void Complejo::SetData(void)
{
cout << "Introduzca el valor real del Complejo: ";
cin >> real;
cout << "Introduzca el valor imaginario del Complejo: ";
cin >> imag;
}
void Complejo::SetReal(double re)
{
real = re;
}
void Complejo::SetImag(double im)
{
imag = im;
}
// operador miembro + sobrecargado
Complejo Complejo::operator+ (const Complejo &a)
{
Complejo suma;
suma.real = real + a.real;
118 PROGRAMACIN C++ Y COMUNICACIONES.

suma.imag = imag + a.imag;


return suma;
}
// operador miembro - sobrecargado
Complejo Complejo::operator- (const Complejo &a)
{
Complejo resta;
resta.real = real - a.real;
resta.imag = imag - a.imag;
return resta;
}

// operador miembro * sobrecargado


Complejo Complejo::operator* (const Complejo &a)
{
Complejo producto;
producto.real = real*a.real - imag*a.imag;
producto.imag = real*a.imag + a.real*imag;
return producto;
}
// operador miembro / sobrecargado
Complejo Complejo::operator/ (const Complejo &a)
{
Complejo cociente;
double d = a.real*a.real + a.imag*a.imag;
cociente.real = (real*a.real + imag*a.imag)/d;
cociente.imag = (-real*a.imag + imag*a.real)/d;
return cociente;
}
// operador miembro de asignacin sobrecargado
Complejo& Complejo::operator= (const Complejo &a)
{
real = a.real;
imag = a.imag;
return (*this);
}
// operador friend de test de igualdad sobrecargado
int operator== (const Complejo& a, const Complejo& b)
{
if (a.real==b.real && a.imag==b.imag)return 1;
else return 0;
}
// operador friend de test de desigualdad sobrecargado
int operator!= (const Complejo& a, const Complejo& b)
{
if (a.real!=b.real || a.imag!=b.imag)return 1;
else return 0;

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 3. EL CONCEPTO DE CLASE 119

}
// operador friend << sobrecargado
ostream& operator << (ostream& co, const Complejo &a)
{
co << a.real;
long fl = co.setf(ios::showpos);
co << a.imag << "i";
co.flags(fl);
return co;
}

/**************fichero main.cpp**************************/
#include "Complejo.h"
void main(void)
{
// se crean dos Complejos con el constructor general
Complejo c1(1.0, 1.0);
Complejo c2(2.0, 2.0);
// se crea un Complejo con el constructor por defecto
Complejo c3;
// se da valor a la parte real e imaginaria de c3
c3.SetReal(5.0);
c3.SetImag(2.0);
// se crea un Complejo con el valor por defecto (0.0) del 2
argumento
Complejo c4(4.0);
// se crea un Complejo a partir del resultado de una expresin
// se utiliza el constructor de copia
Complejo suma = c1 + c2;
// se crean tres Complejos con el constructor por defecto
Complejo resta, producto, cociente;
// se asignan valores con los operadores sobrecargados
resta = c1 - c2;
producto = c1 * c2;
cociente = c1 / c2;
// se imprimen los nmeros Complejos con el operador << sobrecargado
cout << c1 << ", " << c2 << ", " << c3 << ", " << c4 << endl;
cout << "Primer Complejo: " << c1 << endl;
cout << "Segundo Complejo: " << c2 << endl;
cout << "Suma: " << suma << endl;
cout << "Resta: " << resta << endl;
cout << "Producto: " << producto << endl;
cout << "Cociente: " << cociente << endl;

// se comparan Complejos con los operadores == y != sobrecargados


120 PROGRAMACIN C++ Y COMUNICACIONES.

if (c1==c2)
cout << "Los Complejos son iguales." << endl;
else
cout << "Los Complejos no son iguales." << endl;
if (c1!=c2)
cout << "Los Complejos son diferentes." << endl;
else
cout << "Los Complejos no son diferentes." << endl;
cout << "Ya he terminado." << endl;
}

UPM-EUITI-2015. Miguel Hernando.


4. La Herencia

Lamentehumanaclasificalosconceptosdeacuerdoadosdimensiones:pertenencia
yvariedad.SepuededecirqueelFordFiestaesuntipodecoche(variedado,eningls,una
relacindeltipoisa)yqueunaruedaespartedeuncoche(pertenenciaounarelacindel
tipo has a). Antes de la llegada de la herencia, en C ya se haba resuelto el problema de la
pertenenciamediantelasestructuras,quepodansertodolocomplejasquesequisiera.Con
la herencia, como se va a ver en este captulo, se consigue clasificar los tipos de datos
(abstracciones)porvariedad,acercandoasunpasomslaprogramacinalmododerazonar
humano.
Comocasisiempre,C++havenidohaintentarsolucionar,loquelosprogramadores
porsucuentayasehabanprocuradomediantecomplejasestructurassobreC.As,mediante
unaprogramacincompleja,enlaqueentraaformarparteimportanteelpreprocesador,se
conseguan los conceptosde herenciatanto simple como mltiple, as como otros aspectos
de C++. Todos estos mecanismos, a veces ciertamente con apariencia de enrevesados, han

Departamento de Electrnica Automtica e Informtica Industrial


122 PROGRAMACIN C++ Y COMUNICACIONES.

sidodesarrolladosrespondiendoanecesidadesdelaprogramacindealtonivel,porloque
enmuchoscasosintentaremoshacerhincapienlaaplicacindeloqueseexplica.
Como ya se ha mencionado, el mecanismo de la herencia es fuertemente
caractersticodelaprogramacinorientadaaobjetos.Porello,antesdecomenzaraahondar
enelconcepto,esimportantedestacarquenodejadeserunaherramientaquenospermitir
resolverconcomodidadyeleganciaciertosproblemas,peroqueensnoesunfindesdeel
punto de vista de la programacin. Uno de los mayores defectos que se dan a la hora de
realizarunprogramamediantePOO,esprecisamenteelabusodelmecanismodeherencia,y
la poca planificacin a la hora de definir nuestra estructura. Es bastante comn encontrar
desarrollosestancados,pocoeficientesopocousados,enC++debidoalacomplejidadypoca
planificacindelaestructuradelosobjetos.Porestemotivo,anahora,trasbastantesaos
condesarrollossobreC++,siguensaliendoyactualizndosedistintaslibrerascuyainterfacey
desarrollo siguen siendo en C, frente a otras anlogas y de mucho menor xito realizadas
sobreC++.
Por ello, hay que destacar lo siguiente: la herencia es un mecanismo de gran
potencia, pero que necesita de una fase de anlisis en profundidad previa a su
implementacin.Siesteanlisisnoserealizaadecuadamente,nosloperderemoseficiencia,
sinoqueelcdigoterminarcorrompidoyseranmsininteligiblequesobreC.

4.1. Definicin de herencia


La herencia, entendida como una caracterstica de la programacin orientada a
objetosymsconcretamentedelC++,permitedefinirunaclasemodificandounaomsclases
ya existentes. Estas modificaciones consisten habitualmente en aadir nuevos miembros
(variablesofunciones),alaclasequeseestdefiniendo,aunquetambinsepuederedefinir
variablesofuncionesmiembroyaexistentes.
Laclasedelaqueseparteenesteprocesorecibeelnombredeclasebase,ylanueva
clase que se obtiene se denomina clase derivada. sta a su vez puede ser clase base en un
nuevoprocesodederivacin,iniciandodeestamaneraunajerarquadeclases.Deordinario
las clases base suelen ser ms generales que las clases derivadas. Esto es as porque a las
clasesderivadasselessueleniraadiendocaractersticas,endefinitivavariablesyfunciones
quediferencianconcretanyparticularizan.

VeamosunejemplodeunaherenciasimplerealizadasobrecdigoC:

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 4. LA HERENCIA. 123

#define PERSONA char nombre[40]; \


int edad;

typedef struct _persona


{
PERSONA
}persona;

typedef struct _alumno


{
PERSONA
int martricula;
int curso;
}alumno;

typedef struct _profesor


{
PERSONA
int departamento;
int codigo;
int despacho;
}profesor;

Seobservaenelejemplocmopodramosconsiderarapersonaclasebaseparalas
otras dos profesor y alumno. Mediante esta estructuracin, en determinadas funciones de
nuestro programa, podremos entender alumno o profesor como tales, o considerarlos slo
comopersonas(loquesignificara,accederalosprimeroscamposdelaestructura,loscuales
soncomunesaambostipos).
Enalgunoscasosunaclasenotieneotrautilidadqueladeserclasebaseparaotras
clases que se deriven de ella. A este tipo de clases base, de las que no se declara ningn
objeto,selesdenominaclasesbaseabstractas(ABC,AbstractBaseClass)ysufuncineslade
agruparmiembroscomunesdeotrasclasesquesederivarndeellas.Porejemplo,sepuede
definir la clase vehiculo para despus derivar de ella coche, bicicleta, patinete, etc., pero
todos los objetos que se declaren pertenecern a alguna de estas ltimas clases; no habr
vehculosqueseanslovehculos.
Las caractersticas comunes de estas clases (como una variable que indique si est
aradooenmarcha,otraqueindiquesuvelocidad,lafuncindearrancaryladefrenar,etc.),
pertenecernalaclasebaseylasqueseanparticularesdealgunadeellaspertenecernsloa
laclasederivada(porejemploelnmerodeplatosypiones,queslotienesentidoparauna
124 PROGRAMACIN C++ Y COMUNICACIONES.

bicicleta, o la funcin embragar que slo se aplicar a los vehculos de motor con varias
marchas).
Estemecanismodeherenciapresentamltiplesventajasevidentesaprimeravista,
como la posibilidad de reutilizar cdigo sin tener que escribirlo de nuevo. Esto es posible
porque todas las clases derivadas pueden utilizar el cdigo de la clase base sin tener que
volveradefinirloencadaunadeellas.

El nivel de acceso protected.


Unodelosproblemasqueaparececonlaherenciaeseldelcontroldelaccesoalos
datos. Puede una funcin de una clase derivada acceder a los datos privados de su clase
base?Enprincipiounaclasenopuedeaccederalosdatosprivadosdeotra,peropodraser
muyconvenientequeunaclasederivadaaccedieraatodoslosdatosdesuclasebase.Para
hacerposibleesto,existeeltipodedatoprotected.Estetipodedatosesprivadoparatodas
aquellasclasesquenosonderivadas,peropblicoparaunaclasederivadadelaclaseenla
quesehadefinidolavariablecomoprotected.
Por otra parte, el proceso de herencia puede efectuarse de dos formas distintas:
siendolaclasebasepublicoprivateparalaclasederivada.Enelcasodequelaclasebasesea
public para la clase derivada, sta hereda los miembros public y protected de la clase base
como miembros public y protected, respectivamente. Por el contrario, si la clase base es
privateparalaclasederivada,staheredatodoslosdatosdelaclasebasecomoprivate.La
siguientetablapuederesumirloexplicadoenlosdosltimosprrafos.

Tipo de dato de la Clase derivada de Clase derivada de Clase sin relacin de


clasebase unaclasebasepublic una clase base herencia.
private

Private Noaccesible Noaccesible Noaccesible

Protected Protected Private Noaccesible

Public Public Private Accesible(.,>)

Tabla1:Herenciapblicayprivada.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 4. LA HERENCIA. 125

Como ejemplo, se puede pensar en dos tipos de cuentas bancarias que comparten
algunas caractersticas y que tambin tienen algunas diferencias. Ambas cuentas tienen un
saldo,unintersyelnombredeltitulardelacuenta.Lacuentajovenesuntipodecuenta
querequierelaedaddelpropietario,mientrasquelacuentaempresarialnecesitaelnombre
delaempresa.ElproblemapodraresolverseestableciendounaclasebasellamadaC_Cuenta
ycreandodostiposdecuentaderivadosdedichaclasebase.

Paraindicarqueunaclasederivadeotraesnecesarioindicarloenladeclaracinde
la clase derivada, especificando el modo public o private en que deriva de su clase
base:

class <Clase_Derivada> : [public|private] <Clase_Base>

En caso de no especificarse el modo con que se realiza la derivacin, entonces se


sobreentenderquelaherenciaserealizaprivadamente.
Deestaformaelcdigonecesarioparacrearesastresclasesmencionadasquedara
delasiguienteforma:

Ntese que algunas de las lneas han tenido que partirse en concreto los
constructores de las clases debido a su longitud. Esto es vlido y conveniente en C++,
intentandosiempremanteneralmximolaclaridaddelasdefiniciones.

#include <iostream.h>
class C_Cuenta
{
// Variables miembro
private:
char *Nombre; // Nombre de la persona
double Saldo; // Saldo Actual de la cuenta
double Interes; // Inters aplicado
public:
// Constructor
C_Cuenta(char *nombre, double saldo=0.0, double interes=0.0)
{
Nombre = new char[strlen(nombre)+1];
strcpy(Nombre, nombre);
SetSaldo(saldo);
SetInteres(interes);
126 PROGRAMACIN C++ Y COMUNICACIONES.

}
// Destructor
~Cuenta(){delete [] Nombre;}
// Mtodos
char *GetNombre(){ return Nombre; }
double GetSaldo(){ return Saldo; }
double GetInteres(){ return Interes; }
void SetSaldo(double saldo){ Saldo = saldo; }
void SetInteres(double interes){ Interes = interes; }
void Ingreso(double cantidad){SetSaldo(GetSaldo()+cantidad);}
friend ostream& operator<<(ostream& os, C_Cuenta& cuenta){
os << "Nombre=" << cuenta.GetNombre() << endl;
os << "Saldo=" << cuenta.GetSaldo() << endl;
return os;
}
};
//CuentaJoven deriva pblicamente de la clase Cuenta
class C_CuentaJoven : public C_Cuenta
{
private:
int Edad;
public:
C_CuentaJoven(char *nombre,int edad, double saldo=0.0,
double interes=0.0):C_Cuenta(nombre, saldo, interes) {
Edad = laEdad; //especifico de Cuenta Joven
}
};
class C_CuentaEmpresarial : public C_Cuenta
{
private:
char *NomEmpresa;
public:
C_CuentaEmpresarial(char *nombre, char *empresa,
double saldo=0.0, double interes=0.0)
:C_Cuenta(nombre, saldo, interes){
//especfico de Cuenta empresarial
NomEmpresa = new char[strlen(empresa)+1];
strcpy(NomEmpresa, empresa);
}
~C_CuentaEmpresarial(){delete [] NomEmpresa;}
};

void main()
{
C_CuentaJoven c1("Luis", 18, 10000.0, 1.0);
C_CuentaEmpresarial c2("Sara", "ELAI Ltd." ,100000.0);

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 4. LA HERENCIA. 127

cout << c1;


cout << c2;
}

Mtodos y atributos ocultos de la clase base


Si un miembro heredado se redefine en la clase derivada, el nombre redefinido
ocultaelnombreheredadoqueyaquedainvisibleparalosobjetosdelaclasederivada.De
estaforma,sienelejemplosedefinieraunnuevoatributodenominadointersenalgunade
las dos clases derivadas, entonces se creara una nueva variable que al tener el mismo
nombreimpediraalprogramadorverlaheredadadelaclasebase.
Unejemplocompletodeesteaspecto,ydecmosepuedeaccederaunatributooa
un mtodo de una clase base oculto por un atributo o mtodo de la clase derivada es el
siguiente:
class numero
{
public:
numero(int val){valor=val;}
void imprimir(){cout<<valor;}
protected:
int valor;
};
class decimal:public numero
{
public:
decimal(int val, int dec):numero(val){valor=dec;}
void imprimir()
{
numero::imprimir();
cout<<','<<valor;
}
void mostrar()
{
cout<<numero::valor<<','<<valor;
}
private:
int valor;
};

void main(void)
{
decimal num(1,2);
128 PROGRAMACIN C++ Y COMUNICACIONES.

num.imprimir();

cout<<endl;
num.mostrar();
cout<<endl;
num.numero::imprimir();
}

Elresultadodeejecutaresteprogramaeselsiguiente:
1,2
1,2
1

Aunqueelejemplocarecedeutilidad,esciertamenteilustrativodecmosemaneja
eloperadorscope(::)cuandotenemosclasesderivadas.Seanimaallectoraanalizaraquien
hacen referencia los identificadores valor, e imprimir en cada caso. Ntese que para poder
escribirlafuncinmostrardelaclasedecimal,hasidonecesariodefinirvalorcomoprotected
enlaclasebase,yquelaherenciaespblica.Deestaforma,elvalornoesaccesibledesdeel
exterior,perosparalaclasederivada.

AntesdecontinuarconladescripcindeaspectosespecficosdelaherenciaenC++,
esnecesarioindicarquenotodoloquepertenecealaclasebaseesheredado.Loselementos
quenoseheredanson:

Constructores.

Destructores.

Funcionesfriend.

Funcionesydatosestticosdelaclase.

Operadordeasignacin(=)sobrecargado.
Los contructores y destructores tienen un tratamiento especfico como se ver a
continuacin.Aunquenoseheredansiqueseusanenelmomentodecrearseunainstancia
deunobjetoderivado.

4.2. Construccin y destruccin de clases derivadas:


inicializador base.
Unobjetodelaclasederivadacontienetodoslosmiembrosdelaclasebaseytodos
esosmiembrosdebenserinicializados.Porestaraznelconstructordelaclasederivadadebe

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 4. LA HERENCIA. 129

llamar al constructorde laclase base. Aldefinir el constructorde laclase derivada se debe


especificar un inicializador base. Es decir, en el momento de construirse el objeto, es
necesario antes indicar como debe construirse la parte heredada, por lo que es necesario
indicardeentretodoslosconstructorescualdeellosyenconquevaloresseutilizar.
Comoyasehadicholasclasesderivadasnoheredanlosconstructoresdesusclases
base.Elinicializadorbaseeslaformadellamaralosconstructoresdelasclasesbaseypoder
asinicializarlasvariablesmiembroheredadas.

Esteinicializadorbaseseespecificaponiendo,acontinuacindelosargumentosde
unconstructordelaclasederivada,elcarcterdospuntos(:)yelnombredelconstructorde
la clase o las clases base, seguido de una lista de argumentos entre parntesis. Estos
argumentos pueden ser funcin de los argumentos utilizados en el constructor de la clase
derivada.
Porejemplo,elconstructordelaclasedecimaltenaelsiguienteaspecto:
decimal(int val, int dec):numero(val){valor=dec;}

Con lo que se indica que la parte del objeto correspondiente a nmero, debe ser
inicializadoconelprimervalorpasadocomoargumentoenelconstructordelaclasedecimal.

Las listas de argumentos asociadas a las clases base pueden estar formadas por
constantes,variablesglobalesoporparmetrosquesepasanalafuncinconstructordela
clasederivada.

El inicializador base puede ser omitido en el caso de que la clase base tenga un
constructorpordefecto.Enelcasodequeelconstructordelaclasebaseexista,aldeclararun
objetodelaclasederivadaseejecutaprimeroelconstructordelaclasebase.

Otro ejemplo un poco ms complicado es el de la clase CuentaJoven del apartado


anterior. En este caso se utilizan adems valores por defecto en el constructor de la clase
derivada:
C_CuentaJoven(char *nombre, int edad, double saldo=0.0,
double interes=0.0):C_Cuenta(nombre, saldo, interes)
Tienesentidoquesellamealosconstructoresenelmismoordenenquetienenlugar
laderivacindeclases.Puestoquelaclasebasenotieneconocimientodelaclasederivada,
cualquier inicializacin que sta necesite realizar es independiente, y posiblemente sea un
prerrequisitoparacualquierinicializacinrealizadaporlaclasederivada,porloquesedebe
ejecutarprimero.

Deformaanlogaseoperarconeldestructor:eliminandoprimerolomsparticular
y despus lo general. Una funcin destructor de una clase derivada se ejecuta antes del
130 PROGRAMACIN C++ Y COMUNICACIONES.

destructor de la base. Como la destruccin de un objeto de una clase base implica la


destruccindelobjetodelaclasederivada,eldestructordelobjetoderivadosedebeejecutar
antesdequesedestruyaelobjetobase.
Poresounareglaimportanteenlacontruccinydestruccindeobjetosderivadoses
lasiguiente:

Losconstructoressellamanenelordendederivacindelasclases.

Losdestructoressellamanenordeninverso.

Elsiguienteejemplointentailustrarestemododeproceder.
#include <iostream.h>

class Base
{
public:
Base() {cout << \nBase creada\n;}
~Base() {cout << Base destruida\n\n;}
}

class D_clase1 : public Base


{
public:
D_clase1() {cout << D_clase1 creada\n;}
~D_clase1() {cout << D_clase1 destruida\n;}
};

class D_clase2 : public D_clase1


{
public:
D_clase2() {cout << D_clase2 creada\n;}
~D_clase2() {cout << D_clase2 destruida\n;}
};

void main()
{
D_clase1 d1;
D_clase2 d2;

cout << \n;


}

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 4. LA HERENCIA. 131

Esteprogramagenerarlasiguientesalida:

Base creada
D_clase1 creada

Base creada
D_clase1 creada
D_clase2 creada

D_clase2 destruida
D_clase1 destruida
Base destruida

D_clase1 destruida
Base destruida

4.3. Herencia mltiple


Unaclasepuedeheredarvariablesyfuncionesmiembrodeunaomsclasesbaseal
mismo tiempo. En el caso de que herede los miembros de una nica clase se habla de
herencia simple y en el caso de que herede miembros de varias clases base se trata de un
casodeherenciamltiple.Estoseilustraenlasiguientefigura:

Clase 1 Clase 1 Clase 2

Clase 2 Clase 3 Clase 3 Clase 4

Clase 4 Clase 5 Clase 5

Herencia Simple: Todas las clases Herencia Mltiple: Las clases derivadas
derivadas tienen una nica clase base. tienen varias clases base.

132 PROGRAMACIN C++ Y COMUNICACIONES.

Comoejemplosepuedepresentarelcasodequesetengaunaclaseparaelmanejo
delosdatosdelaempresa.SepodradefinirlaclaseC_CuentaEmpresarialcomolaherencia
mltiple de dos clases base: la ya bien conocida clase C_Cuenta y nueva clase llamada
C_Empresa,quesemuestraacontinuacin:

class C_Empresa
{
private:
char *NomEmpresa;
public:
C_Empresa(const char*laEmpresa)
{
NomEmpresa = new char[strlen(laEmpresa)+1];
strcpy(NomEmpresa, laEmpresa);
}
~C_Empresa(){ delete [] NomEmpresa; }
// Otros mtodos ...
};

class C_CuentaEmpresarial : public C_Cuenta, public C_Empresa


{
public:
C_CuentaEmpresarial(char *nombre,char *empresa,
double saldo=0.0,double interes=0.0)
:C_Cuenta(nombre, saldo, interes), C_Empresa(empresa)
{
// Constructor especfico
}
// Otros mtodos
};

Lasintaxisgeneralparaheredarunaclasedevariasclasesbasees:

class<c_derivada>:[public|private]<c_base_1>,[public|private]<base_2>,...
{
...
}
Lasclasesbaseseconstruyenenelordenenelqueaparecenenladeclaracindela
clasederivadadeizquierdaaderecha.Engeneral,cuandoseutilizaunalistadeclasesbase,
losconstructoressedebenllamarenordendeizquierdaaderecha.Losdestructoressedeben
llamarenordendederechaaizquierda.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 4. LA HERENCIA. 133

Los inicializadotes base siguen esta misma sintaxis. Cuando es necesario utilizarlos,
se colocan tras la clase base separadospor comas. Tales el caso delejemplo de lacuenta
empresarialexpuestoanteriormente.
Hayquedestacarqueenposterioreslenguajesdesarrolladossiguiendolafilosofade
POO, la herencia mltiple se ha desechado por ser una posible fuente de errores. La razn
principalresideencmofinalmentevanaquedarordenadaslasestructurasdelosobjetosen
memoria.Sinembargo,aunquenoexisteestaherenciamltiple,podemosgenerarunaserie
declasesabstractasintermediasqueobtenganelmismoresultado,puestoqueelefectofinal
eselmismonoesmsqueunaagregacindedatosymtodos.
Laherenciamltiplepuedeademsproduciralgunosproblemas.Enocasionespuede
suceder que en las dos clases base existaunafuncin con el mismo nombre. Esto crea una
ambigedadcuandoseinvocaaunadeesasfunciones.
Veamosunejemplo:
#include <iostream.h>
class ClaseA {
public:
ClaseA() : valorA(10) {}
int LeerValor(){ return valorA; }
protected:
int valorA;
};
class ClaseB {
public:
ClaseB() : valorB(20) {}
int LeerValor(){ return valorB; }
protected:
int valorB;
};
class ClaseC : public ClaseA, public ClaseB {};

void main() {
ClaseC CC;
cout << CC.LeerValor() << endl;// error de compilacin
cout << CC.ClaseA::LeerValor() << endl;
cin.get();
}

Unasolucinpararesolverlaambigedadeslaquehemosadoptadoenelejemplo.
Pero existe otra, tambin podramos haber redefinido la funcin "LeerValor" en la clase
derivadademodoquesesuperpusiesealasfuncionesdelasclasesbase.
134 PROGRAMACIN C++ Y COMUNICACIONES.

#include <iostream.h>
class ClaseA
{
public:
ClaseA() : valorA(10) {}
int LeerValor(){ return valorA; }
protected:
int valorA;
};
class ClaseB
{
public:
ClaseB() : valorB(20) {}
int LeerValor(){ return valorB; }
protected:
int valorB;
};
class ClaseC : public ClaseA, public ClaseB
{
public:
int LeerValor(){return ClaseA::LeerValor();}
};
void main()
{
ClaseC CC;
cout << CC.LeerValor() << endl;
cin.get();
}

4.4. Clases base virtuales


Supongamosquetenemosunaestructuradeclasescomosta:

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 4. LA HERENCIA. 135

Clase A Clase A

Clase B Clase C

Clase D

LaClaseDheredardosveceslosdatosyfuncionesdelaClaseA,conlaconsiguiente
ambigedadalahoradeaccederadatosofuncionesheredadasdeClaseA.Parasolucionar
estoseusanlasclasesvirtuales.Cuandoderivemosunaclasepartiendodeunaovariasclases
base,podemoshacerquelasclasesbaseseanvirtuales.Estonoafectaralaclasederivada.
Formadedeclaracindeunaclasebasevirtual:

classMadre_1:virtual publicAbuela

...

}
Porejemplo:
class ClaseB : virtual public ClaseA {};

Desde el punto de vista de la ClaseB, no hay ninguna diferencia entre sta


declaracin y la que hemos usado hasta ahora. La diferencia estar cuando declaramos la
ClaseD.Veamoselejemplocompleto:
class ClaseB : virtual public ClaseA {};
class ClaseC : virtual public ClaseA {};
class ClaseD : public ClaseB, public ClaseC {};

Ahora,laClaseDsloheredarunavezlaClaseA.Laestructuraquedaras:
136 PROGRAMACIN C++ Y COMUNICACIONES.

Clase A

Clase B Clase C

Clase D

4.5. Conversiones entre objetos de clases base y clases


derivadas
Esposiblerealizarconversionesoasignacionesdeunobjetodeunaclasederivadaa
unobjetodelaclasebase.Esdecirsepuedeirdelomsparticularalomsgeneral,aunque
enesaoperacinsepierdainformacin,pueshayavariablesquenotenganaquasignarse
(elnmerodevariablesmiembrodeunaclasederivadaesmayoroigualqueeldelaclasede
laquederiva).
Porelcontrariolasconversionesoasignacionesenelotrosentido,esdecirdeloms
general a lo ms particular, no son posibles, porque puede suceder que no se disponga de
valoresparatodaslasvariablesmiembrodelaclasederivada.
Aspues,enunprincipio,lasiguienteasignacinseracorrecta:
Objeto_clase_base = Objeto_clase_derivada
mientrasqueestaotraseraincorrecta:
Objeto_clase_derivada=Objeto_clase_base
Sin embargo, en C++, se permite realizar esta asignacin si somos capaces de
averiguarqueelobjetoqueaparececomolaclasebase,enverdadprovienedeunobjetode
laclasederivadaquesequiereasignar.Paraellodisponemosdeloperadordynamic_castel
cualcompruebasiesposiblerealizarlaasignacin.
Deigualmodo,enCunpunterodeuntiponopuedeapuntaraunobjetodeuntipo
diferente.Sinembargo,existeunaexcepcinimportanteaestareglaqueestrelacionada
solamenteconlasclasesderivadas.EnC++unpunteroaunaclasebasepuedeapuntaraun
objetodeunaclasederivadadeestabase.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 4. LA HERENCIA. 137

Por tanto se puede guardar la direccin almacenada en un puntero a una clase


derivadaenunpunteroalaclasebase.Estoquieredecirquesepuedehacerreferenciaaun
objetodelaclasederivadaconsudireccincontenidaenunpunteroalaclasebase.
Al igual que sucede con los nombres de los objetos, en principio cuando se hace
referencia a un objeto por medio de un puntero, el tipo de dicho puntero determina la
funcinmiembroqueseaplica,enelcasodequeesafuncinseencuentredefinidatantoen

Endefinitiva,unpunteroalaclasebasepuedealmacenarladireccindeunobjeto
pertenecienteaunaclasederivada.Sinembargo,seaplicarnlosmtodosdelaclaseala
que pertenezca el puntero, no los de la clase a la que pertenece el objeto. Por eso es
convenientehacerunaconversindinmicaforzada.
laclasebasecomoenladerivada.

Parapoderutilizarlaconversinforzadadurantelaejecucin,esnecesarioindicaral
compilador que se desea introducir informacin sobre las clases de los objetos en la
ejecucin.Paraello,enlaprcticaseindicacomohabilitarestemodo

Enelsiguienteejemplosepuedenverlasdistintasposibilidadesdeasignacinquese
puedenrealizarentreclasesbaseyclasesderivadaspormediodelasclasesCalseAyClaseB.
#include <iostream.h>
class ClaseA{
protected:
int a;
public:
ClaseA(int n):a(n){}
void mostrar(){cout<<a<<endl;}
};
class ClaseB:public ClaseA{
int b;
public:
ClaseB(int n, int m):ClaseA(n),b(m){}
void mostrar(){cout<<a<<,<<endl;};
} ;
void main()
{
ClaseA ca(2);
ClaseB cb(8,4);
ca.mostrar();
cb.mostrar();
//cb=ca; esto generara un error de compilacin (1)
ca=cb;
ca.mostrar();
138 PROGRAMACIN C++ Y COMUNICACIONES.

cb.mostrar();

ClaseA *c1=new ClaseA(1);


ClaseB *c2=new ClaseB(2,3);

ClaseA *c3=c1,*c4=c2;
c3->mostrar();
c4->mostrar();

ClaseB *c5;
c5 = static_cast<ClaseB *>(c3);
c5->mostrar(); //error en ejecucin (2)
c5 = static_cast<ClaseB *>(c4);
c5->mostrar();
delete c1;
delete c2;
}
En(1)seproduceunerrordecompilacinporquenosepermitelaasignacindesde
unobjetobaseaunobjetoderivadoporserelsegundomsextensoqueelprimero,porlo
quepartedelosatributosnosesabraquevalordebentomar.

Seobservasinembargoquelaasignacininversaesvlida.

En(2)semuestraunaconversinforzosadetipo.Seobligaalcompiladoraaceptar
queladireccinalmacenadaenc3esdeunobjetodeclaseB.Enestecasonoesas,porlo
que si por medio ce c5 ejecutamos un mtodo de la clase B, el resultado puede ser
desastroso,puestoquedichomtodoaccederaunazonadelamemoriaquenopertenece
al objeto y que incluso podra no pertenecer al programa con el consiguiente error del
sistemaoperativo.Hayquedestacarqueesteerrornoesdecompilacinsinodeejecucin.
Enlamayoriadeloscasos,silazonadememoriaaccedidaesnuestra,loquesemostrarser
el resultado de interpretar la memoria como si ah estuviera el atributo que estamos
consultando.

Por ltimo, en la ultima asignacin, el programador se hace responsable de que la


conversinforzadaesvlida.Dehecho,enestecaso,alserelobjetoapuntadorealmenteun
objetodeltipoClaseB,lallamadaalmtodomostrar()serealizacorrectamente.
Luegoelresultadodeejecutaresteprogramaeselsiguiente:
2
8,4
8
8,4
1
2
1,basura informatica????

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 4. LA HERENCIA. 139

2,3

ExisteenC++laposibilidadderealizarunaconversindetiposquecompruebesiel
objetoapuntadoporunpunteroesonoasignableaunpunterodeunaclasederivada.Esta
conversindinmicaconsultaeltipodedatosdelobjetopresenteenlamemoriadurantela
ejecucin.Siestetipodedatosesconvertiblealtipoquetienequerecibirlo,entoncessehace
laconversin.Encasodenoseraselresultadodeestaconversinescero.
Para poder aplicar dynamic_cast, hayquetenerdosprecauciones. Enprimer lugar,
esta operacin solo puede aplicarse sobre tipos polimrficos. Como se ver en el captulo
siguiente,estoocurrecuandosetienequealgunodelosmtodosdelaclaseesvirtua.
Ensegundolugar,hayqueindicaralcompiladorquedebeincluirinformacinsobre
lostiposdeclaseenelcdigo.Estaopcindecompilacindeberindicarseenlasopciones
generalesdelcompiladorqueseestutilizando.

Dichoesto,elejemploquedaramsrobustoyelegantesiseescribelosiguiente.En
ladefinicindelaclaseClaseAincluiremosundestructorvirtualaadiendolasiguientelnea:
virtual ~ClaseA(){}
Yelfinaldelafuncinmainanteriorloreescribiremosdelaformasiguiente:
c5= dynamic_cast<ClaseB *>(c3);
if(c5!=NULL)c5->mostrar();
c5= dynamic_cast<ClaseB *>(c4);
if(c5!=NULL)c5->mostrar();

Enestecaso,sloserealizarlasegundaimpresin,puestoqueelsistemadetecta
queelobjetoapuntadoporc3esdetipoClaseA,yqueportantonoesunaasignacinvlida
la pretendida. Por el contrario, aunque c4 es un puntero de tipo ClaseA, la direccin que
contieneesdeunobjetodetipoClaseB,porloqueeloperadordetectadurantelaejecucin
quelaasignacinesvlida.

4.6. El constructor de copia y el operador de asignacin


Unosdelosmtodosqueseaprendiasobrecargarylarazndedichasobrecarga
explicada en el captulo anterior eran el contructor de copia y la operacin de asignacin
representada por el operador igual. Se coment que precisamente estas operaciones no se
heredaban,yqueportantodebenserredefinidasporelprogramador.
Antes de ver como se debe realizar esta operacin en caso de tener una clase
derivada,esimportanteaclararcuandoseutilizaunoperadorounconstructorenelcdigo
escritodenuestroprograma.
140 PROGRAMACIN C++ Y COMUNICACIONES.

ElsiguienteprogramautilizalaclaseCCuentayadefinidaanteriormente:
void main()
{
CCuenta Cuenta1("Tu");
CCuenta Cuenta2("Yo",1000,10);
Cuenta1=Cuenta2; //(1)
CCuenta Cuenta3(Cuenta2); //(2)
CCuenta Cuenta4=Cuenta2; //(3)
}

En la lnea marcada con (1), claramente se utiliza el operador de asignacin
sobrecargado (si est definido). De igual forma, es claro que en la linea (2) se utiliza el
constructor de copia definido. Lo que es aparentemente una excepcin es la creacin de
Cuenta4enlalinea(3).Enestecaso,aunqueaparentementeparecequeseutilizaeloperador
deasignacin,sehaceusoimplcitodelconstructordecopia.

Una vez aclarado este aspectod ela sintaxis, vamos a ver de que modo se pueden
implementarestosdosmtodosnoheredadosenunaclasederivada:
#include <string.h>
#include <iostream.h>
class Nombre
{
char *nombre;
public:
Nombre(char *nom)
{
nombre=new char[strlen(nom)+1];
strcpy(nombre,nom);
}
Nombre(const Nombre &nom)
{
nombre=new char[strlen(nom.nombre)+1];
strcpy(nombre,nom.nombre);
}
Nombre &operator=(const Nombre &nom)
{
delete [] nombre;
nombre=new char[strlen(nom.nombre)+1];
strcpy(nombre,nom.nombre);
return *this;
}
~Nombre(){delete [] nombre;}
void mostrar(){cout<<nombre;}

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 4. LA HERENCIA. 141

};
class Alumno:public Nombre
{
int numero;
public:
Alumno(char *nom, int num):Nombre(nom),numero(num){}
Alumno(const Alumno &al):Nombre(al),numero(al.numero){};
Alumno &operator=(const Alumno &al)
{
Nombre::operator =(al);
numero=al.numero;
return *this;
}
};

void main()
{
Alumno uno("Juan Ramrez",43271);
Alumno dos=uno; //(1)
Alumno tres("Pepito",41278);
tres=dos; //(2)

Nombre extraer(uno); //(3)


uno.mostrar();
extraer=dos; //(4)
dos.mostrar();
}

Losmtodosqueseejecutanenlasinstruccionesmarcadassonlossiguientes:en(1)
seejecutaelconstructordecopiadeAlumno,peroantesdeejecutarseelcdigocontenido
entre las llaves se inicializa por medio del constructor de copia de Nombre, la parte
correspondienteaestaclasebase.PuestoqueunoesdeclaseAlumno,yestaesderivadade
nomre,laconversinesvidaeinmediata,talycomosemencionoenelanteriorapartado.
En(2)seutilizaeloperadordeasignacindelaclaseAlumno.Fjesequeenelcdigo
deesteoperador,sehaceunusoexplcitodeloperadordeasignacindeNombre.

En (3) se utiliza el constructor de copia de la clase Nombre, puesto que uno se


interpretacomo unobjetode suclase base. Por ltimo en(4) sehace usodel operador de
asignacindelaclasebase,aprovechandolamismapropiedadanterior.Portanto,elcdigo
sacarporpantalladosvecesconsecutivaselmensajeJuanRamrez.
Para no tener que reescribir cdigo que hace lo mismo, es habitual que un
constructordecopiautiliceelpropiooperadordeasignacinsobrecargado.Deestaforma,se
podrareescribirelconstructordecopiacomo:
142 PROGRAMACIN C++ Y COMUNICACIONES.

Alumno(const Alumno &al):Nombre(" ")


{
*this=al;
}

Enestecasoespocoeficientealnotenerunconstructorpordefectodefinidoparala
claseNombre,porloqueseharunareservadememoriaqueinmediatamenteserdenuevo
eliminada por la operacin de asignacin. Sin embargo es interesante que no exista
redundanciaenelcdigodeformaquesloseanecesariomodificaroactualizarunsitiopara
realizarunaoperacinequivalente.

4.7. Ejemplo
Elsiguienteejemploeselcdigoutilizadoenlasprcticasparalarealizacindeuna
pequeajerarquadeclasesquepermitelarealizacindeunapequeabiblioteca:

#include <iostream.h>
typedef std::string cadena;

class CFicha
{
protected:
cadena referencia;
cadena titulo;
public:
// Constructor
CFicha(cadena ref= "", cadena tit= "");
// Destructor
virtual ~CFicha() {};
// Otras funciones
void AsignarReferencia(cadena ref);
cadena ObtenerReferencia() ;
void AsignarTitulo(cadena tit);
cadena ObtenerTitulo() ;
void Imprimir();
void PedirFicha();
friend void TomarLinea(cadena&);

};
class CFichaLibro : public CFicha
{
private:
cadena autor;
cadena editorial;

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 4. LA HERENCIA. 143

public:
// Constructor
CFichaLibro(cadena ref= "", cadena tit= "", cadena aut=
"", cadena ed= "");

// Otras funciones
void AsignarAutor(cadena aut);
cadena ObtenerAutor();
void AsignarEditorial(cadena edit);
cadena ObtenerEditorial();
void PedirLibro();
void Imprimir();
};
class CFichaRevista : public CFicha
{
private:
int NroDeRevista;
int Anyo;
public:
// Constructor
CFichaRevista(cadena ref= "", cadena tit= "", int an= 0, int
nro= 0);
// Otras funciones
void AsignarNroDeRevista(int nro);
int ObtenerNroDeRevista() ;
void AsignarAnyo(int any);
int ObtenerAnyo() ;
void PedirRevista();
void Imprimir();
};
class CFichaVolumen : public CFichaLibro
{
private:
int NroDeVolumen;
public:
// Constructor
CFichaVolumen(cadena ref = "", cadena tit= "", cadena aut=
"", cadena edit= "", int Nro= 0);
// Otras funciones
void AsignarNroDeVolumen(int);
int ObtenerNroDeVolumen();
void PedirVolumen();
void Imprimir();
};
class CBiblioteca
{
private:
144 PROGRAMACIN C++ Y COMUNICACIONES.

std::vector<CFicha *> ficha;


public:
// Constructor
CBiblioteca(int = 100);
// Destructor
~CBiblioteca();
// Operador de indexacin
CFicha *operator[](int);
// Otras funciones
void AnyadirFicha(CFicha *);
int longitud();
void VisualizarFichas();
bool eliminar(cadena);
int buscar(cadena, int);
void VisualizarFicha(int i);
};
ostream& operator<<(std::ostream&, CFicha *);

/**************************************************************
Fin de las declaraciones comienzan las definiciones
**************************************************************/

CFicha::CFicha(cadena ref, cadena tit)


{
referencia = ref;
titulo = tit;
}

void CFicha::AsignarReferencia(cadena ref)


{
referencia = ref;
}

cadena CFicha::ObtenerReferencia()
{
return referencia;
}

void CFicha::AsignarTitulo(cadena tit)


{
titulo = tit;
}

cadena CFicha::ObtenerTitulo()
{
return titulo;
}

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 4. LA HERENCIA. 145

void CFicha::PedirFicha()
{
cout << "Referencia.............: ";
TomarLinea(referencia);
cin.ignore(100, '\n');
cout << "Ttulo.................: ";
TomarLinea(titulo);
}

void TomarLinea(cadena& var)


{
char valor[100];
cin.getline(valor,99);
var+=valor;
}
void CFicha::Imprimir()
{
cout << "Referencia: " << referencia.data() <<endl;
cout << "Titulo: " << titulo.data() <<endl;
}
CFichaLibro::CFichaLibro(cadena ref, cadena tit, cadena aut,
cadena edit): CFicha(ref, tit)
{
autor = aut;
editorial = edit;
}

void CFichaLibro::AsignarAutor(cadena aut)


{
autor = aut;
}

cadena CFichaLibro::ObtenerAutor()
{
return autor;
}

void CFichaLibro::AsignarEditorial(cadena edit)


{
editorial = edit;
}

cadena CFichaLibro::ObtenerEditorial()
{
return editorial;
}
146 PROGRAMACIN C++ Y COMUNICACIONES.

void CFichaLibro::PedirLibro()
{
PedirFicha();
cout << "Autor..................: ";
TomarLinea(autor);
cout << "Editorial..............: ";
TomarLinea(editorial);
}
void CFichaLibro::Imprimir()
{
cout << "Autor: " << autor.data() <<endl;
cout << "Editorial: " << editorial.data() <<endl;
}
CFichaRevista::CFichaRevista(cadena ref, cadena tit, int
nroderev, int anyo) : CFicha(ref, tit), NroDeRevista(nroderev),
Anyo(anyo){}

void CFichaRevista::AsignarNroDeRevista(int nroderev)


{
NroDeRevista = nroderev;
}

int CFichaRevista::ObtenerNroDeRevista()
{
return NroDeRevista;
}

void CFichaRevista::AsignarAnyo(int anyo)


{
Anyo = anyo;
}

int CFichaRevista::ObtenerAnyo()
{
return Anyo;
}
void CFichaRevista::PedirRevista()
{
PedirFicha();
cout << "Nro. de la revista.....: ";
cin >> NroDeRevista;
cout << "Ao de publicacin.....: ";
cin >> Anyo;
}
void CFichaRevista::Imprimir()
{
cout << "Nro Revista: " << NroDeRevista <<endl;

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 4. LA HERENCIA. 147

cout << "Ao : " << Anyo <<endl;


}
CFichaVolumen::CFichaVolumen(cadena ref, cadena tit, cadena aut,
cadena edit, int nrodevol) : CFichaLibro(ref, tit, aut,
edit),NroDeVolumen(nrodevol){}

void CFichaVolumen::AsignarNroDeVolumen(int nrodevol)


{
NroDeVolumen = nrodevol;
}

int CFichaVolumen::ObtenerNroDeVolumen()
{
return NroDeVolumen;
}
void CFichaVolumen::PedirVolumen()
{
PedirLibro();
cout << "Nro. del volumen.......: ";
cin>>NroDeVolumen;
}
void CFichaVolumen::Imprimir()
{
cout << "Tomo: " << NroDeVolumen <<endl;
}
CBiblioteca::CBiblioteca(int n)
{
if (n < 0) n = 1;
ficha.reserve(n);
}

CBiblioteca::~CBiblioteca()
{
for (int i = 0; i < ficha.size(); i++)delete ficha[i];
}

// Indexacin
CFicha *CBiblioteca::operator[](int i)
{
if (i >= 0 && i < ficha.size()) return ficha[i];
else
{
cout << "error: ndice fuera de lmites\n";
return 0;
}
}
148 PROGRAMACIN C++ Y COMUNICACIONES.

// Asignar un objeto al array


void CBiblioteca::AnyadirFicha(CFicha *pficha)
{
//aade una ficha al final del vector
ficha.push_back(pficha);
}

int CBiblioteca::longitud()
{
//nos dice cuantos elementos se han introducido en el vector
return ficha.size();
}

// Visualizar todos los objetos


void CBiblioteca::VisualizarFichas()
{
if (ficha.size()==0)
{
cout << "Biblioteca vaca\n";
return;
}
for (int i = 0; i < ficha.size(); i++)VisualizarFicha(i);
}
void CBiblioteca::VisualizarFicha(int i)
{
if (ficha.size()>i)
{
cout<<"----------------------------------"<<endl;
ficha[i]->Imprimir();
if (CFichaLibro *p = dynamic_cast<CFichaLibro *>(ficha[i]))
p->Imprimir();

if (CFichaVolumen *p=dynamic_cast<CFichaVolumen *>(ficha[i]))


p->Imprimir();

if (CFichaRevista *p=dynamic_cast<CFichaRevista *>(ficha[i]))


p->Imprimir();

cout<<"----------------------------------"<<endl;
}

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 4. LA HERENCIA. 149

bool CBiblioteca::eliminar(cadena refe)


{
// Buscar la ficha y eliminar el objeto
for (unsigned int i = 0; i < ficha.size(); i++)
if (refe == ficha[i]->ObtenerReferencia())
{
delete ficha[i];
ficha.erase(ficha.begin()+i);
return true;
}
return false;
}

int CBiblioteca::buscar(cadena str, int pos)


{
// Buscar un objeto y devolver su posicin
cadena titu, refe;
if (str.empty()) return -1;
if (pos < 0) pos = 0;
for (unsigned int i = pos; i < ficha.size(); i++)
{
// Buscar por el ttulo
titu = ficha[i]->ObtenerTitulo();
if (titu.empty()) continue;
// str est contenida en titu?
if (titu.find(str) != cadena::npos)
return i;
// Buscar por la referencia
refe = ficha[i]->ObtenerReferencia();
if (refe.empty()) continue;
// str es la referencia?
if (str == refe)
return i;
}
return -1;
}
CFicha *leerDatos(int op);
int leerDato();
int menu();

/**********************************************************
************** MAIN ***********************************
**********************************************************/
void main()
{
150 PROGRAMACIN C++ Y COMUNICACIONES.

// Crear un objeto con cero elementos


CBiblioteca bibli;
CFicha *unaFicha = 0;

int opcion = 0, pos = -1;


cadena cadenabuscar;
cadena refe;
bool eliminado = false;

do
{
opcion = menu();
switch (opcion)
{
case 1: // aadir
cout << "Tipo de ficha < 1-(rev), 2-(lib), 3-(vol) >: ";
do
opcion = (int)leerDato();
while (opcion < 1 || opcion > 3);
unaFicha = leerDatos(opcion);
bibli.AnyadirFicha(unaFicha);
break;
case 2: // buscar
cout << "Ttulo total o parcial, o referencia: ";
TomarLinea(cadenabuscar);
pos = bibli.buscar(cadenabuscar, 0);
if (pos == -1)
{
if (bibli.longitud() != 0)
cout << "bsqueda fallida\n";
else
cout << "no hay fichas\n";
}
else
bibli.VisualizarFicha(pos);
break;
case 3: // buscar siguiente
pos = bibli.buscar(cadenabuscar, pos + 1);
if (pos == -1)
if (bibli.longitud() != 0)
cout << "bsqueda fallida\n";
else
cout << "no hay fichas\n";
else
bibli.VisualizarFicha(pos);
break;
case 4: // eliminar ficha

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 4. LA HERENCIA. 151

cout << "Referencia: ";


TomarLinea(refe);
eliminado = bibli.eliminar(refe);
if (eliminado)
cout << "registro eliminado\n";
else
{
if (bibli.longitud() != 0)
cout << "referencia no encontrada\n";
else
cout << "no hay fichas\n";
}
break;
case 5: // listado de la biblioteca
bibli.VisualizarFichas();
break;
}
}
while(opcion != 6);
}

/*********************************************************
FUNCION: int menu()
ARGUMENTOS: ninguno
RETORNO: int. Devolver la opcin escogida (1-6)
DESCRIPCION: Imprime por pantalla el men principal y
solicita al usuario que seleccione. No retornar un
valor hasta que la seleccin sea vlida.
*********************************************************/
int menu()
{
cout << "\n\n";
cout << "1. Aadir ficha\n";
cout << "2. Buscar ficha\n";
cout << "3. Buscar siguiente\n";
cout << "4. Eliminar ficha\n";
cout << "5. Listado de la biblioteca\n";
cout << "6. Salir\n";
cout << endl;
cout << " Opcin: ";
int op;
do
op = (int)leerDato();
while (op < 1 || op > 6);
return op;
}
152 PROGRAMACIN C++ Y COMUNICACIONES.

/*********************************************************
FUNCION: CFicha *leerDatos(int op)
ARGUMENTOS:
int op: Indica el tipo de Ficha que se tiene que crear.
1= Revista, 2= Libro, 3=Volumen
RETORNO: CFicha *. Devolver un puntero a la ficha creada
dinmicamente en funcin de la seleccion y los valores
introducidos por el usuario.
DESCRIPCION: Funcion principal que es llamada cada vez que
quiera crear una ficha de cualquire tipo.
*********************************************************/
CFicha *leerDatos(int op)
{
CFicha *obj=NULL;
switch(op)
{
case 1:
{
CFichaRevista *aux = new CFichaRevista();
aux->PedirRevista();
obj=aux;
}
break;
case 2:
{
CFichaLibro *aux = new CFichaLibro();
aux->PedirLibro();
obj=aux;
}
break;
case 3:
{
CFichaVolumen *aux = new CFichaVolumen();
aux->PedirVolumen();
obj=aux;
}
}
return obj;
}
/*********************************************************
FUNCION: int leerDatos()
ARGUMENTOS: ninguno
RETORNO: int. Retorna el nmero leido
DESCRIPCION: Funcion especial para hacer ms cmoda y
segura la lectura de nmeros del teclado.
*********************************************************/
int leerDato()

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 4. LA HERENCIA. 153

{
int dato = 0;
cin >> dato;
while (cin.fail()) // si el dato es incorrecto, limpiar el
{ // bfer y volverlo a leer
cout << '\a';
cin.clear();
cin.ignore(100, '\n');
cin >> dato;
}
// Eliminar posibles caracteres sobrantes
cin.clear();
cin.ignore(100, '\n');

return dato;
}
5. El Polimorfismo

Conestecaptulosetendrnlasherramientasbsicasparaeldesarrollodeunbuen
programa en C++. An quedara el uso de plantillas, pero estas pueden ser sustituidas en
muchos casos por el polimorfismo, y desde luego son ms difciles de utilizar por un
programadornovelquelosmecanismoshastaahoraexplicados.
Antes de adentrarse en el concepto depolimorfismo, su utilidad y su casustica, es
necesarioaclararalgnconceptoenloqueserefierealasuperposicinylasobrecarga:

5.1. Superposicin y sobrecarga


Talycomosevienelcaptuloanteriorenunaclasederivadasepuededefiniruna
funcinqueyaexistaenlaclasebase.Estoseconocecomo"overriding",osuperposicinde
unafuncin.Ladefinicindelafuncinenlaclasederivadaocultaladefinicinpreviaenla
clasebase.Encasonecesario,esposibleaccederalafuncinocultadelaclasebasemediante
sunombrecompleto:

Departamento de Electrnica Automtica e Informtica Industrial


CAPTULO 5. EL POLIMORFISMO 155


<objeto>.<clase_base>::<mtodo>;

Cuando se superpone una funcin, se ocultan todas las funciones con el mismo
nombre en la clase base. Supongamos que hemos sobrecargado la funcin de la clase base
quedespusvolveremosadefinirenlaclasederivada:

#include <iostream.h>

class ClaseA
{
public:
void Incrementar() { cout << "Suma 1" << endl; }
void Incrementar(int n) { cout << "Suma " << n << endl; }
};
class ClaseB : public ClaseA
{
public:
void Incrementar() { cout << "Suma 2" << endl; }
};

int main()
{
ClaseB objeto;
objeto.Incrementar();
objeto.Incrementar(10); //Existe este mtodo?
objeto.ClaseA::Incrementar();
objeto.ClaseA::Incrementar(10);
cin.get();
return 0;
}

Ahora bien, no es posible acceder a ninguna de las funciones superpuestas de la
clase base, aunque tengan distintos valores de retorno o distinto nmero o tipo de
parmetros.Todaslasfunciones"incrementar"delaclasebasehanquedadoocultas,yslo
son accesibles mediante el nombre completo. Por ello la lnea marcada dar un error de
compilacin, puesto que no existe la funcin incrementar definida en la claseB que reciba
comoargumentountipodedatosalque10seaconvertible.
Trascorregirelerroreliminandoestalnea,lasalidaser:
Suma 2
156 PROGRAMACIN C++ Y COMUNICACIONES.

Suma 1
Suma 10

5.2. Polimorfismo
Ha llegado el momento de introducir uno de los conceptos ms importantes de la
programacinorientadaaobjetos:elpolimorfismo.
En lo que concierne a clases, el polimorfismo en C++, llega a su mxima expresin
cuandolasusamosjuntoconpunterosoconreferencias.Comosehavisto,C++nospermite
accederaobjetosdeunaclasederivadausandounpunteroalaclasebase.Enesoconsisteo
sebasaelpolimorfismo.Hataahoraslopodemosaccederadatosyfuncionesqueexistanen
la clase base, los datos y funciones propias de los objetos de clases derivadas sern
inaccesibles. Esto es debido a que el compilador decide en tiempo de compilacin que
mtodosyatributosestndisponiblesenfuncindelcontenedor.
Parailustrarlovamosaverunejemplosobreunaestructuradeclasesbasadoenla
clase"Persona"ydosclasesderivadas"Empleado"y"Estudiante":

#include <iostream.h>
#include <string.h>

class Persona
{
public:
Persona(char *n) { strcpy(nombre, n); }
void VerNombre() { cout << nombre << endl; }
protected:
char nombre[30];
};
class Empleado : public Persona
{
public:
Empleado(char *n) : Persona(n) {}
void VerNombre()
{
cout << "Emp: " << nombre << endl;
}
};

class Estudiante : public Persona


{
public:
Estudiante(char *n) : Persona(n) {}

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 5. EL POLIMORFISMO 157

void VerNombre()
{
cout << "Est: " << nombre << endl;
}
};
void main() {
Persona *Pepito = new Estudiante("Jose");
Persona *Carlos = new Empleado("Carlos");
Carlos->VerNombre();
Pepito->VerNombre();
delete Pepito;
delete Carlos;
}

Por simplificar el cdigo, se ha utilizado memoria esttica en vez de dinmica.


Evidentemente este es un error funcional grave puesto que el usuario de la clase puede
provocar un fallo en la ejecucin haciendo un uso correcto de los mtodos de interfaz. En
cualquiercaso,suponiendoquetenemoscuidado,lasalidadelprograma,comoesprevisible
serlasiguiente:

Carlos

Jose
Podemos comprobar que se ejecuta la versin de la funcin "VerNombre" que
hemos definido para la clase base, y no la de las clases derivadas. Esto es debido a que la
funcinqueseejecutaseresuelveentiempodeEJECUCIONatendiendonoaltipodeobjeto
apuntado,sinoaltipodelapuntador.
Poreso,siescribimos:
Estudiante *Pepito=new Estudiante(Jose);
Empleado *Carlos=new Empleado(Carlos);

EntoncessiqueseejecutarelmtodoVerNombresuperpuesto.
Esto mismo sucede con las referencias. Las siguientes lneas de cdigo son
totalmentevlidas,siendoelefectoanlogoalobtenidopormediodepunteros:
Estudiante Jose(Jose);
Persona &pJose=Jose;
pJose.VerNombre();
Esdecir,enestecaso,atendiendoalrecipienteynoaloapuntado,seutilizarde
nuevoelmtodoVerNombredelaclasePersona,apesardequerealmentepJoseesunalias
158 PROGRAMACIN C++ Y COMUNICACIONES.

deunobjetodetipoEstudiante.Yaobservamosqueunobjetosecomportadedistintaforma
enfuncindeconqueseloreferencieoapunte.
Sin embargo, parece interesante que cada objeto se comporte como debe
independientementedelrecipiente,esdecir,independientementedeconquesereferencieo
apunteestonosllevaalconceptodepolimorfismodelamanodelosdenominadosmtodos
virtuales.

Mtodos virtuales
Unmtodovirtualesunmtododeunaclasebasequepuedeserredefinidoencada
unadelasclasesderivadasdeesta,yqueunavezredefinidopuedeseraccedidopormedio
deunpunteroounareferenciaalaclasebase,resolvindoseentonceslallamadaenfuncin
delobjetoreferidoenvezdeenfuncindeconqusehacelareferencia.
Quevieneasignificarquesienunaclasebasedefinimosunmtodocomovirtual,si
estemtodoessuperpuestoporunaclasederivada,alinvocarloutilizandounpunteroouna
referenciadelaclasebase,seejecutarelmtododelaclasederivada!.

Cuandounaclasetienealgnmtodovirtualbiendirectamente,bienporherencia
sedicequedichaclaseespolimrfica.

Paradeclararunmtodocomovirtualseutilizalasiguientesintaxis:
virtual <tipo> <nombre_funcin>(<lista_parmetros>) [{}];

Como siempre, la mejor forma de entender los conceptos en programacin es ver


ejemplosdecdigoconsuresultado.

Modifiquemos en el ejemplo anterior la declaracin de la clase base "Persona",


haciendoqueelmtodoVerNombreseavirtual:
class Persona
{
public:
Persona(char *n) { strcpy(nombre, n); }
virtual void VerNombre() {cout << nombre << endl;}
protected:
char nombre[30];
};

Ahora ejecutemos el programa de nuevo. Observamos entonces que la salida es


diferente:
Emp:Carlos

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 5. EL POLIMORFISMO 159

Est:Jose

Ahora,alllamaraPepito>VerNombre()seinvocaalafuncinVerNombredelaclase
Estudiante,yalllamaraCarlos>VerNombre()seinvocaalafuncindelaclaseEmpleado,a
pesardequetantoPepitocomoCarlossonpunterosalaclasePersona.
Deigualformaocurrirsienvezdeutilizarpunteros,hacemosusodereferencias:
void main()
{
Estudiante Pepito("Jose");
Empleado Carlos("Carlos");
Persona &rPepito = Pepito; // Referencia como Persona
Persona &rCarlos = Carlos; // Referencia como Persona
rCarlos.VerNombre(); //cada objeto ejecuta su mtodo
rPepito.VerNombre(); //en vez de utilizar el de Persona
}

Portanto,laideacentraldelpolimorfismoesladepoderllamarafuncionesdistintas
aunque tengan el mismo nombre, segn la clase a la que pertenece el objeto al que se
aplican. Esto es imposible utilizando nombres de objetos: siempre se aplica la funcin
miembro de la clase correspondiente al nombre del objeto, y esto se decide en tiempo de
compilacin.

Sinembargo,utilizandopunterospuedeconseguirseelobjetivobuscado.Recurdese
que un puntero a la clase base puede contener direcciones de objetos de cualquierade las
clasesderivadas.

Antes de ahondar y ver ms ejemplos de mtodos virtuales se van a establecer


algunascaractersticasdelmecanismodevirtualidad:

Una vez que una funcin es declarada como virtual, lo seguir siendo en las
clasesderivadas,esdecir,lapropiedadvirtualsehereda.

Si la funcin virtual no se define exactamente con el mismo tipo de valor de


retorno y el mismo nmero y tipo de parmetrosqueen laclase base, no se
considerarcomolamismafuncin,sinocomounafuncinsuperpuesta.

El nivel de acceso no afecta a la virtualidad de las funciones. Es decir, una


funcin virtual puede declararse como privada en las clases derivadas aun
160 PROGRAMACIN C++ Y COMUNICACIONES.

siendo pblica en la clase base, pudiendo por tanto ejecutarse ese mtodo
privadodesdefuerapormediodeunpunteroalaclasebase.

Una llamada a un mtodo virtual se resuelve siempre en funcin del tipo del
objetoreferenciado.

Unallamadaaunmtodonormalseresuelvesiempreenfuncindeltipodela
referenciaopunteroutilizado.

Una llamadaa un mtodo virtual especificando laclase,exige la utilizacin del


operadorderesolucindembito::,loquesuprimeelmecanismoderitualidad.
Evidentemente este mecanismo solo podr utilizarse para el mtodo de la
mismaclasedelcontenedorodeclasesbasedelmismo.

Porsumododefuncionamientointerno(esdecir,porelmodoenquerealmente
trabajaelordenador)lasfuncionesvirtualessonunpocomenoseficientesque
lasfuncionesnormales.
Vamos a ver algn ejemplo adicional que ayude a entender el polimorfismo y las
clasespolimrficas.
#include <iostream.h>

class Base
{
public:
virtual void ident(){cout<<"Base"<<endl;}
};
class Derivada1:public Base
{
public:
void ident(){cout<<"Primera derivada"<<endl;}
};
class Derivada2:public Base
{
public:
void ident(){cout<<"Segunda derivada"<<endl;}
};
class Derivada3:public Base
{
public:
void ident(){cout<<"Tercera derivada"<<endl;}
};

void main()
{
Base base,*pbase;

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 5. EL POLIMORFISMO 161

Derivada1 primera;
Derivada2 segunda;
Derivada3 tercera;

pbase=&base;
pbase->ident();
pbase=&primera;
pbase->ident();
pbase=&segunda;
pbase->ident();
pbase=&tercera;
pbase->ident();
}

Evidentemente,elresultadodeejecutarestecdigoeselsiguiente:
Base
Primera derivada
Segunda derivada
Tercera derivada

De nuevo, al ser el mtodo virtual se ejecuta la funcin del objeto apuntado,


independientementedequeseapunteconunpunterodetipoBase.
Siescribiramoslosiguienteenelcuerpodelmain:
pbase=&base;
pbase->Base::ident();
pbase=&primera;
pbase->Base::ident();
pbase=&segunda;
pbase->Base::ident();
pbase=&tercera;
pbase->Base::ident();

Entonceselresultadodelaejecucinseraelsiguiente:
Base
Base
Base
Base

Ahora lo que haremos ser poner la modificacin de virtualidad en la clase


Derivada2,yloquitamosdelaclaseBase.Enestecasoelresultadodelaejecucinserde
162 PROGRAMACIN C++ Y COMUNICACIONES.

nuevo cuatro veces Base. Esto es debido a que desde el punto de vista del puntero que
contenedor (de tipo Base) la funcin ya no es virtual y por tanto se decide en tiempo de
compilacincomocualquiermtodonormal.Parapoderaccederalmtododefinidoporlas
clasesderivadasalmenossernecesarioqueutilicemosunpunterodetipoDerivada2para
aquellasclasesquesonpolimrficas(enestecasosloloseraDerivada3).

Porltimo,sivolvemosalprogramaoriginal,yestablecemosqueelmtodoidentes
privado en la clase Derivada2, se observa que no afecta para nada al funcionamiento de
nuestroprograma.
El polimorfismo hace posible que un usuario pueda aadir nuevas clases a una
jerarquasinmodificarorecompilarelcdigooriginal.Estoquieredecirquesideseaaadir
una nueva clase derivada es suficiente con establecer la clase de la que deriva, definir sus
nuevas variables y funciones miembro, y compilar esta parte del cdigo, ensamblndolo
despusconloqueyaestabacompiladopreviamente.
Elsiguienteejemploesunpocomslargoycomplicadorespectodelosanteriores,
peroesmselocuenteantelasposibilidadesquenosofreceelpolimorfismo:

#include <iostream.h>

class Vehiculo
{
public:
virtual void muestra(ostream &co){}
virtual void rellena(){}
friend ostream& operator <<(ostream &co,Vehiculo &ve)
{
ve.muestra(co);
return co;
}
};
class Coche:public Vehiculo
{
protected:
char marca[20];
char modelo[20];
public:
void muestra(ostream &co)
{
co<<"Coche marca "<<marca<<" modelo "<<modelo<<endl;
}
void rellena()
{

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 5. EL POLIMORFISMO 163

cout<<"Marca?:";
cin>>marca;
cout<<"Modelo?:";
cin>>modelo;
cin.clear();
}
};
class Camion:public Coche
{
private:
int carga;
public:
void muestra(ostream &co)
{
co<<"Camion marca "<<marca<<" modelo "<<modelo<<endl;
co<<"\tCapacidad de carga: "<<carga<< "Kg."<<endl;
}
void rellena()
{
Coche::rellena();
cout<<"Carga mxima?:";
cin>>carga;
cin.clear();
}
};

void main()
{
Vehiculo *flota[4];
int seleccion=0;
for(int i=0;i<3;i++)
{
cout<<"Seleccione tipo del vehiculo "<<i<<":\n";
cout<<"(1-Camin, 2-Coche): ";

while((seleccion<1)||(seleccion>2))
cin>>seleccion;
switch(seleccion)
{
case 1: flota[i]=new Camion;break;
case 2: flota[i]=new Coche;break;
}
seleccion=0;
flota[i]->rellena();
}
cout<<"\n Estos son los vehiculos introducidos:\n";
for(i=0;i<3;i++)cout<<i<<":"<<*flota[i];
164 PROGRAMACIN C++ Y COMUNICACIONES.

}

Unejemplodeejecucindeesteprogramaeselsiguiente:


Seleccione tipo del vehiculo 0:
(1-Camin, 2-Coche): 1
Marca?:SCANIA
Modelo?:SuperTruck
Carga mxima?:22000
Seleccione tipo del vehiculo 1:
(1-Camin, 2-Coche): 2
Marca?:Seat
Modelo?:Ibiza
Seleccione tipo del vehiculo 2:
(1-Camin, 2-Coche): 2
Marca?:Renault
Modelo?:Twingo

Estos son los vehiculos introducidos:


0:Camion marca SCANIA modelo SuperTruck
Capacidad de carga: 22000Kg.
1:Coche marca Seat modelo Ibiza
2:Coche marca Renault modelo Twingo

Se observa entonces como es posible almacenar y tratar los objetos como iguales
atendiendoaqueheredandeunamismaclasebase,ysinembargo,estosmismosobjetosson
capaces de realizar acciones distintas o especializadas cuando se ejecutan sus mtodos
virtuales.Estoeslapotenciadelpolimorfismo,ytalvezgraciasalmismoalgunocomienzea
vislumbrarelporqueseparecentantoyalavezsondistintoslosprogramasquesemanejan
sobreWindows.

Implementacin del mecanismo de virtualidad


A continuacin se explica, sin entrar en gran detalle, el funcionamiento de las
funciones virtuales. Cada clase que utiliza funciones virtuales tiene un vector de punteros,
uno por cada funcin virtual, llamado vtable. Cada uno de los punteros contenidos en ese
vector apunta a la funcin virtual apropiada para esa clase, que ser, habitualmente, la
funcinvirtualdefinidaenlapropiaclase.Enelcasodequeenesaclasenoestdefinidala
funcinvirtualencuestin,elpunterodevtableapuntaralafuncinvirtualdesuclasebase
msprximaenlajerarqua,quetengaunadefinicinpropiadelafuncinvirtual.Estoquiere

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 5. EL POLIMORFISMO 165

decirquebuscarprimeroenlapropiaclase,luegoenlaclaseanteriorenelordenjerrquico
yseirsubiendoeneseordenhastadarconunaclasequetengadefinidalafuncinbuscada.
Cadaobjetocreadodeunaclasequetengaunafuncinvirtualcontieneunpuntero
ocultoalavtabledesuclase.Medianteesepunteroaccedeasuvtablecorrespondienteya
travsdeestatablaaccedealadefinicinadecuadadelafuncinvirtual.Esestetrabajoextra
elquehacequelasfuncionesvirtualesseanmenoseficientesquelasfuncionesnormales.

5.3. Virtualidad en destructores y constructores.


Supongamosquetenemosunaestructuradeclasesenlaqueenalgunadelasclases
derivadasexistaundestructor.Undestructoresunafuncincomolasdems,porlotanto,si
destruimosunobjetoreferenciadomedianteunpunteroalaclasebase,yeldestructornoes
virtual,estaremosllamandoaldestructordelaclasebase.Estopuedeserdesastroso,yaque
nuestraclasederivadapuedetenermstareasquerealizarensudestructorquelaclasebase
delaqueprocede.Sinoposiblementeseranecesariodefinirlo.

Como norma general, el constructor de la clase base se llama antes que el


constructor de la clase derivada. Con los destructores, sin embargo, sucede al revs: el
destructordelaclasederivadasellamaantesqueeldelaclasebase.
Poresarazn,enelcasodequeseborre,aplicandodelete,unpunteroaunobjeto
delaclasebasequeapunteaunobjetodeunaclasederivada,sellamaraldestructordela
clasebase,envezdealdestructordelaclasederivada,queseraloadecuado.Lasolucina
esteproblemaconsisteendeclararcomovirtualeldestructordelaclasebase.Estohaceque
automticamentelosdestructoresdelasclasesderivadasseantambinvirtuales,apesarde
tenernombres distintos.De este modo, al aplicar delete aunpunterode laclasebase que
puedeapuntaraunobjetodeesetipooacualquierobjetodeunaclasederivada,seaplicael
destructoradecuadoencadacaso.
Esteproblemanosepresentaconlosconstructoresyporesonoexisteningntipo
deconstructorvirtualosimilar.Poresolosconstructoresnopuedenservirtuales.Estopuede
serunproblemaenciertasocasiones.Porejemplo,elconstructordecopianoharsiempre
aquelloque esperamos quehaga. Engeneral nodebemos usar el constructor copiacuando
usemospunterosaclasesbase.Parasolucionaresteinconvenientesesuelecrearunafuncin
virtual"clonar"enlaclasebasequesesuperpondrparacadaclasederivada.
Porejemplo:

#include <iostream>
#include <cstring>
166 PROGRAMACIN C++ Y COMUNICACIONES.

using namespace std;


class Persona {
public:
Persona(char *n) { strcpy(nombre, n); }
Persona(const Persona &p);
virtual void VerNombre() {
cout << nombre << endl;
}
virtual Persona* Clonar() { return new Persona(*this); }
protected:
char nombre[30];
};
Persona::Persona(const Persona &p) {
strcpy(nombre, p.nombre);
cout << "Per: constructor copia." << endl;
}
class Empleado : public Persona {
public:
Empleado(char *n) : Persona(n) {}
Empleado(const Empleado &e);
void VerNombre() {
cout << "Emp: " << nombre << endl;
}
virtual Persona* Clonar() { return new Empleado(*this); }
};
Empleado::Empleado(const Empleado &e) : Persona(e) {
cout << "Emp: constructor copia." << endl;
}
class Estudiante : public Persona {
public:
Estudiante(char *n) : Persona(n) {}
Estudiante(const Estudiante &e);
void VerNombre() {
cout << "Est: " << nombre << endl;
}
virtual Persona* Clonar() {
return new Estudiante(*this);
}
};
Estudiante::Estudiante(const Estudiante &e) : Persona(e) {
cout << "Est: constructor copia." << endl;
}
int main() {
Persona *Pepito = new Estudiante("Jose");
Persona *Carlos = new Empleado("Carlos");
Persona *Gente[2];
Carlos->VerNombre();

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 5. EL POLIMORFISMO 167

Pepito->VerNombre();
Gente[0] = Carlos->Clonar();
Gente[0]->VerNombre();
Gente[1] = Pepito->Clonar();
Gente[1]->VerNombre();
delete Pepito;
delete Carlos;
delete Gente[0];
delete Gente[1];
cin.get();
return 0;
}

Hemosdefinidoelconstructorcopiaparaquesepuedavercuandoesinvocado.La
salidaessta:

Emp: Carlos
Est: Jose
Per: constructor copia.
Emp: constructor copia.
Emp: Carlos
Per: constructor copia.
Est: constructor copia.
Est: Jose

Estemtodoaseguraquesiempresellamaalconstructorcopiaadecuado,yaquese
hacedesdeunafuncinvirtual.
Siunconstructorllamaaunafuncinvirtual,stasersiempreladelaclasebase.
Estoesdebidoaqueelobjetodelaclasederivadaannohasidocreada.

5.4. Funciones virtuales puras y clases abstractas


Habitualmentelasfuncionesvirtualesdelaclasebasedelajerarquanoseutilizan
porqueenlamayoradeloscasosnosedeclaranobjetosdeesaclase,y/oporquetodaslas
clasesderivadastienensupropiadefinicindelafuncinvirtual.Sinembargo,inclusoenel
casodequelafuncinvirtualdelaclasebasenovayaaserutilizada,debedeclararse.
De todos modos, si la funcin no va a ser utilizada no es necesario definirla, y es
suficientecondeclararlacomofuncinvirtualpura.Unafuncinvirtualpurasedeclaraas:
168 PROGRAMACIN C++ Y COMUNICACIONES.

virtual <tipo> <nombre_funcin>(<lista_parmetros>) = 0;

La nica utilidad de esta declaracin es la de posibilitar la definicin de funciones


virtualesenlasclasesderivadas.Dealgunamanerasepuededecirqueladefinicindeuna
funcincomovirtualpurahacenecesarialadefinicindeesafuncinenlasclasesderivadas,
alavezqueimposibilitasuutilizacinconobjetosdelaclasebase.

Aldefinirunafuncincomovirtualpurahayquetenerencuentaque:

Nohacefaltadefinirelcdigodeesafuncinenlaclasebase.

Nosepuedendefinirobjetosdelaclasebase,yaquenosepuedellamaralas
funcionesvirtualespuras.

Sin embargo, es posible definir punteros a la clase base, pues es a travs de


elloscomoserposiblemanejarobjetosdelasclasesderivadas.

Se denomina clase abstracta a aquella que contiene una o ms funciones virtuales


puras.Elnombreprovienedequenopuedeexistirningnobjetodeesaclase.Siunaclase
derivada no redefine una funcin virtual pura, la clase derivada la hereda como funcin
virtual pura y se convierte tambin en clase abstracta. Por el contrario, aquellas clases
derivadas que redefinen todas las funciones virtuales puras de sus clases base reciben el
nombredeclasesderivadasconcretas,nomenclaturanicamenteutilizadaparadiferenciarlas
delasantesmencionadas.

Aparentementepuedeparecerquecarecedesentidodefinirunaclasedelaqueno
vaaexistirningnobjeto,perosepuedeafirmar,sinmiedoaequivocarse,quelaabstraccin
esunaherramientaimprescindibleparauncorrectodiseodelaProgramacinOrientadaa
Objetos.
Habitualmente las clases superiores de muchas jerarquas de clases son clases
abstractas y las clases que heredan de ellas definen sus propias funciones virtuales,
convirtindoseasenfuncionesconcretas.

No es posible crear objetos de una clase abstracta, estas clases slo se usan como
clasesbaseparaladeclaracindeclasesderivadas.
Las funciones virtuales puras sern aquellas que siempre se definirn en las clases
derivadas,demodoquenosernecesariodefinirlasenlaclasebase.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 5. EL POLIMORFISMO 169

A menudo se mencionan las clases abstractas como tipos de datos abstractos, en


ingls:AbstractDataType,oresumidoADT.
Como consecuencia de lo dicho se pueden resumir dos reglas a tener en cuenta
cuandoseutilizanclasesabstractas:

Noestpermitidocrearobjetosdeunaclaseabstracta.

Siemprehayquedefinirtodaslasfuncionesvirtualesdeunaclaseabstractaen
sus clases derivadas, no hacerlo as implica que la nueva clase derivada ser
tambinabstracta.
Para crear un ejemplo de clases abstractas, recurriremos de nuevo a nuestra clase
"Persona". Haremos que sta clase sea abstracta. De hecho, en nuestros programas de
ejemplonuncahemosdeclaradounobjeto"Persona".
Veamosunejemplo:
#include <iostream>
#include <cstring>
using namespace std;
class Persona {
public:
Persona(char *n) { strcpy(nombre, n); }
virtual void Mostrar() = 0;
protected:
char nombre[30];
};
class Empleado : public Persona {
public:
Empleado(char *n, int s) : Persona(n), salario(s) {}
void Mostrar() const;
int LeeSalario() const { return salario; }
void ModificaSalario(int s) { salario = s; }
protected:
int salario;
};
void Empleado::Mostrar() const {
cout << "Empleado: " << nombre
<< ", Salario: " << salario
<< endl;
}
class Estudiante : public Persona {
public:
Estudiante(char *n, float no) : Persona(n), nota(no) {}
void Mostrar() const;
float LeeNota() const { return nota; }
170 PROGRAMACIN C++ Y COMUNICACIONES.

void ModificaNota(float no) { nota = no; }


protected:
float nota;
};
void Estudiante::Mostrar() const {
cout << "Estudiante: " << nombre
<< ", Nota: " << nota << endl;
}
int main() {
Persona *Pepito = new Empleado("Jose", 1000); (1)
Persona *Pablito = new Estudiante("Pablo", 7.56);
char n[30];
Pepito->Mostrar();
Pablito->Mostrar();
cin.get();
return 0;
}

Lasalidaseras:

Empleado: Jose, Salario: 1000


Estudiante: Pablo, Nota: 7.56

Enesteejemplocombinamoselusodefuncionesvirtualespurasconpolimorfismo.
Fjate que, aunque hayamos declarado los objetos "Pepito" y "Pablito" de tipo puntero a
"Persona" (1), en realidad no creamos objetos de ese tipo, sino de los tipos "Empleado" y
"Estudiante".

5.5. Ejemplos

Como ejemplo se puede suponer que la cuenta_joven y la cuenta_empresarial ya


utilizadas y descritas anteriormente, con una forma distinta de abonar mensualmente el
intersalsaldo.

Enlacuenta_joven,noseabonarelinterspactadosielsaldoesinferiora
unlmite.

En la cuenta_empresarial se tienen tres cantidades lmite, a las cuales se


aplican factores de correccin en el clculo del inters. El clculo de la
cantidadabonadadeberealizarsedelasiguienteforma:

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 5. EL POLIMORFISMO 171

Sielsaldoesmenorque50000,seaplicaelintersestablecidopreviamente.

Si el saldo est entre 50000 y 500.000, se aplica 1.1 veces el inters


establecidopreviamente.

Si el saldo es mayor a 500.000, se aplica 1.5 veces el inters establecido


previamente.

Elcdigocorrespondientequedaradelasiguienteforma:

class C_Cuenta {
// Variables miembro
private:
double Saldo; // Saldo Actual de la cuenta
double Interes; // Inters calculado hasta el momento, anual,
// en tanto por ciento %
public:
//Constructor
C_Cuenta(double unSaldo=0.0, double unInteres=4.0)
{
SetSaldo(unSaldo);
SetInteres(unInteres);
}
// Acciones Bsicas
inline double GetSaldo()
{ return Saldo; }
inline double GetInteres()
{ return Interes; }
inline void SetSaldo(double unSaldo)
{ Saldo = unSaldo; }
inline void SetInteres(double unInteres)
{ Interes = unInteres; }
void Ingreso(double unaCantidad)
{ SetSaldo( GetSaldo() + unaCantidad ); }
virtual void AbonaInteresMensual()
{
SetSaldo( GetSaldo() * ( 1.0 + GetInteres() / 12.0 / 100.0) );
}
// etc...
};

class C_CuentaJoven : public C_Cuenta


{
public:
C_CuentaJoven(double unSaldo=0.0, double unInteres=2.0,
172 PROGRAMACIN C++ Y COMUNICACIONES.

double unLimite = 50.0E3) :C_Cuenta(unSaldo, unInteres)


{
Limite = unLimite;
}

virtual void AbonaInteresMensual()


{
if (GetSaldo() > Limite)
SetSaldo( GetSaldo() * (1.0 + GetInteres() / 12.0 / 100.0) );
else
SetSaldo( GetSaldo() );
}
private:
double Limite;
};

class C_CuentaEmpresarial : public C_Cuenta {


public:
C_CuentaEmpresarial(double unSaldo=0.0, double unInteres=4.0)
: C_Cuenta(unSaldo, unInteres)
{
CantMin[0] = 50.0e3;
CantMin[1] = 500.0e3;
}
virtual void AbonaInteresMensual()
{
SetSaldo( GetSaldo() * (1.0 + GetInteres() * CalculaFactor() /
12.0 / 100.0 ));
}
double CalculaFactor()
{
if (GetSaldo() < CantMin[0])
return 1.0;
else if (GetSaldo() < CantMin[1])
return 1.1;
else return 1.5;
}
private:
double CantMin[2];
};

UPM-EUITI-2015. Miguel Hernando.


Departamento de Electrnica Automtica e Informtica Industrial


174 PROGRAMACIN C++ Y COMUNICACIONES.

6. Plantillas

La generalidad es una propiedad que permite definir una clase o una funcin sin
tener que especificar el tipo de todos o alguno de sus miembros. Esta propiedad no es
imprescindible en un lenguaje de programacin orientado a objetos y ni siquiera es una de
sus caractersticas. Esta caracterstica del C++ apareci mucho ms tarde que el resto del
lenguaje, al final de la dcada de los ochenta. Esta generalidad se alcanza con las plantillas
(templates).
Lautilidadprincipaldeestetipodeclasesofuncionesesladeagruparvariablescuyo
tipo no est predeterminado. As el funcionamiento de una pila, una cola, una lista, un
conjunto,undiccionarioounarrayeselmismoindependientementedeltipodedatosque
almacene(int,long,double,char,uobjetosdeunaclasedefinidaporelusuario).Endefinitiva
estasclasessedefinenindependientementedeltipodevariablesquevayanaconteneryesel
usuario de la clase el que debe indicar ese tipo en el momento de crear un objeto de esa
clase.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 6. PLANTILLAS 175

6.1. Introduccin
Hemosindicadoqueenlaprogramacinclsicaexistaunaclaradiferenciacinentre
los datos y su manipulacin, es decir, entre los datos y el conjunto de algoritmos para
manejarlos. Los datos eran tipos muy simples, y generalmente los algoritmos estaban
agrupadosenfuncionesorientadasdeformamuyespecficaalosdatosquedebanmanejar.
Posteriormente la POO introdujo nuevas facilidades: La posibilidad de extender el
conceptodedato,permitiendoqueexistiesentiposmsComplejosalosquesepodaasociar
laoperatorianecesaria.Estanuevahabilidadfueperfiladaconunpardemejorasadicionales:
Laposibilidaddeocultacindedeterminadosdetallesinternos,irrelevantesparaelusuario,y
lacapacidaddeherenciasimpleomltiple.
Observe que las mejoras introducidas por la POO se pueden sintetizar en tres
palabras:Composicin,ocultacinyherencia.Deotrolado,laposibilidaddeincluirjuntos
los datos y su operatoria no era exactamente novedosa. Esta circunstancia ya exista de
formasubyacenteentodosloslenguajes.Recuerdequeelconceptodeentero(intenC)ya
incluyeimplcitamentetodounlgebrayreglasdeusoparadichotipo.Observetambinque
laPOOmantieneunparadigmadeprogramacinorientadoaldato(oestructurasdedatos).
De hecho los "Objetos" se definen como instancias concretas de las clases, y estas
representan nuevos tiposdedatos, de modo que POO es sinnimo de Programacin
OrientadaaTiposdedatos

Desde luego la POO supuso un formidable avance del arsenal de herramientas de


programacin. Incluso en algunos casos, un autntico baln de oxgeno en el desarrollo y
mantenimientodeaplicacionesmuygrandes,enlasqueseestabaenellmitedelofactible
conlastcnicasprogramacintradicional.Sinembargo,algunostericosseguancentraron
su atencin en los algoritmos. Algo que estaba ah tambin desde el principio. Se dieron
cuenta que frecuentemente las manipulaciones contienen un denominador comn que se
repite bajo apariencias diversas. Por ejemplo: La idea de ordenacin "Sort" se repite
infinidad de veces en la programacin, aunque los objetos a ordenar y los criterios de
ordenacin varen de un caso a otro. Alrededor de esta idea surgi un nuevo paradigma
denominadoprogramacingenricaofuncional.
La programacin genrica est mucho ms centrada en los algoritmos que en los
datosysupostuladofundamentalpuedesintetizarseenunapalabra:generalizacin.Significa
que, en la medida de lo posible, los algoritmos deben ser parametrizados al mximo y
expresadosdelaformamsindependienteposiblededetallesconcretos,permitiendoasque
puedanservirparalamayorvariedadposibledetiposyestructurasdedatos.
Los expertos consideran que la parametrizacin de algoritmos supone una
aportacin a las tcnicas de programacin, al menos tan importante, como fue en su
176 PROGRAMACIN C++ Y COMUNICACIONES.

momento la introduccin del concepto de herencia, y que permite resolver algunos


problemasqueaquellanopuederesolver.
Observe que la POO y la programacin genrica representan enfoques en cierta
formaortogonalesentresi:

Laprogramacinorientadaaldatorazonadelsiguientemodo:Representemos
untipodedatogenrico(porejemploint)quepermitarepresentarobjetoscon
ciertas caractersticas comunes (peras y manzanas por ejemplo). Definamos
tambinqueoperacionespuedenaplicarseaestetipo(porejemploaritmticas)
y sus reglas de uso, independientemente que el tipo represente peras o
manzanasencadacaso.

Por su parte la programacin funcional razona lo siguiente: Construyamos un


algoritmogenrico(porejemplosort),quepermitarepresentaralgoritmoscon
ciertascaractersticascomunes(ordenacindecadenasalfanumricasyvectores
porejemplo).Definamostambinaquetipospuedenaplicarseaestealgoritmo
y sus reglas de uso, independientemente que el algoritmo represente la
ordenacindecadenasalfanumricasovectores.
Con el fin de adoptar los paradigmas de programacin entonces en vanguardia,
desde sus inicios C++ haba adoptado conceptos de lenguajes anteriores. Uno de ellos, la
programacin estructurada , ya haba sido recogida en el diseo de su antecesor directo C.
TambinadoptlosconceptosdelaPOOentoncesemergente.Posteriormentehaincluido
otros conceptos con que dar soporte a los nuevos enfoques de la programacin funcional;
bsicamenteplantillasycontenedores.Lasplantillas,queseintrodujeronconlaversindel
Estndar de Julio de 1998 son un concepto tomado del Ada. Los contenedores no estn
definidosenelpropiolenguaje,sinoenlaLibreraEstndar.

6.2. Concepto de plantilla

Las plantillas ("Templates"), tambin denominadas tipos parametrizados, son un


mecanismoC++quepermitequeuntipopuedaserutilizadocomoparmetroenladefinicin
deunaclaseounafuncin.

Yasetratedeclasesofunciones,laposibilidaddeutilizaruntipocomoparmetroen
ladefinicin,posibilitalaexistenciadeentesdeniveldeabstraccinsuperioraldefuncino
claseconcreta.Podramosdecirquesetratadefuncionesoclasesgenricas;parametrizadas
(deahsunombre).Las"instancias"concretasdeestasclasesyfuncionesconformanfamilias
de funciones o clases relacionadas por un cierto "denominador comn", de forma que

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 6. PLANTILLAS 177

proporcionan un medio simple de representar gran cantidad de conceptos generales y un


mediosencilloparacombinarlos.
Parailustrarlointentaremosunaanaloga:silaclaseHeladodeFresarepresentara
losheladosdefresa,delosquelas"instancias"concretasserandistintostamaosyformatos
de helados de este sabor, una plantilla Heladode<tipo> sera capaz de generar las clases
Heladodefresa; Heladodevainilla; Heladodechocolate, etc. con solo cambiar
adecuadamente el argumento <tipo>. En realidad respondera al concepto genrico de
"Heladode". Las instancias concretas de la plantilla forman una familia de productos
relacionados (helados de diversos sabores). Forzando al mximo la analoga diramos
"especialidades".
ObservequeelmecanismodeplantillasC++esenrealidadungeneradordecdigo
parametrizado. La conjuncin de ambas capacidades: Generar tipos (datos) y cdigo
(algoritmos)lesconfiereunaextraordinariapotencia.Sibienelpropioinventordellenguaje
reconoce que a costa de "cierta complejidad", debida principalmente a la variedad de
contextosenlosquelasplantillaspuedenserdefinidasyutilizadas
Laideacentralaresaltaraquesqueunaplantillageneraladefinicindeunaclaseo
de una funcin mediante uno o varios parmetros. A esta instancia concreta de la clase o
funcinseladenominaunaespecializacinoespecialidaddelaplantilla.Unaspectocrucial
delsistemaesquelosparmetrosdelaplantillapuedenserasuvezplantillas.
Paramanejarestosconceptosutilizaremoslasiguienteterminologa:

Plantilladeclase(templateclass)osuequivalente:clasegenrica.

Plantilladefuncin(templatefunction)osuequivalente:funcingenrica.

Definida una plantilla, al proceso por el cual se obtienen clases especializadas (es
decirparaalgunodelostiposdedatosespecficos)sedenominainstanciacinodelaplantilla
o especializacin de una clase o mtodo genrico. A las funciones y clases generadas para
determinadostiposdedatosselasdenominaentoncescomoclasesofuncionesconcretaso
especializadas.

Comosehaindicado,lasplantillasrepresentanunadelasltimasimplementaciones
del lenguaje y constituyen una de las soluciones adoptadas por C++ para dar soporte a la
programacin genrica. Aunque inicialmente fueron introducidas para dar soporte a las
tcnicas que se necesitaban para la Librera Estndar (para lo que se mostraron muy
adecuadas),sontambinoportunasparamuchassituacionesdeprogramacin.Precisamente
la exigencia fundamental de diseo de la citada librera era lograr algoritmos con el mayor
grado de abstraccin posible, de forma que pudieran adaptarse al mayor nmero de
situacionesconcretas.
178 PROGRAMACIN C++ Y COMUNICACIONES.

Eltiempoparecedemostrarquesusautoresrealizaronunmagnficotrabajoqueva
ms all de la potencia, capacidad y versatilidad de la Librera Estndar C++ y de que otros
lenguajeshayan seguido la senda marcada por C++ en este sentido. Tal es el casode Java,
con su JGL ("Java Generic Library"). Lo que comenz como una herramienta para la
generacin parametrizada de nuevos tipos de datos (clases), se ha convertido por propio
derechoenunnuevoparadigma,lametaprogramacin(programasqueescribenprogramas).
De lo dicho hasta ahora puede deducirse, que las funciones y clases obtenidas a
partir de versiones genricas (plantillas), pueden obtenerse tambin mediante codificacin
manual (en realidad no se diferencian en nada de estas ltimas). Aunque en lo tocante a
eficaciaytamaodelcdigo,lasprimeraspuedancompetirenigualdaddecondicionescon
lasobtenidasmanualmente.Esto seconsigueporqueelusodeplantillasnoimplicaningn
mecanismo de tiempo de ejecucin. Las plantillas dependen exclusivamente de las
propiedades de los tipos que utiliza como parmetros y todo se resuelve en tiempo de
compilacin. Podramos pensar que su resolucin es similar a las macros de C en el que se
hacaunasustitucintextualdelaexpresinindicadaeneldefineporlaexpresinpuestaa
continuacin,peroenfuncindeunosparmetros.Deigualforma,cuandoseespecializauna
plantilla,seescribeelcdigoconlostipossustitudosporloindicadoenlaplantilla,ydespus
seprocedeacompilartantoelcdigoescritomanualmentecomoelescritoautomticamente
porestemecanismo.
Lasplantillasrepresentanunmtodomuyeficazdegenerarcdigo(definicionesde
funciones y clases) a partir de definiciones relativamente pequeas. Adems su utilizacin
permitetcnicasdeprogramacinavanzadas,enlasqueimplementacionesmuysofisticadas
semuestranmedianteinterfacesqueocultanalusuariolacomplejidad,mostrndolasoloen
la medida en que necesite hacer uso de ella. De hecho, cada una de las potentes
abstraccionesqueseutilizanenlaLibreraEstndarestrepresentadacomounaplantilla.A
excepcin de algunas pocas funciones, prcticamente el 100% de la Librera Estndar est
relacionada con las plantillas, de ah que hasta ahora nose halla hecho mucha referenciaa
estalibrerapertenecientealestndardeC++.

Lapalabraclavetemplate

C++utilizaunapalabraclaveespecficatemplateparadeclararydefinirfuncionesy
clases genricas. En estos casos acta como un especificador de tipo y va unido al par de
ngulos<>quedelimitanlosargumentosdelaplantilla:
template <T> void fun(T& ref); // funcin genrica
template <T> class C {/*...*/}; // clase genrica

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 6. PLANTILLAS 179

Enalgunasotras(raras)ocasioneslapalabratemplateseutilizacomocalificadorpara
indicar que determinada entidad es una plantilla (y en consecuencia puede aceptar
argumentos)cuandoelcompiladornopuedededucirloporsmismo.
Bien,puesunavezexpuestaslasideasprincipalesreferentesalconceptodeplantilla,
vamos a ver en primer lugar como se realzan funciones genricas, para despus explicar el
conceptoyelmododefuncionamientodelasclasesgenricas.

6.3. Plantillas de funciones

Para ilustrar grficamente su utilidad utilizaremos un ejemplo clsico: queremos


construir unafuncin max(a, b) que pueda utilizarse para obtener elmayor de dosvalores,
suponiendoqueestosseandecualquiertipocapazdeserordenado,esdecir,cualquiertipo
enelquesepuedaestableceruncriteriodeordenacin(establecemosa>bsiaestdespus
quebenelorden).

El problema que presenta C++ para esta propuesta es que al ser un lenguaje
fuertementetipado,ladeclaracincmax(a,b)requiereespecificareltipodeargumentosy
valordevuelto.Enrealidadserequierealgoas:

tipoTmax(tipoTa,tipoTb);
y la sintaxis del lenguaje no permite que tipoT sea algo variable. Una posible
solucin es sobrecargar la funcin max(), definiendo tantas versiones como tipos distintos
debamosutilizar.
double max(double a,double b){return a>b?a:b;}
int max(int a,int b){return a>b?a:b;}

Otraalternativaserautilizarunamacro:
#define max(a, b) ((a > b) ? a : b)
peroestopresentasusinconvenientes.Empezandoporquesuutilizacinpermitira
comparar un entero con una estructura o una matriz, algo que est claramente fuera del
propsitodelafuncinquepretendemos.
La solucin al problema enunciado es utilizar una funcin genrica (plantilla). La
sintaxisdesudefinicineslasiguiente:
template <class T> T max(T a, T b)
{
return (a > b) ? a : b;
}

180 PROGRAMACIN C++ Y COMUNICACIONES.

<classT>eslalistadeparmetros.Representael/losparametrosdelaplantilla.Los
parmetrosdeunaplantillafuncionaenciertaformacomolosargumentosdeunamacro(el
trabajodeestamacroesgenerarcdigodefunciones).Esimportantesignificarqueutilizamos
dosconceptosdistintos(aunquerelacionados):losparmetrosdelaplantilla(contenidosen
la lista template <....> ) y los argumentos de la funcin (argumentos con que se invoca la
funcinencadacasoconcreto).
Lomismoqueenlasfuncionesexplcitas,lasgenricaspuedenserdeclaradasantes
desuutilizacin:
template <class T> T max(T, T);

ydefinidasdespus:
template <class T> T max(T a, T b)
{
return (a > b) ? a : b;
}

La idea fundamental es que el compilador deduce los tipos concretos de los


parmetros de la plantilla de la inspeccin de los argumentos actuales utilizados en la
invocacin . Por ejemplo, la plantilla anterior puede ser utilizada mediante las siguientes
sentencias:
int i, j;
UnaClase a, b;
...
int k = max(i, j); // (1)
UnaClase c = max(a, b); // (2)

En(1)losargumentosdelafuncinsondosobjetostipoint;mientrasen(2)sondos
objetos tipo UnaClase. El compilador es capaz de construir dos funciones aplicando los
parmetrosadecuadosalaplantilla.Enelprimercaso,elparmetroesunint;enelsegundo
un tipo UnaClase. Como veremos ms adelante, es de la mxima importancia que el
compilador sea capaz de deducir los parmetros de la plantilla a partir de los argumentos
actuales (los utilizados en cada invocacin de la funcin), as como las medidas sintcticas
adoptadascuandoestonoesposibleporproducirseambigedad.
Unafuncingenricapuedetenermsargumentosquelaplantilla.Porejemplo:
template <class T> void func(T, inf, char, long, ...);

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 6. PLANTILLAS 181

Tambinpuedetenermenos:
template <class T> void func();

La forma de operar en este caso para que el compilador deduzca el parmetro
correcto T a utilizar en la plantilla, se muestra ms adelante cuando se hable de la
especificacinexplcitadelosargumentosdeunaplantilla.
Llegadosaestepuntoesconvenientehaceralgunasobservacionesimportantes:

Las funciones genricas son entes de nivel de abstraccin superior a las funciones
concretas (en este contexto preferimos llamarlas funciones explcitas), pero las funciones
genricassolotienenexistenciaenelcdigofuenteyenlamentedelprogramador.Hemos
dichoqueelmecanismodeplantillasC++seresuelveentiempodecompilacin,demodoque
enelejecutable,ydurantelaejecucin,noexistenadaparecidoaunafuncingenrica,solo
existenespecializaciones(instanciasdelafuncingenrica).

Esta caracterstica de las funciones genricas es de la mayor importancia. Supone


quepuedenescribirsealgoritmosmuygenricosenlosquelosdetallesdependendeltipode
objeto con el que se utiliza (el algoritmo). En nuestro ejemplo, el criterio que define que
objetoaobesmayor,noestcontenidoenlafuncinmax(),sinoenlapropiaclaseaque
pertenecen ambos objetas en donde ha debido sobrecargarse el operador > para ese tipo
concreto.Estaesjustamentelapremisafundamentaldelaprogramacingenrica.
La instanciacin de la plantilla se produce cuando el compilador encuentra que es
necesaria una versin concreta (especialidad) de la funcin genrica. Esto sucede cuando
existeunainvocacincomoenelejemplo,lalnea(2),osetomaladireccindelafuncin
(porejemploparainiciarunpunteroafuncin).Entoncessegeneraelcdigoapropiadoen
concordanciaconeltipodelosargumentosactuales.

Ocurrequesiestainstanciaaparecemsdeunavezenunmdulo,oesgenerada
enmsdeunmdulo,elenlazadorlasrefundeautomticamenteenunasoladefinicin,de
formaquesoloexistaunacopiadecadainstancia.Dichoenotraspalabras:enlaaplicacin
resultante solo existir una definicin de cada funcin. Por contra, si no existe ninguna
invocacinnosegeneraningncdigo.
Aunque la utilizacin de funciones genricas conduce a un cdigo elegante y
reducido,quenosecorrespondeconelresultadofinalenelejecutable.Silaaplicacinutiliza
muchasplantillasconmuchostiposdiferentes,elresultadoeslageneracindegrancantidad
decdigoconelconsiguienteconsumodeespacio.Estacrecimientodelcdigoesconocida
como "Code bloat", y puede llegar a ser un problema. En especial cuando se utilizan las
plantillas de la Librera Estndar, aunque existen ciertas tcnicas para evitarlo. Como regla
182 PROGRAMACIN C++ Y COMUNICACIONES.

general,lasaplicacionesquehaceusoextensivodeplantillasresultangrandesconsumidoras
dememoria(eselcostodelacomodidad).
Puesto que cada instancia de una funcin genrica es una verdadera funcin, cada
especializacindisponedesupropiacopiadelasvariablesestticaslocalesquehubiese.Se
les pueden declarar punteros y en general gozan de todas las propiedades de lasfunciones
normales,incluyendolacapacidaddesobrecarga
VeamosuncasoconcretoconunafuncingenricaqueutilizatantounaclaseVector
comounentero:
#include <iostream.h>
class Vector
{
public:
float x, y;
bool operator>(Vector v)
{
return ((x*x + y*y) > (v.x*v.x + v.y*v.y))? true: false;
}
};
template<class T> T max(T a, T b){ return (a > b) ? a : b;}

void main()
{
Vector v1 = {2, 3}, v2 = {1, 5};
int x = 2, y = 3;
cout <<"Mayor: "<<max(x, y)<< endl;
cout <<"Mayor:"<<max(v1, v2).x<<", "<<max(v1,v2).y << endl;
}

Elresultadodeejecutarelprogramaeselsiguiente:

Mayor:3

Mayor:1,5


Otro ejemplo clsico en la definicin de una plantilla de funcin es el caso de la
funcinpermutar:
#include <iostream.h>
template <class S> void permutar(S&, S&);
void main(void)
{

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 6. PLANTILLAS 183

int i=2, j=3;


cout << "i=" << i << " " << "j=" << j << endl;
permutar(i, j);
cout << "i=" << i << " " << "j=" << j << endl;
double x=2.5, y=3.5;
cout << "x=" << x << " " << "y=" << y << endl;
permutar(x, y);
cout << "x=" << x << " " << "y=" << y << endl;
}
template <class S> void permutar(S& a, S& b)
{
S temp;
temp = a;
a = b;
b = temp;
}

Otro ejemplo, es el de la realizacin de un algoritmo de ordenacin por seleccin
directa.Enestecasoseharusodelafuncingenricapermutar.Observesequeacausade
ello, el numero de funciones generadas automticamente pasa a ser cuatro. Si se
implementase el cdigo de la funcin genrica permutar directamente en el interior de la
funcingenricaordenar,elnmerodefuncionesgeneradasautomticamentehubierasido
lamitad:
#include <iostream.h>
template <class S> void permutar(S& a, S& b);
template <class T> void ordenar (T *vector, int num);

void main(void)
{

float mivector[10]={2,4,6,8,1,3,5,7,9,0};
char cadena[10]="efghBACDI";

ordenar(mivector,8);
ordenar(cadena,10);

for(i=0;i<10;i++)cout<<mivector[i];
cout<<endl<<cadena;
}

template <class S> void permutar(S &a, S &b)


{
S temp;
temp = a;
184 PROGRAMACIN C++ Y COMUNICACIONES.

a = b;
b = temp;
}
template <class T> void ordenar (T *vector, int num)
{
int i,j;
for(i=0;i<num-1;i++)
for(j=i+1;j<num;j++)
if(vector[i]<vector[j])permutar(vector[i],vector[j]);
}

Metodos genricos
Lasfuncionesgenricaspuedensermiembros(mtodos)declases:
class A
{
template<class T> void func(T& t) // def de mtodo genrico
{
...
}
...
}

La definicin de mtodos genricos puede hacerse tambin fuera del cuerpo de la


clase como con cualquier otro mtodo, mediante el uso del operador de resolucin de
mbito:
class A
{
template<class T> void func(T& t);//decl mtodo genrico
...
}
...
template <class T> void A::func(T& t) //definicin del mtodo
{
// cdigo del mtodo...
}

Aunqueannosehanexplicadolasclasesgenricas,esconvenienteindicaryaque
los miembros genricos pueden ser a su vez miembros de clases genricas, en cuyo caso
pueden hacer uso de los parmetros de la plantilla de clase genrica. Un ejemplo de un
mtodogenricoeselsiguiente:
#include <iostream.h>

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 6. PLANTILLAS 185

class A
{
public:
int x;
template<class T> void fun(T t1, T t2);
A (int a = 0) { x = a; }
};

template<class T> void A::fun(T t1, T t2)


{ cout << "Valor-1: " << t1
<< ", Valor-2: " << t2
<< ", Valor-x: " << x << endl;
}

void main(void)
{
A a(7), b(14);
a.fun(2, 3);
b.fun('x', 'y');
}

Salida:

Valor1:2,Valor2:3,Valorx:7

Valor1:x,Valor2:y,Valorx:14

Parmetros de la plantilla
Ladefinicindelafuncingenricapuedeincluirmsdeunargumento.Esdecir,el
especificador template <...> puede contener una lista con varios tipos. Estos parmetros
puedensertiposComplejosofundamentales,porejemplounint;inclusoespecializacionesde
clasesgenricasyconstantesdetiempodecompilacin.

Engenerallosparmetrosdeunaplantillapuedenser:

Identificadoresdetipo,porejemploT.Estosparmetrosvanprecedidospor
lapalabrareservadaclassotypename:
template<classA,classB>voidfunc(A,B);

template<typenameA,typenameB>voidfunc(A,B);
186 PROGRAMACIN C++ Y COMUNICACIONES.

Plantillasdeclases(adelantandodenuevo):
template<classA,template<classt>classX>voidfunc(A,X<T>);

Parmetrosdealgnotrotipo:primitivo,derivado,definidoporelusuario,
o de plantilla. Un parmetro de plantilla que no sea un tipo, es una
constantedentrodelaplantilla,yporlotanto,nosepuedemodificar.

template<classA,intx>voidfunc(A,int);
template<classT,intp>Tfx(Tx);

Un ejemplo que ilustra este ltimo caso, es el siguiente en el que se utilizan dos
plantillasmuyparecidasdesdeelpuntodevistadeuso,perodiferentesencuantoalcdigo
compiladoeselsiguiente:
#include <iostream.h>

template <class T, int ind> void imprime(T* v)


{
for(int i=0;i<ind;i++)cout<<v[i];
}
template <class T> void imprime2(T* v,int ind)
{
for(int i=0;i<ind;i++)cout<<v[i];
}
void main()
{
float vector[3]={1,2,3};
char cadena[]="Hola Mundo";
imprime<float,3>(vector); //(1)
imprime<char,8>(cadena);
imprime2(vector,2);
imprime2(cadena,5);
}


Losargumentosalaplantilladelasfuncionesgenricasnopuedentenervalorespor
defecto. Lo mismo que en las funciones explcitas, en las funciones genricas debe existir
concordanciaentreelnmeroytipodelosargumentosformalesyactuales.

template <class A, int x> void func(A, int);
...

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 6. PLANTILLAS 187

func(T); // Error!! falta 1 argumento



Evidentemente los parmetros de la funcin, no afectados por la plantilla, si que
puedentenervalorespordefecto.Porejemplo,lafuncinimprime2podraserreescritadela
formasiguiente:

template <class T> void imprime2(T* v,int ind=2)
{
for(int i=0;i<ind;i++)cout<<v[i];
}

yalahoradeejecutarsepodraentoncesescribirse:


imprime2(vector);

Como se observa en el ejemplo, todos los argumentos formales de la plantilla


(contenidos en la lista template <....> ) deberan estar representados en los argumentos
formalesdelafuncin.Denoseras,nohabraposibilidaddededucirlosvaloresdelostipos
de la lista <....> salvo que se indique explcitamente cuando se produzca una invocacin
especfica de la funcin por medio del uso de <> como en la lnea (1) del ejemplo de
imprime.
Elsiguientecdigoportantodaraerrorenlacompilacin:
template <class A, class B> void func(A a) { // Plantilla
...
};
...
func(a); // Error de compilacin !!

EnestecasoelcompiladornotieneposibilidaddededucireltipodelargumentoB.
Enocasioneseldiseodelafuncinnopermitedeterminareltipodeparmetrode
la plantilla a partir de los argumentos actuales de la invocacin (o sencillamente se quiere
obligaralcompiladoraaplicarlosargumentosactualesaunaespecializacininstanciadacon
unosparmetrosconcretos).Porejemplo:
template <class T> T* construir ()
{
T *aux=new T;
188 PROGRAMACIN C++ Y COMUNICACIONES.

if(aux==NULL)
{
cout<<Error de construccin;
abort();
}
return aux;
}


Laplantillaanteriorcreaunobjetodecualquiertipoydevuelveunpunteroalobjeto
creado, o aborta el programa en caso de no haber podido crearlo. Se observa que el
compilador no puede deducir el tipo de parmetro a utilizar con la plantilla a partir del
argumentoactual,puestoqueenestecasonohayargumentoactual.Lasiguientelneasera
errnea:
int* iptr = construir();

Elcompiladorarrojaraelmensaje:ERROR,parmetroTdesconocido.
Para su utilizacin debe especificarseexplcitamente el tipode parmetro a utilizar
medianteunargumentodeplantilla:
int* iptr = construir<int>();

La gramtica del lenguaje exige que cuando el argumento de la plantilla solo es


utilizado por la funcin en el tipo de retorno, debe indicarse explcitamente que tipo de
instanciacin se pretende mediante la inclusin de parmetros de plantilla <...> entre el
nombredelafuncinylalistadeargumentos:funcin<...> (...).Estoescoherenteconel
modo de comportarse gramaticalmente el compilador con las funciones sobrecargadas.
Recurdesequeparaestasfunciones,ladiferenciacinentrelasmismasnopuederealizarse
pormediodeltipodelafuncinoderetorno.

Estaformadeinstanciarunaplantillasedenominainstanciacinimplcitaespecfica
delaplantillaoespecificacinexplcitadelosparmetrosdelaplantilla,yenestoscasosla
lista <...> que sigue al nombre de la funcin genrica puede incluir los parmetros de la
plantilla que sean necesarios. Esta lista no tiene porqu incluir a todos los parmetros
actualmente utilizados por la plantilla, ya que el compilador la completa con los tipos que
puedan deducirse de la lista de argumentos de la funcin. Sin embargo, los parmetros
faltantes deben ser los ltimos de la lista <...> (anlogo a lo exigido a los argumentos por
defectoenlasfuncionesexplcitas).Porejemplo:
template <class A, class B, class C> void func(B b, C c, int i);

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 6. PLANTILLAS 189

....
func(b, c, i); // Error!!
func <A, B, C>(b, c, i); // Ok. B y C redundantes
func<A>(b, c, i); // Ok.
func<A>(b, c); // Error!! falta argumento i

Un aspecto crucial de las funciones genricas es que el compilador debe poder
deducir sin ambigedad los argumentos de la plantilla a partir de los argumentos utilizados
paralainvocacindelafuncin.
Recordemos que en los casos de sobrecarga, la invocacin de funciones C++ utiliza
un sistema estndar para encontrar la definicin que mejor se adapta a los argumentos
actuales.Tambinserealizantransformacionesautomticascuandolosargumentospasados
a la funcin no concuerdan exactamente con los esperados (argumentos formales) Estos
mecanismosutilizanunasreglasdenominadascongruenciaestndardeargumentos

Encasodelasplantillasdefuncinofuncionesgenricas,elcompiladordeducelos
parmetrosdelaplantillamedianteelanlisisdelosargumentos actuales de la invocacin,
peroparaestosolorealizaconversionestriviales(menossignificativasquelasrealizadascon
lasfuncionesexplcitas).Lossiguientesejemplospuedenayudarailustrarestasconversiones
tantoparaunafuncingenricacomoparaunanormaloexplcita:
template<class T> bool igual(T a, T b)
{
return (a == b) ? true : false;
}
bool desigual(double a, double b)
{
return (a == b) ? false : true;
}
...
int i;
char c;
double d;
...
igual(i, i); // Ok. invoca igual(int ,int)
igual(c, c); // Ok. invoca igual(char,char)
igual(i, c); // Error!! igual(int,char) indefinida
igual(c, i); // Error!! igual(char,int) indefinida
desigual(i, i) // Ok. conversin de argumentos efectuada
desigual(c, c) // Ok. conversin de argumentos efectuada
desigual(i, c) // Ok. conversin de argumentos efectuada
desigual(d, d) // Ok. concordancia de argumentos

190 PROGRAMACIN C++ Y COMUNICACIONES.

Sobrecarga de funciones genricas

Hemossealadoquelainstanciacindelaplantillaserealizacuandoelcompilador
encuentraunainvocacindelafuncingenricaoseobtienesudireccinyquesolopuede
existirunaversindecadaespecializacindelafuncingenrica.Estaspremisasconducena
queseaposibleevitarlageneracinautomticaparaunoovariostiposconcretos,mediante
dosprocedimientos:

Proporcionando una versin codificada de forma "manual" de la funcin


(versin explcita ). Es decir escribiendo el cdigo de la funcin con los
parmetrosespecificadosnormalmente.

Forzarunainstanciacinespecficadelaplantilla(instanciacinexplcita),de
forma que se genera el cdigo de una especialidad concreta, con
independencia de que posteriormente se requiera o no, la utilizacin del
cdigogenerado.Lainstanciacinpuederealizarsededosformas:
o Forzar la instanciacin de la plantilla "tal cual" para un tipo
particular. Esta instancia explcita tendra el comportamiento
genrico definido en la plantilla, por lo que la denominamos
instanciacinexplcitageneral.
o Forzar una instanciacin para un tipo particular en las mismas
condiciones que el anterior (con independencia de la posible
utilizacin del cdigo generado en el programa), pero definiendo
un nuevo comportamiento, distinto del general definido en la
plantilla. En otras palabras: instanciar una versin sobrecargada
de la funcin para un tipo especfico. La denominamos
instanciacinexplcitaparticular.

Como veremos a continuacin, estas posibilidades tienen distinta utilidad y ligeras
diferencias de detalle. Aunque son tcnicas diferentes, el resultado final es anlogo: la
existencia de una (o varias) especializaciones concretas de la funcin, lo que nos obligar a
contemplarunageneralizacindelasobrecargadefuncionesqueincluyafuncionesexplcitas
ygenricas.

Con independencia de la explicacin ms detallada que sigue, para situarnos en el


temaadelantamosunesbozodeloquesignificalaliteraturaanteriorreferidaauncasomuy
sencillo:
// funcin genrica (declaracin)

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 6. PLANTILLAS 191

template<class T> T max(T, T);


...
// funcin genrica (definicin)
template<class T> T max(T a, T b) { return (a > b) ? a : b; }
...
// versin explcita
char max(char a, char b) { return (a >= b) ? a : b; }
...
// instanciacin explcita general
template long max<long>(long a, long b);
...
// instanciacin explcita particular
template<> double max<double>(double a, double b)
{ return (a >= b) ? a : b; };
...
// instanciacin implcita especfica
int x = max<int>(x, 'c');

Para entrar con mayor profundidad en el tema , considere un caso en el que


utilizamosunafuncingenricaigual()paracomprobarsidosobjetossoniguales,yalacual
iremosaplicandocadaunodeloscasosanteriores:

#include <iostream.h>

class Vector
{
public:
float x, y;
Vector(float a,float b):x(a),y(b){}
bool operator==(const Vector& v)
{
return ( x == v.x && y == v.y)? true : false;
}
};
template<class T> bool igual(T a, T b) funcin genrica
{
return (a == b) ? true : false;
}

void main()
{
192 PROGRAMACIN C++ Y COMUNICACIONES.

Vector v1(2, 3), v2 (1, 5);


int x = 2, y = 3;
double d1 = 2.0, d2 = 2.2;

if ( igual(v1, v2) ) cout << "vectores iguales" << endl;


else cout << "vectores distintos" << endl;
if ( igual(d1, d2) ) cout << "doubles iguales" << endl;
else cout << "doubles distintos" << endl;
if ( igual(x, y) ) cout << "enteros iguales" << endl;
else cout << "enteros distintos" << endl;
}

Lasalidadeesteprograma,comoeradeesperareslasiguiente:
vectoresdistintos

doublesdistintos

enterosdistintos

Hasta aqu nada nuevo: el compilador ha generado y utilizado correctamente las


especializacionesdeigual()paralasinvocacionescontiposint,doubleyVector.

Versin explcita
Consideremos ahora que es necesario rebajar la exigencia para que dos variables
sean consideradas iguales en el caso de que sean doubles. Para ello introducimos una
instancia de igual codificada manualmente en el que reflejamos la nueva condicin de
igualdad:


#include <iostream.h>

class Vector
{
public:
float x, y;
Vector(float a,float b):x(a),y(b){}
bool operator==(const Vector& v)
{
return ( x == v.x && y == v.y)? true : false;
}
};
template<class T> bool igual(T a, T b)

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 6. PLANTILLAS 193

{
return (a == b) ? true : false;
};
bool igual(double a, double b) // versin explcita
{
return (labs(a-b) < 1.0) ? true : false;
};
void main()
{
Vector v1(2, 3), v2 (1, 5);
int x = 2, y = 3;
double d1 = 2.0, d2 = 2.2;

if ( igual(v1, v2) ) cout << "vectores iguales" << endl;


else cout << "vectores distintos" << endl;
if ( igual(d1, d2) ) cout << "doubles iguales" << endl;
else cout << "doubles distintos" << endl;
if ( igual(x, y) ) cout << "enteros iguales" << endl;
else cout << "enteros distintos" << endl;
}
Salida:

vectoresdistintos

doublesiguales

enterosdistintos

Laversinexplcitaparatiposdoubleutilizalafuncindelibreralabsparaconseguir
que dos doubles sean considerados iguales si la diferencia es solo en los decimales. La
inclusin de esta definicin supone que el compilador no necesita generar una versin de
igual()cuandolosparmetrossontipodouble.Enestecaso,elcompiladorutilizalaversin
suministrada"manualmente"porelprogramador.
Adems de permitir introducir modificaciones puntuales en el comportamiento
general, las versiones explcitas pueden utilizarse tambin para eliminar algunas de las
limitacionesdelasfuncionesgenricas.
Porejemplo,sisustituimoslasentencia:
if ( igual(d1, d2) ) cout << "doubles iguales" << endl;
por:
if ( igual(d1, y) ) cout << "doubles iguales" << endl;
194 PROGRAMACIN C++ Y COMUNICACIONES.

Seobtieneunerrordecompilacin:Couldnotfindamatchfor'igual<T>(double,int)'.
Laraznesque,comohemosvisto,elcompiladornorealizaningntipodeconversinsobre
eltipodelosargumentosutilizadosenlasfuncionesgenricas,yenestecasonoexisteuna
definicin de igual() que acepte un double y un int. En cambio, la misma sustitucin de
cuando existe una versin explcita para igual(double double), no produce ningn error. La
razn es que para las funciones normales el compilador si es capaz de realizar
automticamente determinadas transformaciones de los argumentos actuales para
adecuarlosalosesperadosporlafuncin.

Instanciacin explcita general


El estndar ha previsto un procedimiento para obligar al compilador a generar el
cdigo de una especializacin concreta a partir de la plantillafuncin. Esta instanciacin
forzada se denomina instanciacin explcita, y utiliza el especificador template aislado (sin
estarseguidode<...>).Recuerdequeladefinicindelaplantillaiguales:
template<class T> bool igual(T a, T b) {...}
La sintaxis para generar una versin de igual especfica para doubles sera la
siguiente:
template bool igual<double>(double a, double b);

Observelasintaxisutilizada:lalistadeparmetros<...>sehacambiadodeposicin
respectoaladeclaracindelaplantilla.

La inclusin de una instanciacin explcita como la anterior (la llamaremos general


porque sigue el comportamiento general definido por la plantilla), origina la aparicin del
cdigocorrespondiente a la especializacin solicitada aunque en el programa no exista una
necesidad real (invocacin)de dichocdigo. Esta instancia explcitageneral desempea un
papelanlogoaldeunaversinquesehubiesecodificadomanualmente(versinexplcita).

Instanciacin explcita particular


Observe que la versin instanciada en la expresin anterior es concordante con la
plantilla,porloquenosirvepararealizarmodificacionesespecficascomolasrealizadasenel
ejemplo anterior en el caso de los float. Sin embargo, es posible tambin especificar una
definicinparticularparalaespecialidadqueseinstanciaaadiendoelcuerpoadecuado.A
estaversinladenominamosinstanciaexplcitaparticular.
Lasintaxisserialasiguiente:
template<> bool igual<double>(double a, double b)
{

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 6. PLANTILLAS 195

return (labs(a-b) < 1.0) ? true : false;


}
Los ngulos <> despus de template indican al compilador que sigue una
especializacin particular de una plantilla definida previamente. Como puede figurarse el
lector,elresultadoessimilaralqueseobtendraunaversinexplcita.
Esunerrorintentarlaexistenciademsdeunadefinicinparalamismafuncin,ya
seaestaunainstanciacinimplcita,explcitaounaversincodificadamanualmente.
Porejemplo:
bool igual(double& a, double& b)
{
return (labs(a-b) < 1.0) ? true : false;
};

template bool igual<double>(double& a, double& b);


Enlascondicionesanterioreselcompiladorpuedegenerarunerror,unaadvertencia,
o sencillamente ignorar el segundo requerimiento, ya que previamente existe una versin
explcitadelafuncinconidnticafirma.Encualquiercasoesunareglaqueelcompilador
dar preferencia a una funcin normal (versin explcita) sobre cualquier forma de
instanciacin,explcitaoimplcita,alutilizarunafuncin.

6.4. Clases genricas

Hemos indicado alcomienzodel captulo que las clasesplantilla,clasesgenricaso


generadores de clases, son un artificio C++ que permite definir una clase mediante uno o
variosparmetros.Estemecanismoescapazdegenerarladefinicindeclases(instanciaso
especializaciones de la plantilla) distintas, pero compartiendo un diseo comn. Podemos
imaginar que una clase genrica es un constructor de clases, que como tal acepta
determinados argumentos (no confundir con el constructor deunaclase, que genera
objetos).
Para ilustrarlo veremos la clase mVector. Los objetos mVector son matrices cuyos
elementossonobjetosdelaclaseVector;queasuvezrepresentanvectoresdeunespaciode
dosdimensiones.
Eldiseobsicodelaclaseescomosigue:
196 PROGRAMACIN C++ Y COMUNICACIONES.

class mVector
{
int dimension;
public:
Vector* mVptr;
mVector(int n = 1)
{
dimension = n;
mVptr = new Vector[dimension];
}
~mVector() { delete [] mVptr; }
Vector& operator[](int i) { return mVptr[i]; }
void mostrar(int);
};
void mVector::mostrar (int i)
{
if((i >= 0) && (i <= dimension)) mVptr[i].mostrar();
}

Elsistemadeplantillaspermitedefinirunaclasegenricaqueinstancieversionesde
mVectorparamatricesdecualquiertipoespecificadoporunparmetro.Laventajadeeste
diseo parametrizado, es que cualquiera que sea el tipo de objetos utilizados por las
especializaciones de la plantilla, las operaciones bsicas son siempre las mismas (insercin,
borrado,seleccindeunelemento,etc).

Definicin de una clase genrica

Ladefinicindeunaclasegenricatieneelsiguienteaspecto:
template<lista-de-parametros> class nombreClase
{
...
};

Una clase genrica puede tener una declaracin adelantada (forward) para ser
declaradadespus:

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 6. PLANTILLAS 197

template<lista-de-parametros> class nombreClase;


...
template<lista-de-parametros> class nombreClase
{
...
};
pero recuerde que debe ser definida antes de su utilizacin y evidentemente, solo
puededefinirseunavez.

Observequeladefinicindeunaplantillacomienzasiemprecontemplate<...>,yque
losparmetrosdelalista<...>nosonvalores,sinotiposdedatos.
Ladefinicindelaclasegenricacorrespondientealcasoanterioreslasiguiente:
template<class T> class mVector
{
int dimension;
public:
T* mVptr;
mVector(int n = 1)
{
dimension = n;
mVptr = new T[dimension];
}
~mVector() { delete [] mVptr; }
T& operator[](int i) { return mVptr[i]; }
void mostrar (int);
};

template<class T> void mVector<T>::mostrar (int i)


{
if((i >= 0) && (i <= dimension)) mVptr[i].mostrar();
}

Observequeapartedelcambiodeladeclaracin,sehansustituidolasocurrenciasde
Vector(untipoconcreto)porelparmetroT.Observetambinladefinicindemostrar()que
serealizaofflineconlasintaxisdeunafuncingenrica.
Recordemosqueenestasexpresiones,elespecificadorclasspuedesersustituidopor
typename,deformaquelaprimeralneapuedesersustituidapor:

template<typename T> class mVector


198 PROGRAMACIN C++ Y COMUNICACIONES.

{
...
};

Veamoselejemplocompleto:
#include <iostream.h>
class Vector
{
public:
int x, y;
Vector& operator= (const Vector& v)
{
x = v.x; y = v.y;
return *this;
}
void mostrar(){cout << "X = " << x << "; Y = " << y << endl;}
};

template<class T> class mVector


{
int dimension;
public:
T* mVptr;
mVector& operator=(const mVector& mv)
{
delete [] mVptr;
dimension = mv.dimension;
mVptr = new T[dimension];
for(int i = 0; i<dimension; i++)
mVptr[i]= mv.mVptr[i];
return *this;
}
mVector(int n = 1)
{
dimension = n;
mVptr = new T[dimension];
}
~mVector() {delete [] mVptr;}
mVector(const mVector& mv)
{
dimension = mv.dimension;
mVptr = new T[dimension];
for(int i = 0; i<dimension; i++)
mVptr[i]= mv.mVptr[i];

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 6. PLANTILLAS 199

T& operator[](int i) { return mVptr[i]; }


void mostrar (int);
void mostrar ();
};

template <class T> void mVector<T>::mostrar (int i)


{
if((i >= 0) && (i < dimension)) mVptr[i].mostrar();
}
template <class T> void mVector<T>::mostrar ()
{
cout << "Matriz de: " << dimension << " elementos." << endl;
for (int i = 0; i<dimension; i++)
{
cout << i << "- ";
mVptr[i].mostrar();
}
}

void main()
{
mVector<Vector> mV1(5);
mV1[0].x = 0; mV1[0].y = 1;
mV1[1].x = 2; mV1[1].y = 3;
mV1[2].x = 4; mV1[2].y = 5;
mV1[3].x = 6; mV1[3].y = 7;
mV1[4].x = 8; mV1[4].y = 9;
mV1.mostrar();
mVector<Vector> mV2 = mV1;
mV2.mostrar();
mV1[0].x = 9; mV1[0].y = 0;
mV2.mostrar(0);
mV1.mostrar(0);
mVector<Vector> mV3(0);
mV3.mostrar();
mV3 = mV1;
mV3.mostrar();
}

Salida:
Matriz de: 5 elementos.
0 - X = 0; Y = 1
1 - X = 2; Y = 3
2- X = 4; Y = 5
3- X = 6; Y = 7
200 PROGRAMACIN C++ Y COMUNICACIONES.

4- X = 8; Y = 9
Matriz de: 5 elementos.
0- X = 0; Y = 1
1- X = 2; Y = 3
2- X = 4; Y = 5
3- X = 6; Y = 7
4- X = 8; Y = 9
X = 0; Y = 1
X = 9; Y = 0
Matriz de: 0 elementos.
Matriz de: 5 elementos.
0- X = 9; Y = 0
1- X = 2; Y = 3
2- X = 4; Y = 5
3- X = 6; Y = 7
4- X = 8; Y = 9

Otroejemploquedescribeunaclasegenricaparalarealizacindeunapiladedatos
sin que se utilicen listas enlazadas y reserva dinmica de memoria adicional durant
funcionmientodeunobjetodeunaclaseinstanciadaeselsiguiente:

// fichero Pila.h
template <class T>
// declaracin de la clase
class Pila
{
public:
Pila(int nelem=10); // constructor
void Poner(T);
void Imprimir();
private:
int nelementos;
T* cadena;
int limite;
};
// definicin del constructor
template <class T> Pila<T>::Pila(int nelem)
{
nelementos = nelem;
cadena = new T(nelementos);
limite = 0;
};
// definicin de las funciones miembro
template <class T> void Pila<T>::Poner(T elem)

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 6. PLANTILLAS 201

{
if (limite < nelementos)
cadena[limite++] = elem;
};
template <class T> void Pila<T>::Imprimir()
{
int i;
for (i=0; i<limite; i++)
cout << cadena[i] << endl;
};

Elprogramaprincipalpuedeserelquesigue:
#include <iostream.h>
#include "Pila.h"
void main()
{
Pila <int> p1(6);
p1.Poner(2);
p1.Poner(4);

Miembros de clases genricas


Losmiembrosdelasclasesgenricassedefinenydeclaranexactamenteigualquelos
declasesconcretas.Perodebemossealarquelasfuncionesmiembrosonasuvezplantillas
parametrizadas(funcionesgenricas)conlosmismosparmetrosquelaclasegenricaaque
pertenecen.
Consecuenciadeloanterioresquesilasfuncionesmiembrosedefinenfueradela
plantilla,susprototiposdeberanpresentarelsiguienteaspecto:
template<class T> class mVector
{
int dimension;
public:
T* mVptr;
template<class T> mVector<T>& operator=(const mVector<T>&);
template<class T> mVector<T>(int);
template<class T> ~mVector<T>();
template<class T> mVector<T>(const mVector<T>& mv);
T& operator[](int i) { return mVptr[i]; }
template <class T> void mostrar (int);
template <class T> void mostrar ();
202 PROGRAMACIN C++ Y COMUNICACIONES.

};

Sin embargo, no es exactamente as por diversas razones: La primera es que, por


ejemplo, se estara definiendo la plantilla mostrar sin utilizar el parmetro T en su lista de
argumentos (lo que en un principio no est permitido ). Otra es que no est permitido
declarar los destructores como funciones genricas. Adems los especificadores <T>
referidosamVectordentrodelapropiadefinicinsonredundantes.

Estasconsideracioneshacenquelosprototipospuedanserdejadoscomosigue(los
datosfaltantespuedenserdeducidosporelcontexto):
template<class T> class mVector
{
int dimension;
public:
T* mVptr;
mVector& operator= (const mVector&);
mVector(int); // constructor por defecto
~mVector(); // destructor
mVector(const mVector& mv); // constructor-copia
T& operator[](int i) { return mVptr[i]; }
void mostrar (int); // funcin auxiliar
void mostrar (); // funcin auxiliar
};

Sinembargo,lasdefinicionesdemtodosrealizadasoffline(fueradelcuerpodeuna
plantilla)debenserdeclaradasexplcitamentecomofuncionesgenricas.

Porejemplo:
template <class T> void mVector <T>::mostrar (int i)
{
...
}

Miembros estticos
Las clases genricas pueden tener miembros estticos (propiedades y mtodos).
Posteriormente cada especializacin dispondr de su propio conjunto de estos miembros.
Estos miembros estticos deben ser definidos fuera del cuerpo de la plantilla, exactamente
igualquesifuesenmiembrosestticosdeclasesconcretas:
template<class T> class mVector
{

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 6. PLANTILLAS 203

...
static T* mVptr;
static void mostrarNumero (int);
...
};

template<class T> T* mVector<T>::nVptr;


template<class T> void mVector<T>::mostrarNumero(int x){ ... };

Mtodos genricos
Hemossealadoque,porsupropianaturaleza,losmtodosdeclasesgenricassona
su vez (implcitamente) funciones genricas con los mismos parmetros que la clase, pero
puedenserademsfuncionesgenricasexplcitas(quedependandeparmetrosdistintosde
laplantillaaquepertenecen):

template<class X> class A
{

// mtodo genrico de clase genrica


template<class T> void func(T& t);
...
}

Segnesusual,ladefinicindelmiembrogenricopuedeefectuarsededosformas,
inlineuoffline:
#include <iostream.h>

template<class X> class A


{
public:
int x;
X* xptr;
template<class T> void fun(T t1, T t2)
{
// mtodo genrico
cout << "Valor-1: " << t1
<< ", Valor-2: " << t2
<< ", Miembro-x: " << x
<< ", Objeto: " << *xptr << endl;
}
A (X* b, int i = 0)
204 PROGRAMACIN C++ Y COMUNICACIONES.

{
x = i;
xptr = b;
}
};

int main(void)
{
char c = 'c'; char* cptr = &c;
int x = 13; int* iptr = &x;
A<int> a(iptr, 2);
A<char> b(cptr, 3);
a.fun(2, 3);
a.fun('x', 'y');
b.fun(2, 3);
b.fun('x', 'y');
return 0;
}

Salida:

Valor-1: 2, Valor-2: 3, Miembro-x: 2, Objeto: 13


Valor-1: x, Valor-2: y, Miembro-x: 2, Objeto: 13
Valor-1: 2, Valor-2: 3, Miembro-x: 3, Objeto: c
Valor-1: x, Valor-2: y, Miembro-x: 3, Objeto: c

Instanciacin de clases genricas


Lasclasesgenricassonentesdenivelsuperioralasclasesconcretas.Representan
para las clases normales (en este contexto preferimos llamarlas clases explcitas) lo mismo
quelasfuncionesgenricasalasfuncionesconcretas.Comoaquellas,solotienenexistencia
enelcdigo.ComoelmecanismodeplantillasC++seresuelveentiempodecompilacin,ni
enelficheroejecutablenidurantelaejecucinexistenadaparecidoaunaclasegenrica,solo
existenespecializaciones.Enrealidadlaclasegenricaqueseveenelcdigo,actacomouna
especiede"macro"queunavezejecutadosutrabajoenlafasedecompilacin,desaparece
deescena.
Observeque,comoha indicado algn autor, el mecanismo de plantillas representa
una especie de polimorfismo en tiempo de compilacin, similar al que proporciona la
herenciademtodosvirtualesentiempodeejecucin.
A diferencia de lo que ocurre con las funciones genricas, en la instanciacin de
clases genricas el compilador no realiza ninguna suposicin sobre la naturaleza de los
argumentosautilizar,demodoqueseexigequeseandeclaradossiempredeformaexplcita.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 6. PLANTILLAS 205

Porejemplo:
mVector<char> mv1;
mVector mv2 = mv1; // Error !!
mVector<char> mv2 = mv1; // Ok.

Sin embargo, como veremos a continuacin, las clases genricas pueden tener
argumentospordefecto,porloqueenestoscasosladeclaracinpuedenoserexplcitasino
implcita(referidaalosvalorespordefectodelosargumentos).Laconsecuenciaesqueen
estoscasoselcompiladortampocorealizaningunasuposicinsobrelosargumentosautilizar.
Las clases genricas pueden ser utilizadas en los mecanismos de herencia. En ese
caso,laclasederivadaestarparametrizadaporlosmimmosargumentosquelaplantilladela
clsebase.
Porejemplo:
template <class T> class Base { ... };
template <class T> class Deriv : public Base<T> {...};

Los typedef son muy adecuados para acortar la notacin de objetos de clases
genricascuandosetratadedeclaracionesmuylargasonointeresanlosdetalles.

Porejemplo:
typedef basic_string <char> string;

string st1;

Las clases genricas pueden tener argumentos por defecto, en cuyo caso, el tipo T
puedeomitirse,peronolosngulos<>.Porejemplo:
template<class T = int> class mVector {/* ... */};
...
mVector<char> mv1; // Ok. argumento char explcito
mVector<> mv2; // Ok. argumento int implcito

Cada instancia de una clase genrica es realmente una clase, y sigue las reglas
generales de las clases. Dispondr por tanto de su propia versin de todos los miembros
estticos si los hubiere. Estas clases son denominadas implcitas, para distinguirlas de las
definidas"manualmente",quesedenominanexplcitas.
La primera vez que el compilador encuentra una sentencia del tipo
mVector<Vector> crea la funcinclase para dicho tipo; es el punto de instanciacin. Con
206 PROGRAMACIN C++ Y COMUNICACIONES.

objetodequesoloexistaunadefinicindelaclase,siexistenmsocurrenciasdeestemismo
tipo,lasfuncionesclaseredundantessoneliminadasporelenlazador.Porlarazninversa,si
el compilador no encuentra ninguna razn para instanciar una clase (generar la funcin
clase), esta generacin no se producir y no existir en el cdigo ninguna instancia de la
plantilla.

Al igual que ocurre con las funciones genricas, en las clases genricas tambin
puedeevitarselageneracindeversionesimplcitasparatiposconcretosproporcionandouna
especializacinexplcita.
Porejemplo:
class mVector<T> { ... }; // definicin genrica
...
class mVector<char> { ... }; // definicin especfica
mstarde,lasdeclaracionesdeltipo
mVector<char> mv1, mv2;

generar objetos utilizando la definicin especfica. En este caso mv1y mv2 sern
matricesalfanumricas(cadenasdecaracteres).

Observequeladefinicinexplcitacomportadosrequisitos:

Aunque es una versin especfica (para un tipo concreto), se utiliza la sintaxis de


plantilla:classmVector<...>{...};

Sehasustituidoeltipogenrico<T>poruntipoconcreto<char>.
Resultaevidentequeunadefinicinespecfica,comolaincluda,solotienesentidosi
senecesitanalgunasmodificacioneseneldiseocuandolaclaseserefieraatiposchar.

Argumentos de la plantilla
La declaracin de clases genricas puede incluir una lista con varios parmetros.
Estos pueden ser casi de cualquier tipo: Complejos, fundamentales, por ejemplo un int, o
inclusootraclasegenrica(plantilla).Ademsentodosloscasospuedenpresentarvalores
pordefecto.:
template<class T, int dimension = 128> class mVector { ... };

Aligualqueenlasfuncionesgenricas,enlainstanciacindeclasesgenricas,los
valoresdelosparmetrosquenoseantiposComplejosdebenserconstantesoexpresiones
constantes.
const int K = 128;

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 6. PLANTILLAS 207

int i = 256;
mVector<int, 2*K> mV1; // OK
mVector<Vector, i> mV2; // Error: i no es constante

Este tipo de parmetros constantes son adecuados para establecer tamaos y
lmites.Sinembargo,porsupropianaturalezadeconstantes,cualquierintentoposteriorde
alterarsuvalorgeneraunerror.

Los argumentos tambin pueden ser otras plantillas, pero solo de clases genricas.
Introducircomoargumentounaplantilladefuncionegenricanoestpermitido:
template <class T, template<class X> class C> class MatrizC
{ ...
};
template <class T, template<class X> void Func(X a)> class MatrizF
{ // Error!!
...
};

Hay que tener en cuenta que no existe algo parecido a un mecanismo de


"sobrecarga"de las clasesgenricasparalelo alde las funcionesgenricas. Por ejemplo las
siguientesdeclaracionesproducenunerrordecompilacin.
template<class T> class mVector { ... };
template<class T, int dimension> class mVector { ... };

El compilador dara el siguiente error: Number of template parameters does not


matchinredeclarationof'Matriz<T>'.

Punteros y referencias a clases implcitas


Como hemos sealado, las clases implcitas gozan de todas las prerrogativas de las
explcitas, incluyendo por supuesto la capacidad de definir punteros y referencias. En este
sentido no se diferencian en nada de aquellas; la nica precaucin es tener presente la
cuestindelostiposalahoradeefectuarasignaciones,ynoperderdevistaquelaplantillaes
una abstraccin que representa mltiples clases (tipos), cada una representada por
argumentosconcretos.
ConsideremoslaclasegenricaMatrizcuyadeclaracines:
208 PROGRAMACIN C++ Y COMUNICACIONES.

template <class T, int dim =1> class Matriz { /* ... */};



Ladefinicindepunterosyreferenciasseracomosigue:
Matriz<int,5> m1; // Ok. Tres objetos
Matriz<char,5> m2; // de tipos
Matriz<char> m3; // distintos.
...
Matriz<int,5>* ptrMi5 = &m2 // Error!! tipos distintos
Matriz<char,5>* ptrMch5 = &m2; // Ok.
Matriz<char,1>* ptrMch1 = &m2; // Error!! tipos distintos
Matriz<char,1>* ptrMch1 = &m3; // Ok.
ptrMch5->show(); // Ok. invocacin de mtodo
Matriz<char> m4 = *ptrMch1; // Ok asignacin mediante puntero

void (Matriz<char,5>::* fptr1)(); // Ok. declara puntero a mtodo


fptr1 = &Matriz<char,5>::show; // Ok. asignacin
(m3.*fptr1)(); // Error!! tipo de m3 incorrecto
(m2.*fptr1)(); // Ok. invocacin de mtodo

Matriz<char,5>& refMch5 = m2; // Ok. referencia


Matriz<char>& refMch1 = m4; // Ok.
refMch5.show(); // Ok. invocacin de mtodo

Merecenespecialatencinlassentenciasdondeseutilizanpunterosamiembrosde
clases implcitas. El tipo de clase est definido en los parmetros. Observe que fptr1 es
punteroamtododeclaseMatriz<char,5>,ynopuedereferenciarunmtododem3,quees
unobjetodetipoMatriz<char,1>.
p1.Imprimir();
Pila <char> p2(6);
p2.Poner('a');
p2.Poner('b');
p2.Imprimir();
}

6.5. Clases genricas en la Librera Estndar

AlprincipiodelcapitulosehasealadoquelasplantillasfueronintroducidasenC++
paradarsoporteadeterminadastcnicasutilizadasenlaLibreraEstndar;dehecho,laSTL
est constituida casi exclusivamente por plantillas. Hablar y utilizar en profundidad las
plantillas de la librera estndar puede permitirnos el reducir drsticamente el esfuerzo

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 6. PLANTILLAS 209

necesario para la programacin, son embargo comprenderlas e introducirse en el modo en


quesehanprogramadorequiereyadeunasolturaenelmanejodellenguajequequedafuera
de los objetivos de este curso. Uno de los aspectos ms utilizados de las STL son los
contenedores, entre los que se podra incluir aquellos dedicados a manejar cadenas de
caracteres.

Una idea bsica dentro de las STL es el contenedor, que es precisamente lo que
parece: un sitio en el que almacenar cosas. Ya se ha visto que una de las operaciones ms
habituales es esta, as como una de las justificaciones para el uso de plantillas de clases
(recurdese el ejemplo de Lista<Esferas> o de la clase genrica mVector. Habitualmente
necesitamos este tipo de sitios de almacenamiento cuando de antemano desconocemos
cuantosobjetosodatosvamosatener.LoscontenedoresdelaSTLhacenesto;soncapaces
de mantener colecciones de objetos y adems se pueden redimensionar. El modo como
almacenanestascoleccionesdeobjetos,ycomoconsecuencialasoperacionesquesepueden
realizar sobre las colecciones, hacen que aparezcan distintos tipos de contenedores. Los
contenedoresmssecillosson:

vector. Un vector es la versin STL de una matriz dinmica de una dimensin. Las
instanciasdeestaclasegenricaconformanunasecuencia(unaclasedecontenedor).La
clasedisponedeaccesoaleatorioasuselementosydeunmecanismomuyeficientede
insercinyborradodeelementosalfinal.Aunquetambinpuedeninsertarseyborrarse
elementosenmedio,porelmodoenqueseorganizanloselementosenmemoria,esta
operacin es muy poco eficiente. Est definida en el fichero <vector> y responde a la
siguientedeclaracin:
template <class T, class Allocator = allocator<T> > class vector;

Una especializacin concreta de esta plantilla, cuando el tipo T es un booleano


vector<bool>, es considerada por la STL como un caso especial, con un cdigo
optimizado que incluye mtodos no disponibles para el resto de las instancias (los
mtodosflipyswap)pensadoparatrabajarconrepresentacionesbitabit.

deque. Esmuyparecidoavector,unasecuencialinealdeelementos,peroadmitecon
eficiencia la insercin de objetos tanto al principio como al final, mientras que sigue
comportndosemalparainsercionesintermedias.Admiteelaccesoaleatoriocasiconla
mismaeficienciaquevector,peroesespecialmentemsrpidocuandorequieresolicitar
msespacioparaalmacenarmsdatos(redimensionamiento).

list.Lasinstanciasdeestaplantillaconformantambinunasecuenciaquedisponede
mecanismosmuyeficientesparainsertaryeliminarelementosencualquierpunto.Est
internamente implementada como una lista doblemente enlazada. Como consecuencia
210 PROGRAMACIN C++ Y COMUNICACIONES.

de su estructura, no est diseada para el acceso aleatorio siendo este bastante ms


ineficientequeenlasdosclasesanteriores.Estdefinidaenelfichero<list>yrespondea
lasiguientedeclaracin:
template <class T, class Allocator = allocator<T> > class list;

Los tres tipos de conenedores admiten el mtodo push_back() que agregar un
nuevoelementoalfinaldelasecuencia(ademsdequeylist,tienenelmtodopush_front()
elcualpermitelainsercinalinicio).
El acceso a los elementos del vector o dedeque, puedeser aleatorio, y tienenpor
elloimplementadalasobrecargadeloperador[],peroestenoestdefinidoparalaclaselist.
Para contar con un medio de recorrer los contenedores de forma uniforme, y tambin por
razonesdeconsistenciadelosdatos,sehaceusodeuntipodedatosdefinidoparatodoslos
contenedoresydenominadoiterator.

Un iterador es una clase que abstrae el proceso de moverse a lo largo de una


secuencia,sinnecesidaddeconocercomoestestructuradaestasecuanciainternamente(no
nos importa si los objetos en memoria estan ordenados secuencialmente o su orden est
determinadoporalgntipodeestructuraadicionalcomoeselcasodelaslistas).Contarcon
estetipode"recorredor"desecuenciasesimportantodadoquenosdaunmodouniformede
tratarlas, y por tanto nos permitir utilizar funciones genricas indistintamente al tipo de
contenedorusado.
Todosloscontenedorescontienenestaclasedeobjetosdefinidayquesobrecargael
operador ++ y el operador >, adems de otras operaciones. Adems, los contenedores
contienen el mtodo begin() y end() que nos retornarn un iterador ubicado en la posicin
inicialofinaldelasecuenciarespectivamente.
Dado que solo se trata de dar una visin rpida de los contenedores en las STL, el
siguienteejemploesbastanteilustrativodesuuso:
#include <vector>
#include <iostream>
using namespace std;

class Shape {
public:
virtual void draw() = 0;
virtual ~Shape() {};
};

class Circle : public Shape {


public:
void draw() { cout << "Circle::draw\n"; }

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 6. PLANTILLAS 211

~Circle() { cout << "~Circle\n"; }


};

class Triangle : public Shape {


public:
void draw() { cout << "Triangle::draw\n"; }
~Triangle() { cout << "~Triangle\n"; }
};

typedef std::vector<Shape*> Container; //por comodidad definimos


typedef Container::iterator Iter; //dos tipos con typedef

int main() {
Container shapes;
shapes.push_back(new Circle);
shapes.push_back(new Triangle);
for(Iter i = shapes.begin();
i != shapes.end(); i++)
(*i)->draw(); //se puede usar i->draw() dado que el iterador tiene
//sobrecargado el operador ->
// ... al final si queremos limpiar la memoria:
for(Iter j = shapes.begin();
j != shapes.end(); j++)
delete *j;
}

Esinteresanteverqueesposiblecambiarsinproblemaseltipobsicodelcontenedora
una lista o un deque, y el cdigo no se ve alterado ms que en la definicin del
contenedor.


Algunasotrasclaseshabitualmenteutilizadas,seranlassiguientes:

basic_string: una plantilla para utilizar entidades como secuencias de caracteres. Est
definidaenelficherodecabecera<string>,yrespondealasiguientedeclaracin:
template <class charT, class traits = char_traits<charT>,
class Allocator = allocator<charT> > class basic_string;

Comopuedeverse,aceptatresargumentos,delosquedostienenvalorespordefecto.
Existendosespecializacionesquetienennombresespecficos.EnconcretosicharTes
charlaespecializacinsedenominastring,ywstringsicharTeswchar_t.Estosehace
mediantesendostypedef:
typedef basic_string <char> string;
212 PROGRAMACIN C++ Y COMUNICACIONES.

typedef basic_string <wchar_t> wstring;



deformaquelasdossentenciassiguientessonequivalentes:
basic_string<char> s1;
string s1;

LascadenasenC++sonenelfondocontenedoresdecaracteresycomotalespueden
ser tratados. Sin embargo, dado su uso tan comn, se ha dotado a basic_string de un
conjuntodefuncionesyoperadoresquesimplifican(porfin!) elusodeestetipodedatos.
Porejemplo,laconcatenacin,creacin,reserva,comparacin,pasoamayusculas,etc...son
operacionesincluidasdirectamente:
#include <string>
#include <iostream>
using namespace std;

int main() {
string s1("This ");
string s2="That ";
string s3("The other ");
// operator+ concatena strings
s1 = s1 + s2;
cout << s1 << endl;
// otra forma de concatenar strings
s1 += s3;
cout << s1 << endl;
// o acceder a la vez que se concatena a un caracter
s1 += s3 + s3[4] + "oh lala";
cout << s1 << endl;
if(s1 != s2) {
cout << "los strings son distitos:" << " ";
if(s1 > s2)
cout << "s1 es > s2" << endl;
else
cout << "s2 es > s1" << endl;
}
}

map.Estaplantillaestdefinidaenelfichero<map>,ytienelasiguientedeclaracin:
template <class Key, class T, class Compare = less<Key>
class Allocator = allocator<pair<const Key, T>> > class map;

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 6. PLANTILLAS 213

Las instancias de esta plantilla conforman un contenedor asociativo (una clase de


contenedor) que permite almacenar y acceder objetos de tipo T indexados mediante
unanicaclaveKey,disponiendodemecanismosmuyeficientesdeinsercinyborrado.

auto_ptr.Estaplantillagenerapunteros"inteligentes"quedestruyenautomticamente
elobjetosealadocuandoellosmismossalendembito.Sudefinicinestenelfichero
<memory>,ysudeclaracines:
template <class X> class auto_ptr;

EnrealidadestaplantillasehaincluidoenlaLibreraEstndarparaayudararesolver
el problema de los objetos persistentes, creados con el operador new, cuyo
referente (el puntero que los seala) es un objeto automtico que puede ser
destruido inadvertidamente al salir de mbito. Lo que puede ocurrir en el los
procesosdelanzamientoycapturadeexcepciones.

6.6. Ejemplo

Elsiguienteestractodecdigomuestraunaclasegenricaquesirveparaalamecenar
punteros de objetos o elementos creados externamente a ella. Internamente se comporta
comounvectordinmicoqueadmiteportantounnmeroindefinidodeelementos.Incluye
adems una serie de operaciones bsicas para facilitar el manejo y mantenimiento del
conjuntodedireccionesalmacenadas:

Ficherocontenedor.h
template <class T> class contenedor
{
private:
T **array;
int nElem;
int elemMax;
public:
contenedor(void);
contenedor(contenedor &td); /*copia*/
~contenedor(void);
inline T* operator [] (int a);
void operator += (T *ele);
void destruirObjetos(void);
void eliminar (int a);
214 PROGRAMACIN C++ Y COMUNICACIONES.

T* quitar(int a);
T* quitar(T* ele);
int buscar(T* ele);
void swap(int a, int b);
void insertar(T *ele, int a);
inline int numElem (void);
};

Ficherocontenedor.cpp
#include contenedor.h
template <class T> contenedor<T>::contenedor (void)
{
array = new T* [5];
nElem = 0;
elemMax = 5;
}
template <class T> void contenedor<T>::destruirObjetos (void)
{
for (int i=0; i<numElem; i++)
delete array[i];
numElem=0;
}
template <class T> contenedor<T>::~contenedor (void)
{
delete [] array;
}

template <class T> contenedor<T>::contenedor (contenedor & td)


{
int i;
nElem = td.nElem;
elemMax = td.elemMax;
array = new T* [elemMax];
for(i=0;i<nElem;i++) array[i]=td[i];
}
template <class T> T* contenedor<T>::operator [] (int a)
{
if ((a>=0)&&(nElem>a))return array[a];
return NULL;
}
template <class T> void contenedor<T>::operator += (T* ele)
{

if (nElem == elemMax)
{
elemMax+=5;

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 6. PLANTILLAS 215

T** array2 = new T* [elemMax];


memcpy (array2,array,nElem*sizeof(T*));
delete [] array;
array=array2;
}
array[nElem] = ele;
nElem ++;
}
template <class T> T* contenedor<T>::quitar(int a)
{
T* aux;
if((a>=0)&&(a<numElem))
{
aux=array[a];
array[a]=NULL;
for(int i=a+1;i<numElem;i++)
array[i-1]=array[i];
return aux;
}
return NULL;
}
template <class T> T* contenedor<T>::quitar(T* ele)
{
return (quitar(buscar(ele)));
}
template <class T> int contenedor<T>::buscar(T* ele)
{
for(int i=0;i<nElem;i++)if(array[i]==ele)return i;
return -1;
}
template <class T> void contenedor<T>::swap(int a,int b)
{
T* aux;
if((a>=0)&&(a<nElem)&&(b>=0)&&(b<nElem))aux=a;a=b;b=aux;
}
template <class T> void contenedor<T>::insertar(T *ele, int a)
{
if(a<0)return;
(*this)+=ele;
swap(nElem-1,a);
}
template <class T> int contenedor<T>::numElem (void)
{
return nElem;
}

Departamento de Electrnica Automtica e Informtica Industrial


Departamento de Electrnica Automtica e Informtica Industrial


220 PROGRAMACIN C++ Y COMUNICACIONES.

7. Manejo de excepciones y tratamiento de errores

Unodelosaspectosqueconmsdificultadseabordanenlosdistintoslenguajesde
programacineselcorrectotratamientodeloserrores.Esdecir,elfuncionamientonormalde
un algoritmo o programa contiene la dificultad inherente del problema que se quiere
resolver, y como consecuencia generar un flujograma ms o menos complicado. Sin
embargo,todoelloseincrementaencomplejidaddeformanotableenelmomentoenelque
sepretendeverificarycomprobarlosposibleserroresosituaciones"nonominales"durante
elprocesodeejecucin.
Esteproblemanoessoloespecficodelaingenieradelsoftware,sinoqueamenudo
eselmayorquebraderodecabezaenlamayoradelosproyectosdediseoyenparticular
aquellosenlosquelaseguridadesimportante.Dehecho,sepuededecirsinproblema,que
es ms Complejo el sistema de redundancia y seguridad que se incluye en el software de
controldeunavinqueelpropiosistemadecontrol.

Al conjunto de situaciones "imprevistas" se la denomina "excepcin", y al


mecanismo dispuesto para reaccionar ante esas situaciones, se lo denomina como

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 7. MANEJO DE EXCEPCIONES Y TRATAMIENTO DE ERRORES 221

consecuencia"manejadordeexcepciones6".Existenmuchostiposdeexcepciones,peropara
ubicar el tema, durante la ejecucin de un programa puede ocurrir que un fichero no se
pueda grabar (disco lleno), o que se agote la memoria, o que el usuario haya intentado
realizarunaoperacinnovlida(porejemplodesdeelprogramaabrirunficherosobreelque
carecedepermiso),etc.

7.1. Tratamiento de excepciones en C++

El tratamiento de excepciones C++ sigue un proceso estructurado, por lo que a la hora de


disearlosediferenciantresconceptosbsicos:

1. Hayunapartedecdigoenelqueseconsideraquesepuedenproducirsituaciones
anmalas,yqueconsecuenciasepuedengenerarunaseriedeexcepciones.Poreso,
seconsideraqueesposiblequelaaccinqueesapartedecdigoquiererealizarno
seconsiga,yportantoesunazonade"intentodeejecucin"(try).
2. Cuandosedetectaunacircunstanciaextraaoanmala(unaexcepcin),seinforma
alproceso,funcin,oprogramaquehaocurridoalgoimprevisto,yseinterrumpeel
curso normal de ejecucin. Para realizarlo se "lanza" una excepcin (throw). Esa
excepcin es un objeto que contiene informacin sobre el error para que el que
escucheseacapazdereaccionaranteestasituacin.
3. Paraqueelprogramapuedadecidirquehacerenestoscasos,trasintentarejecutar
algo susceptible de fallar, indicar una zona del cdigo que se ejecutar para
reaccionar ante esas sistuaciones. Para ello "captura" (catch) las excepciones
lanzadas en la zona de "intento" y se decide que hacer al respecto con la
informacinqueestascontienen.

En el fondo el mecanismo es un mecanismo de salto controlado. Al cdigo encargado de
reaccionaranteunadeterminadaexcepcinselodenomina"manejador"delaexcepcin.

Durante la ejecucin de un programa pueden existir dos tipos de circunstancias


excepcionales:sncronasyasncronas.Lasprimerassonlasqueocurrendentrodelprograma.
Porejemplo,queseagotelamemoriaocualquierotrotipodeerror.Sonaestasalasquenos
hemos estado refiriendo. Las excepcionesasncronas son las que tienen su origen fuera del
programa,aniveldelSistemaOperativo.PorejemploquesepulsenlasteclasCtrl+C.

6
Exception Handler
222 PROGRAMACIN C++ Y COMUNICACIONES.

GeneralmentelasimplementacionesC++soloconsideranlasexcepcionessncronas,deforma
quenosepuedencapturarconellasexcepcionestalescomolapulsacindeunatecla.Dicho
con otras palabras: solo pueden manejar las excepciones lanzadas con la sentencia
throw. Siguen un modelo denominado de excepciones sncronas con terminacin, lo que
significaqueunavezquesehalanzadounaexcepcin,elcontrolnopuedevolveralpunto
quelalanz.El"handler"nopuededevolverelcontrolalpuntodeorigendelerrormediante
una sentencia return. En este contexto, un return en el bloque catch supone salir de la
funcinquecontienedichobloque.

El sistema estndar C++ de manejo de excepciones no est diseado para manejar


directamente excepciones asncronas, como las interrupciones de teclado, aunque pueden
implementarsemedidasparasucontrol.Ademslasimplementacionesmsusualesdisponen
derecursosparamenejarlasexcepcionesdelSistemaOperativo

Antes de ver un ejemplo completo se ver en primer lugar como se ha previsto en C++ la
transcripcin de cada uno de estos compoenentes del mecanismo de tratamiento de
excepciones.

El bloque "try"

En sntesis podemos decir que el programa se prepara para cierta accin, decimos
que"lointenta".Paraelloseespecificaunbloquedecdigocuyaejecucinsevaaintentar
("tryblock")utilizandolapalabraclavetry:


try
{

// conjunto de instrucciones en las que


// se puede producir una excepcin y que quedan
// afectadas por la misma
...
}

Unejemplosencilloseralaoperacindeaperturaygrabacindeinformacinenunfichero.
Es posible que no se pueda abrir el fichero por no tener permisos de escritura en el luegar
indicado por el usuario, y por tanto cualquier instruccin de escritura tras fracasar en la
aperturadebeserevitada.

Laideadelbloquetryenestecasopodraejemplarizarsedelasiguienteforma:

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 7. MANEJO DE EXCEPCIONES Y TRATAMIENTO DE ERRORES 223

INTENTA{
1.Abrirelfichero
2.Guardarlainformacin
3.Cerrarelfichero
}
SIHAYUNERRORCAPTURALOYEJECUTA
{
4.Informaalusuario
}

Luego habitualmente el bloque de intento no slo incluye la zona susceptible de generar


errores,sinoquetambinincluyelapartedecdigoquedebeevitarserejecutadaencasode
queestoserroresseproduzcan.Asenelejemplo,silaaperturadeficherodaunerror,habr
queevitarejecutarlasoperacionesindicadaspor2ypor3.Porello,si1lanzaunaexcepcin
de "ERROR DE APERTURA", se interrumpe la ejecun secuencial del programa y se "SALTA"
hastaelmanejador(4)queinformaralusuariodeesteerror.
Seinformaportantoalprogramaquesiseproduceunerrorduranteel"intento",entoncesse
debe transferir el control de ejecucin alpuntodonde exista un manejador de excepciones
("handler") que coincida con el tipo de excepcin lanzado. Si no se produce ninguna
excepcin,elprogramasiguesucursonormal.

De lo dicho se deduce inmediatamente que se pueden lanzar excepciones de varios tipos y


que pueden existir tambin receptores (manejadores) de varios tipos; incluso manejadores
"universales",capacesdehacersecargodecualquiertipodeexcepcin.

Aspues,tryesunasentenciaqueenciertaformaescapazdeespecificarelflujodeejecucin
delprograma.Unbloqueintentodebeserseguidoinmediatamenteporelbloquemanejador
delaexcepcin,elcualseespecificapormediodelapalabraclavecatch.

El bloque "catch"

Mediante la palabra clave catch especificamos el cdigo encargado de reaccionar ante una
determinadaexcepcinoconjuntodeexcepciones.Comoyasehacomentado,sedicequeun
manejador"handler"capturaunaexcepcin.
EnC++esobligatorioquetrasunbloquetryseincluyaalmenosunbloquecatch,porloquela
sintaxisanteriorquedaracompletadelasiguienteforma:

try { // bloque de cdigo que se intenta


...
}
catch (...) { // bloque manejador de posibles excepciones
...
224 PROGRAMACIN C++ Y COMUNICACIONES.

}
... // continua la ejecucin normal

El "handler" es el sitio donde continua el programa en caso de que ocurra la circunstancia


excepcional (generalmente un error) y donde se decide qu hacer. A este respecto, las
estrategiaspueden ser muyvariadas (no es lo mismo elprograma de controldeun reactor
nuclear que un humilde programa de contabilidad). En ltimo extremo, en caso de errores
absolutamente irrecuperables, la opcin adoptada suele consistir en mostrar un mensaje
explicandoelerror.

Lanzamiento de una excepcin " throw "


Lasexcepcinesnoslolaslanzanlasfuncionesincluidasdentrodelaslibrerasexternas,sino
quenosotrospodemosquererinformarquealgonohaidobiendentrodelalgicadenuestro
programa.

Al igual que ocurre con el cdigo de las libreras estandar, esto se realiza por medio de la
instruccinthrow.

EllenguajeC++especificaquetodaslasexcepcionesdebenserlanzadasdesdeelinteriorde
un bloqueintento y permite que sean de cualquier tipo. Como se ha apuntado antes,
generalmentesonunobjeto(instanciadeunaclase)quecontieneinformacin.Esteobjeto
escreadoylanzadoenelpuntodelasentenciathrowycapturadodondeestlasentencia
catch.Eltipodeinformacincontenidoenelobjetoesjustamenteelquenosgustaratener
para saber que tipo de error se ha producido. En este sentido puede pensarse en las
excepcionescomoenunaespeciedecorreosquetransportaninformacindesdeelpuntodel
error hasta el sitio donde esta informacin puede ser analizada. Todo esto lo veremos con
msdetalleacontinuacin.

Como se ha comentado C++ permite lanzar excepciones de cualquier tipo. Sin embargo lo
normalesqueseaninstanciasdeunaclasetipoX,quecontienelainformacinnecesariapara
conocer la naturaleza de la circunstancia excepcional (probablemente un error). El tipo X
debecorresponderconeltipodeargumentousadoenelbloquecatch,detalformaquepor
medio del tipo de las excepciones ser posible ejecutar manejadores distintos an siendo
estaslanzadasdesdeelmismobloquetry.

Nota:Serecomiendaquelasclasesdiseadasparainstanciarestetipode
objetos(denominadasExcepciones)seanespecficasydiseadasparaestefin
exclusivo,sinquetenganotrousoquelaidentificacinymanejodelas
excepciones.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 7. MANEJO DE EXCEPCIONES Y TRATAMIENTO DE ERRORES 225

Laexpresinthrow(Xarg)inicializarunobjetotemporalargdetipoX,aunquepuedequese
generenotrascopiaspornecesidaddelcompilador.Enconsecuenciapuedesertildefinirun
constructorcopiacuandoelobjetoalanzarperteneceaunaclasequecontienesubobjetos,
comoenelcasodecualquierotraclasecuyosobjetosquieranserpasadosporvalor
(recurdeseelapartadodedicadoalcontructordecopiayeloperadordeasignacinenel
captulo3).

EnelsiguienteejemplosepasaelobjetodetipoOutalmanejadorcatch:

#include <stdio.h>
bool pass;
class Out{}; // L.3: Para instanciar el objeto a lanzar

void festival(bool); // L.4: prototipo


int main()
{
try { // L.7: bloque intento
pass = true;
festival(true);
}
catch(Out o) { // L.11: la excepcin es capturada aqu
pass = false; // L.12: si se produce una excepcin
} // L.13:
return pass ? (puts("Acierto!"),0) : (puts("Fallo!"),1);
}

void festival(bool firsttime){


if(firsttime) {Obj o; throw o; } // L.18: lanzar excepcin
}

7.2. Secuencia de ejecucin del manejo de excepciones

Comopuedeverse,lafilosofaC++respectoalmanejodeexcepcionesnoconsisteencorregir
el error y volver al punto de partida. Por el contrario, cuando se genera una excepcin el
control sale del bloque try que lanz la excepcin (incluso de la funcin), y pasa al bloque
catchcuyomanejadorcorrespondeconlaexcepcinlanzada(siesqueexiste).

Asuvezelbloquecatchpuedehacervariascosas:

Relanzarlamismaexcepcin
226 PROGRAMACIN C++ Y COMUNICACIONES.

Saltaraunaetiqueta

Terminarsuejecucinnormalmente(alcanzarlallavedecierre).

Si el bloque catch termina normalmente sin lanzar una nueva excepcin, el control se salta
todos los bloques catch que hubiese asociados al bloque try correspondiente y sigue la
ejecucindelprogramaacontinuacin.

Puede ocurrir que el bloque catch lance a su vez una excepcin. Lo que nos conduce a
excepcionesanidadas.Estopuedeocurrir,porelhechodequeseejecutanintruccionesypor
tantoesposiblequealgunadeellasvuelvaagenerarasuvezunaexcepcin(supongaseque
es una excepcin lanzada por intentar cerrar un fichero que no existe o que no se puede
cerrar)

Como se puede ver, un programador avanzado puede utilizar las excepciones C++ como un
mecanismo de return o break multinivel, controlado no por una circunstancia excepcional,
sinocomounactodeliberadodelprogramadorparacontrolarelflujodeejecucin.selanzan
deliberadamenteexcepcionesconlaideademoverseentrebloquesadistintosniveles.Dado
el nivel de este curso no se recomienda esta prctica hasta que no se est totalmente
familiarizadoconlaprogramacinestructurada.

Relanzar una excepcion

Si seha lanzadopreviamente una excepciny se est en el bloque que laha capturado, es


posiblerepetirellanzamientodelaexcepcin(elmismoobjetorecibidoenelbloquecatch)
utilizandosimplementelasentenciathrowsinningnespecificador.Noperderdevistaqueel
lanzamiento throw, solo puede realizarse desde el interior de un bloque try, al que debe
seguirsucorrespondiente"handler".

Elsiguienteejemploseraincorrecto,dadoqueseintentarelanzarunaexcepcindesdefuera
deunbloquetry:

try {
...
if (x) throw A(); // lanzar excepcin
}
catch (A a) { // capturar excepcin
... // hacer algo respecto al error
throw; // Error!! no est en un bloque try
}

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 7. MANEJO DE EXCEPCIONES Y TRATAMIENTO DE ERRORES 227

Elmodomshabitualderealizarunrelanzamientoesdebidoaquesetratadeunbloquetry
anidadoenotrobloquetry(enlamismafuncinoenfuncionesjerarquicamenteporencima
enlapiladellamadas).Elsiguienteejemploreflejaestemododeproceder:

void foo();
void main () {
try {
...
foo();
}
catch (A a) {
...
}
return 0;
}
void foo() {
...
if (x) try {
throw A();
}
catch (A) {
...
throw;
}
}

Departamento de Electrnica Automtica e Informtica Industrial


230 PROGRAMACIN C++ Y COMUNICACIONES.

8. Breve Introduccin a la representacin UML

El trmino UML proviene delas siglas inglesas de Lenguaje Unificado de Modelado(Unified


Modeling Language) y es el lenguaje de modelado de sistemas software ms conocido y
utilizado en la actualidad, y se encuentra respaldado por el OMG (Object Management
Group).

ElobjetivodeUMLesproporcionaradesarrolladoresdesoftware,arquitectosdesistemase
ingenierosdesoftwaredeherramientasparaelanlisis,diseoeimplementacindesistemas
basadosensoftware,ascomomodelarprocesosdenegocioysimilares.

Es importante remarcar que UML es un "lenguaje de modelado" para especificar o para


describirmtodosoprocesos.Seutilizaparadefinirunsistema,paradetallarlosartefactosen
el sistema y para documentar y construir. En otras palabras, es el lenguaje en el que est
descrito el modelo. Se puede aplicar en el desarrollo de software gran variedad de formas
paradarsoporteaunametodologadedesarrollodesoftware,peroUMLensnoespecifica
qumetodologaoprocesousar.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 8. BREVE INTRODUCCIN A LA REPRESENTACIN UML 231

Por eso es importante seleccionar correctamente el modelo adecuado y el nivel de


representacin correcto. UML es muy extenso y en la prctica, la mayora de los sistemas
requierenparasumodeladoslodelusodeun10o20%delasposibilidadesdadasporUML.

CollageobtenidodeWikipediaenelquesereflejanalgunosdelosmltiplesdiagramasqueesfecificaUML.

UML cuenta con varios tipos de diagramas, los cuales muestran diferentes aspectos de las
entidadesrepresentadas.

FinalmentenohayqueconfundirUMLconunlenguajedeprogramacin.Dehecho,apesar
deconstituirunestndarprcticamenteaceptadoporelconjuntodeprogramadores,nodeja
derecibirciertascrticasdebidoalaambigedadenlainterpretacinquesepuederealizaren
los distintos diagramas. Adems, al constituir una serie de herramientas de modelado, en
general, una misma realidad se representa o dibuja desde distitnas perspectivas que se
complementan para finalmente dotar al conjunto de un significado. Luego por eso es muy
importantequelosdiagramassecentrenenaquelaspectoquequierenmostrarynointentar
reflejartodalarealidadenunsologrfico.
232 PROGRAMACIN C++ Y COMUNICACIONES.

8.1. Elementos de contruccin de los diagramas UML

LosdiagramasdeUMLcontienencincotiposdeelementosdiferenciados:

1. Elementosestructurales:Puedeentendersecomolarepresentacindelosnombres
dentro de un modelo de algo. Por ejemplo, en una urbanizacin, casa, rbol,
carretera. Son sustantivos del modelo. Constituyen la parte ms esttica del
modeladorepresentandotantoelementosconceptualescomofsicos.
2. Elementosdecomportamiento:deformaanloga,podemosestablecerquevienena
sercomolosverbosdellenguajedemodelado.Representancomportamientosenel
tiempo y en el espacio. Existirn elementos de comportamiento que nos servirn
paraespecificarcomoevolucionanlascosasademsdecmoserelacionan.
3. Elementos de agrupacin. Son las partes organizativas del modelo. Establece las
divisionesenquesepuedefraccionarunmodelo.
4. Elementosdeanotacin.Comosupropionombreindicasonlaspartesexplicativas
del modelo UML. Iluminan, explican, detallan aspectos de cualquier elemento del
modelo.
5. Relaciones. Nos permiten reflejar los modos en que los elementos del modelo se
relacionanentres.

Aunque la explicacin detallada de cada uno de estos conjuntos de elementos excede la


finalidaddeestecaptulo,sevaaprocederacontinuacinaenumerarydescribirbrevemente
losdistintoscomponentesascomosurepresentacinparacadaunadelascategoras:

Elementos estructurales

CLASE:Reflejaunconjuntodeobjetosquecompartenlosmismosatributos,operaciones,
relaciones y semntica. Lgicamente constituir una representacin unvoca del
elemento homnimo de C++. Se refleja como un rectngulo dividido en tres secciones:
nombre,atributosymtodos.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 8. BREVE INTRODUCCIN A LA REPRESENTACIN UML 233

INTERFAZ: Una interfaz corresponde a un conjunto de operaciones que especifican un


servicio dado por una clase o componente. Por tanto describe el coportameinto
externamentevisibledeestoselementos.Sediferenciaclaramentedeunaclaseenenel
sentido de que carece de atributos. En C++ no existe de forma directa el concepto de
interfaz, aunque estas se pueden realizar por medio de clases virtuales puras sin
atributos, y con todos los mtodos abstractos. En JAVA este elemento existe como
entidad propia. Su representacin grfica se realiza por medio de un caja que lleva el
ttulo de <<interfaz>> antes del nombre, y que est dividida en dos zonas (la de
identificacin,ylademtodos).

Unainterfazsuministradaporunaclasealrestodecomponentes(conjuntode
operacionesagrupadasquedanunservicio,porloqueunaclasepuedetenervarias
interfaces),seespecificapormediodeuncirculounidoporunalneaalaclase.Deigual
forma,siunaclaserequieredeaccederaunainterfazdeotrocomponente,estose
reflejapormediodeunsemicrculounidoporunsegmentoalaclase.Porejemplo,la
claseventanaimplementalaintefazIVentana,yrequieredelusodelainterfazIPaint(que
esunservicioquelepermitirdibujarseenalgnlugar):


234 PROGRAMACIN C++ Y COMUNICACIONES.

Caso de uso: Es una descripcin de un conjunto de secuencias de acciones que un


sistema ejecuta y que produce un resultado observable de inters para un actor
particular. Aunque es un concepto importante, de momento para los objetivos de este
cursosimplementeemplazamosaqusurepresentacin:

Componente: Es una parte modular del sistema de diseo, agrupando por tanto sus
elementos lgicos (clases, interfaces), y mostrando fundamentalmente un conjunto de
funcionalidades utilizables por el exterior. Por ejemplo, un componente podra ser el
reporductor de Video de un sistema de ventanas. Internamente contendr una
complejidadelevada,perofinalizadoelcomponente,loquesenecesitaparasuusoeslas
interfaces publicas del componente (abrir un fichero, reproducirlo, subir el volumen
etc).Unaspectoimportanteesqueuncomponenteenprincipiopuedeserintercambiado
porotrosiemprequesemantengalainterfaz.

Nodo: Elemento fsico que existe en tiempo de ejecucin y que representa un recurso
computacional que, por lo general, dispone de algo de memoria y, con frecuencia, de
capacidaddeprocesamiento.Unconjuntodecomponentespuederesidirenunnodo.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 8. BREVE INTRODUCCIN A LA REPRESENTACIN UML 235

Elementos de comportamiento

Interaccin:Comportamientoquecomprendeunconjuntodemensajesintercambiadosentre
un conjunto de objetos, dentro de un contexto particular para conseguir un propsito
especfico. Involucra otros muchos elementos, incluyendo mensajes, secuencias de accin
(comportamientoinvocadoporunobjeto)yenlaces(conexionesentreobjetos)

Estado:Seutilizaparareflejarenunasecuencialosestadosporlosquepasaunobjetoouna
interaccinenrespuestaaeventozosucesosengeneral.

Elementos de agrupacin

Paquete:Esunmecanismodepropsitogeneralparaorganizarelementos(estructurales,de
comportamiento, e incluso otros elementos de agrupacin ) en grupos. Al contrario de los
componentes (que existen en tiempo de ejecucin), un paquete es puramente conceptual
(sloexisteentiempodedesarrollo).Unpaqueteformaunespaciodenombres,ysepideen
anidar,aunquedebenavistarsepasquetesmuyanidados:

Elementos de anotacin

Nota: el tipo principal de anotacin. Son comentarios que se pueden aplicar para describir,
clarificaryhacerobservacionescobrecualquierelementodeunmodelo

Elementos de relacin

Una relacin es una conexin entre elementos. Para diferenciar las distintas relaciones se
utilizan diferentes tipos de lneas. Hay cuatro tipos de relaciones: dependencia, asociacin,
generalizacinyrealizacin
236 PROGRAMACIN C++ Y COMUNICACIONES.

Dependencia: Es una relacin semntica entre dos elementos en la cual un cambio a un


elemento (el elemento independiente) puede afectar a la semntica del otro elemento
(elementodependiente).

Asociacin:Relacinestructuralquedescribeunconjuntodeenlaces,loscualssonrelaciones
entre objetos. La agregacin es un tipo especila de asociacin y representa una relacin
estructuralentreuntodoysuspartes.

Generalizacin: Es una relacin de especializacin/generalizacin en la cual los objetos del


elemento especializado (el hijo) pueden sustituir a los objetos del elemento general (el
padre).Deestaforma,elhijocompartelaestructurayelcomportamientodelpadre.

Realizacin: Es una relacin semntica entre clasificadores, donde un clasificador especifica


uncontratoqueotroclasificadorgarantizaquecumplir.Sepuedenencontrarrelacionesde
realizacinendossitios:entreinterfacesylasclasesycomponentesquelasrealizan,yentre
loscasosdeusoylascolaboracionesquelosrealizan.

8.2. Modelado estructural

ElmodeladoeslapartedeUMLqueseocupadeidentificartodaslaspartesimportantesde
un sistema as como sus interacciones. De igual forma se entiende como modelado
estructural, al modelo de los aspectos estticos de un sistema, para lo cual se utilizan
fundamentalmente como sustantivos o elementos estructrales bsicos las clases y las
interfaces as como sus relaciones entre ellas. Dado que en estos apuntes slo se pretende
darunasnocionesquenospermitanrepresentarlaestructuradeclasesyalgodelaevolucin
denuestrosprogramas,seprocedeahroaaverloselementosmscomunesenestetipode
diagramasdenominadosDCD(DiagramasdeClasesdeDiseo).

Un aspecto muy importante a la hora de realizar el modelo estructural de un sistema es el


anlisisderesponsabilidadesdelasclasesycomponentes.Entendemoscomoresponsabilidad
deunaclasealconjuntodefinesparaelcualestaclaseescreadaascomosusobligaciones.
Es muy buena prctica iniciar la programacin especificando las responsabilidades de cada
clase.Enesteprocesoesimportanteabstraerlonecesarioysuficiente,ycomoconsecuencia
hayqueevitardarexcesivasresponsabilidadesaunasolaclaseperotampocoobtenerclases
conmuypocasresponsabilidadesquenisiquieratenganentidad.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 8. BREVE INTRODUCCIN A LA REPRESENTACIN UML 237

La forma en que representamos las interacciones entre clases queda reflejado por sus
relaciones. En los diagramas de modelado sin embargo no hay porque reflejar TODAS las
relacionesexistentes,porqueenesecasoeldiagramapuedeconvertirseenalgoilegible.Las
relacionesmshabituales(yesaquendondenoscentraremosenestecurso,dejandootros
diagramasyrelacionesparamsadelante)son:

Relacindedependencia:

Uncambioenlaespecificacindelelementoindependientepuedeafectaralotroelemento
implicado en la relacin. En el ejemplo tanto la Televisin como el Grabador USAN un
determinadoCanal.Deformaquesicambialainterfazoelcomportamientodelosobjetosde
tipo Canal, habra que modificar el Grabador y la Televisin, cosaque no ocurre ensentido
contrario.Luegoexisteunadependenciaentreclases.EsimportantedestacarqueelCanalno
necesitaconoceralGrabadornialaTelevisin.EnC++estarelacinhabitualmentesetraduce
enunasentencia#includequepermiteusarlaclasedelacualsedepende.

RelacindeGeneralizacin:

Eslarelacinqueseestableceentreunconceptooelementogeneral(superclase)yuncaso
msespecficodeeseelemento(subclaseohijo).Elcasomsclaroeseldeunaclase(hija)
que hereda de otra clase (padre). Como se coment anteriormente, los objetos hijos se
podrnutilizarencualquierlugardondeaparezcaunobjetodetipopadre.
238 PROGRAMACIN C++ Y COMUNICACIONES.

RelacindeAsociacin:

Mediante esta relacin representamos como los objetos de un elemento estn conectados
conlosobjetosdeotros.Puedenestablecerseinclusorelacionesrecursivas,esdecirqueun
objetoestasociadoaunobjetodelmismotipo.

Enlasrelacionesdeasociacinsesuelenincluiradornosparafacilitarsucomprensin,ypara
diferenciarlosdistintosmodosquelaasociacinpuederealizarse:

Nombre: nombre de una asociacin que describe la naturaleza de la relacin


(contiene)
Rol:Aspectoquecadaextremopresentaalaclasequeseencuentraenelotrolado
delarelacin(unamesacontienepatas,porloquelaspatassonpartedelamesa
ylamesaeselcontenedorparalaspatas,dentrodeunarelacindecontener)
Multiplicidad: Indica cuantos objetos se pueden conectar a travs de una instancia
delaasociacin.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 8. BREVE INTRODUCCIN A LA REPRESENTACIN UML 239

Agregacin:Representaunarelacinestructuralentreiguales(sirvepararelacionar
todo/parte,peroenelquetantoeltodocomolapartetienenunavidapropia.En
C++reflejaagregacionesdeobjetosporreferencia.

Composicin:Comounaagregacinsimpleperoenestecasoeltododalavidaala
parte.EnC++,reflejaelhechodequeunobjetooconjuntodeobjetossonatributos
delobjetoqueloscontiene.


240 PROGRAMACIN C++ Y COMUNICACIONES.

8.3. Diagramas

DiagramasdeClases:

Dado que solo se trata de una breve introduccin, incluimos en este captulo uno de los
diagramasmsrecurrentementeutilizadosenDOO,eldiagramadeclasesdediseo.Eneste
semuestraunconjuntodeclases,coninterfaces,colaboracionesysusrelaciones.

Se usa fundamentalmente para modelar el vocabulario del sistema (abstracciones que son
partedelsistemaylasquenoloson)ascomomodelarcolaboracionessimples,yelesquema
lgicodeunabasededatos.Portantoseutilizanparavisualizarlosaspectosestticosdelos
bloquesdeconstruccindelsistema.

Paratrazarundiagramadeclasesenelquesereflejenlascolaboracionessimples,enprimer
lugar habr que identificar las funciones o comportamientos del sistema que se est
modelando,yquequedarnreflejadosporeldiagrama.

Paracadaelementoentonces,habrqueidentificarlasclases,iterfacesyrelacionesconotros
elementos.Habrqueirdontandoaestoselementosdecontenido,intentandoquehayaun
repartoderesponsabilidadesentreclasesyterminandoporconvertirlasresponsabilidaders
enatributos.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 8. BREVE INTRODUCCIN A LA REPRESENTACIN UML 241

DiagramasdeSequecia:

Otrodelosdiagramasmsrecurrentescuandosedeseareflejarelcomportamientodinmico
delasinteraccionesentredistintoselementoseseldiagramadesecuencia.

Semodelanlosaspectosdinmicosdeunsistemamedianteinteracciones.Unainteraccines
un comportamiento que comprende un conjunto de mensajes intercambiados entre un
conjuntodeobjetosdentrodeuncontextoparalograrunpropsitoyseutilizaparamodelar
elflujodecontroldentrodeunaoperacin,unaclase,uncomponente,uncasodeusooel
propio sistema. En este contexto, se considera un mensaje a la especificacin de una
comunicacin entre objetos que transmite informacin, con la expectativa de que se
desencadenarunaactividad.Lostiposbasicosdemensajeson:

Llamada:Invocaunaoperacinsobreunobjeto
Retorno:Devuelveunvaloralinvocador
Envo:Envaunasealaunobjeto
Creacin
Destruccin

Las interacciones aparecen en la colaboracin de objetos existentes en el ambito de un


sistemaounsubsistema,oentrelosobjetosdeunmismosubsistemaenlaimplementacin
deunaoperacin,oenelcontextodeunaclase(cmolosatributosydiferentesoperaciones
interaccionanentresparadarlugaraunanuevaoperacin).

Los objetos que participan en una interaccin son o bien elementos concretos (objetos) o
bienelementosprototpicos(clases,nodos,actoresycasosdeuso).

Undiagramadesecuenciaseraelreflejadoacontinuacin:


242 PROGRAMACIN C++ Y COMUNICACIONES.

A diferencia de lo que ocurre en un diagrama de colaboracin, destaca la ordenacin


temporaldelosmensajes.Conelselograunarepresentacinvisualclaradelflujodecontrol
alolargodeltiempo.

Algunascaractersticasdestacabesson:

Lalneadevidadelasinstanciasoclases:Representalaexistenciadeunobjetoalolargode
unperiododetiempo.Sisecreanodestruyenobjetosdurantelainteraccin,suslneasde
vida aparecen y desaparecen cuando reciben los mensajes estereotipados >>create>> y
<<destroy>>respectivamente.Lalneadevidasonlaslneasverticalesdeldiagrama.

Elfocodecontrol:elcualrepresentaelperiododetiempoduranteelcualunobjetoejecuta
unaaccin.Serepresentanconrectngulosvacossobrelalneadevida.

Asuvezlosmensajessepuedenclasificaradicionalmentecomo:

Sncronos se corresponden con llamadas a mtodos del objeto que recibe el


mensaje. El objeto que enva el mensaje queda bloqueado hasta que termina la
llamada.Serepresentanconflechasconlacabezallena.
Asncronos, estos mensajes terminan inmediatamente, y crean un nuevo hilo de
ejecucindentrodelasecuencia.Serepresentanconflechasconlacabezaabierta.

Tambinserepresentalarespuestaaunmensajeconunaflechadiscontinua

UPM-EUITI-2015. Miguel Hernando.


Departamento de Electrnica Automtica e Informtica Industrial


9. Introduccin a los Sistemas Operativos

A lo largo de la historia de las computadoras, el sistema operativo no ha dejado de


evolucionar como las necesidades de los usuarios y las capacidades de los sistemas
informticos que han cambiado. Como Weizer (1981) ha sealado, los sistemas operativos
hanevolucionadodesdeladcadade1940atravsdeunaseriedegeneracionesdistintas,
quecorrespondenaproximadamentealasdelasdcadas.

A finales de los 40's el uso de computadora estaba restringido a aquellas empresas o


instituciones que podan pagar su alto precio, y no existan los sistemas operativos. En su
lugar,elprogramadordebatenerunconocimientoycontactoprofundoconelhardware,y
enelinfortunadocasodequesuprogramafallara,debaexaminarlosvaloresdelosregistros
y pneles de luces indicadoras del estado de la computadora para determinar la causa del
falloypodercorregirsuprograma,ademsdeenfrentarsenuevamentealosprocedimientos
de reservar tiempo del sistema y poner a punto los compiladores, enlazadores, etc; para
volveracorrersuprograma,esdecir,enfrentabaelproblemadelprocesamientoserial(serial
processing).

Laimportanciadelossistemasoperativosnacehistricamentedesdelos50's,cuandosehizo
evidente que el operar una computadora por medio de tableros enchufables en la primera
generacinyluegopormediodeltrabajoenloteenlasegundageneracinsepodamejorar
notoriamente,pueseloperadorrealizabasiempreunasecuenciadepasosrepetitivos,locual
esunadelascaractersticascontempladasenladefinicindeloqueesunprograma.Esdecir,
secomenzaverquelastareasmismasdeloperadorpodanplasmarseenunprograma,el
cualatravsdeltiempoyporsuenormecomplejidadselellam"SistemaOperativo".As,
tenemosentrelosprimerossistemasoperativosalFortranMonitorSystem(FMS)eIBSYS.

Posteriormente, en la tercera generacin de computadoras nace uno de los primeros


sistemasoperativosconlafilosofadeadministrarunafamiliadecomputadoras:elOS/360de
IBM.Fueesteunproyectotannovedosoyambiciosoqueenfrentporprimeravezunaserie
de problemas conflictivos debido a que anteriormente las computadoras eran creadas para
dospropsitosengeneral:elcomercialyelcientfico.As,altratardecrearunsolosistema
operativoparacomputadorasquepodandedicarseaunpropsito,alotrooambos,pusoen
evidencia la problemtica del trabajo en equipos de anlisis, diseo e implantacin de
sistemasgrandes.

Departamento de Electrnica Automtica e Informtica Industrial


246 PROGRAMACIN C++ Y COMUNICACIONES.

Elresultadofueunsistemadelcualunodesusmismosdiseadorespatentizsuopininenla
portadadeunlibro:unahordadebestiasprehistricasatascadasenunfosodebrea.Surge
tambin en la tercera generacin de computadoras el concepto de la multiproceso, porque
debido al alto costo de las computadoras era necesario idear un esquema de trabajo que
mantuviesealaunidadcentraldeprocesamientomstiempoocupada,ascomoelencolado
(spooling ) de trabajos para su lectura hacia los lugares libres de memoria o la escritura de
resultados. Sin embargo, se puede afirmar que los sistemas durante la tercera generacin
siguieronsiendobsicamentesistemasdelote.

En la cuarta generacin la electrnica avanza hacia la integracin a gran escala, pudiendo


crearcircuitosconmilesdetransistoresenuncentmetrocuadradodesilicioyyaesposible
hablardelascomputadoraspersonalesylasestacionesdetrabajo.Surgenlosconceptosde
interfacesamigablesintentandoasatraeralpblicoengeneralysepromueveelusodelas
computadorascomoherramientascotidianas.SehacenpopulareselMSDOSyUNIXenestas
mquinas.Tambinescomnencontrarclonesdecomputadoraspersonalesyunamultitud
deempresaspequeasensamblndolasportodoelmundo.

Para finales de los 80's, comienza el auge de las redes de computadores y la necesidad de
sistemasoperativosenredysistemasoperativosdistribuidos.LaredmundialInternetseva
haciendoaccesibleatodaclasedeinstitucionesysecomienzanadarmuchassoluciones(y
problemas ) al querer hacer convivir recursos residentes en computadoras con sistemas
operativos diferentes. Para los 90's el paradigma de la programacin orientada a objetos
cobra auge, as como el manejo de objetos desde los sistemas operativos. Las aplicaciones
intentancrearseparaserejecutadasenunaplataformaespecficaypoderversusresultados
en la pantalla o monitor de otra diferente (por ejemplo, ejecutar una simulacin en una
mquinacon UNIX y ver los resultados en otra con DOS ). Los niveles de interaccin se van
haciendocadavezmsprofundos.

ActualmentepodemosresumirquedetodoesteprocesohistricoseextraequeunSistema
Operativo es un conjunto de programas que controla los dispositivos que forman el
ordenador(memoriayperifricos),administralosrecursosygestionalaejecucindelresto
del software. De alguna forma acta como enlace entre el usuario y los programas y el
hardwaredelordenador.Aunqueahoralosveremosenmsdetalle,losobjetivosbsicosde
unsistemaoperativopodranresumirseendos:

Realizarunaeficientegestindelosrecursosdelordenador
Ocultarlosdetallesespecficosdefuncionamientodelosdispositivos,consiguiendo
deestaformaunciertoniveldeabstraccinrespectodelhardware.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 247

9.1. Funciones de un sistema operativo

Elobjetivofundamentaldelossistemasoperativosesgestionaryadministrareficientemente
losrecursosdeuncomputador,permitiendolaejecucindeprogramassinqueseproduzcan
conflictosenelaccesodelosrecursosutilizados,ysinqueningnprogramamonopoliceun
mediodeterminado.

Elsistemaoperativoefecta,entreotras,lassiguientesfunciones:

Desdeelpuntodevistadelusuariocomn:

Comandosparaentraryabandonarelsistema.

rdenesparamodificarlaclavedeentrada.

Comandosparadefinirlascaractersticasdeunterminal.

Establecerlasrutasdebsqueda.

Ejecucinycontroldeprogramas.

Paraestablecerprioridadesenlosprocesos.

Paralamanipulacindeficherosysubdirectorios.

Paralainformacindeestado.

rdenesdeadministracin

Desdeelpuntodevistadelprogramadordeaplicaciones:

Creacindeprocesosyborrado.

Comunicacinysincronizacindeprocesos.

Actividadesdetemporizacin.

Gestinyusoderecursos.

Asignacinyliberacindememoria.

Establecimientodeprioridades.

Desdeelpuntodevistadelaseguridaddelsistema:
248 PROGRAMACIN C++ Y COMUNICACIONES.

ProteccindeE/S:Paraconseguirlasediferenciandosmodosdeoperacin:modo
usuarioy modo supervisor. Elcambio deun modo a otro secontrolaporparte del
S.O.,siendosloposibleelcambioamodosupervisordesdeunusuariopormediode
llamadasafuncionesdelS.O.Deestemodociertasinstruccionessloseejecutarn
enmodosupervisoryelS.O.PodrcontrolarcomoserealizalaE/S.

Proteccin de la memoria: para que la proteccin de memoria sea eficiente, se


necesita generalmente recursos hardware por los que se controla el acceso a la
memoria.Laimplementacindeestecontrol,varadependiendodelagestinquese
haga.

De forma resumida podemos establecer las funciones del sistema operativo en base a los
gestoresbsicosdelosquehabitualmenteconsta:

1. Gestin de la CPU o gestin de procesos: Responsable de iniciar los programas,


finalizarlos, interrumpirlos, reanudarlos, darles tiempo de CPU etc. Tambin debe
permitirlacomunicacindelaCPUconelexterior.

2. Gestin de memoria: Controla la cantidad de memoria que necesita cada


programa.Permitelacoexistenciadevariosprocesosenmemoriacentral.

3.GestindeE/S:Losprogramasaccedenalosperifricosdeformasencilla.

4.Gestindedispositivosdealmacenamiento:organizalainformacinenarchivosy
carpetasypermiteelaccesorpidoyeficienteadichainformacin.

5. Intrprete de comandos: Las rdenes del usuario son interpretadas y llevadas a


cabo.

Gestin de procesos
Estrategiasparalagestindeprocesos

Existendosformasbsicasdetrabajarconuncomputador:porlotesydeformainteractiva.
En esta ltima, la CPU est constantemente atendiendo al usuario, y en cualquier caso,
aunquelaCPUtengavariosprocesosenmemoria,setienelaimpresindequeelusuarioest
trabajando directamentecon elcomputador. Los primeros sistemas operativos funcionaban
como monotarea o serie; es decir, hasta que no finaliza la ejecucin de un programa no
empiezaaejecutarseotro.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 249

Un sistema operativo multitarea aprovecha los tiempos inactivos de la CPU, que


habitualmente son provocados por los perifricos; as mismo, se deben aprovechar los
espacios de la memoria principal no ocupados por los procesos. La multitarea consiste, en
esencia, en cargar en la memoria principal varios procesos e ir asignando la CPU, de forma
alternativa, a los distintos procesos que estn en ejecucin, de forma que se aproveche al
mximolaCPUyquevariosprocesosvayanavanzandoensuejecucin,sinnecesidaddeque
finalicecompletamenteunoparainiciarlaejecucindeotro.Estemododefuncionamiento
tambinsedenominaejecucinconcurrentedeprocesos

Segnelsistemaoperativoenparticularsedefinendiferentesestadosparaunproceso.Los
estados bsicos son activo, bloqueado y preparado. Se dice que un proceso est en estado
activo, o de ejecucin, cuando la CPU est ejecutando sus instrucciones. Se dice que un
procesoentraenestadodebloqueocuandolaCPUnopuedecontinuartrabajandoconl,a
causadetenerqueesperaralarealizacindeunaoperacindeentrada/salida,oaalgnotro
eventodenaturalezasimilar.Sedicequeunprocesoestenestadopreparado,oejecutable,
cuandolaCPUpuedeiniciarocontinuarsuejecucin.

Enlossistemasmultitarea,cuandounprocesoentraenestadodebloqueado,unmdulodel
sistemaoperativodenominadodistribuidor(dispacher)pasaelturnodeejecucinaunode
losprocesosdelamemoriaprincipalqueestenestadopreparado.Paraello,seproduceuna
interrupcin que provoca una conmutacin de contexto entre procesos. El cambio de
contexto implica almacenar en una zona de la memoria principal toda la informacin
referente al proceso interrumpido. Esta informacin, denominada contexto de un proceso,
est referida a los contenidos de los registros de la CPU, indicadores de los biestables,
punterosaarchivosdediscos,contenidodelapila,etc.;ascomo,informacindelastablas
referentesalestadodelosprocesosenmemoria.Elcambiodecontextosuponeunconsumo
detiempodeCPUporpartedeldistribuidor.Cuandoeldistribuidorvuelvaadarelturnoal
proceso interrumpido, por haber finalizado la operacin de E/S; es decir, haber salido del
estado de bloqueado y entrado en el de preparado, debe producirse la recuperacin de
contexto en el sentido contrario al anterior, ya que, tiene que restituirse desde la zona
auxiliar de memoria los contenidos de los registros salvados, quedando la CPU tal y como
estabaenelinstantequeinterrumpiesteproceso,ypreparada,portanto,paraproseguirsu
ejecucin.Estasoperacionesocurrensucesivamenteparacadaunodelosprocesosexistentes
enmemoriaprincipal.

Eltipodemultitareadescritoanteriormente,enelqueunprocesodejadeejecutarseporla
CPUcuandoseproduceuneventorelativoaunaE/Sosimilar,tieneelinconvenientedeque
un proceso que contiene muchas operaciones de procesamiento y pocas E/S, puede
monopolizar la CPU, hasta que finalice su ejecucin. Los sistemas multitarea no
necesariamente deben esperar a que un proceso pase al estado de bloqueado para que el
250 PROGRAMACIN C++ Y COMUNICACIONES.

distribuidor lo interrumpa y d el turno a otro proceso que est preparado. El sistema


operativo debe implementar los correspondientes mecanismos para permitir la ejecucin
intermitentedetodossusprocesos.

Unsistemamultitareadebedisponerdelastcnicasapropiadasdeproteccindememoriay
de control de concurrencias para permitir el acceso compartido a dispositivos de E/S y
archivos. Un sistema multiusuario prev el uso compartido de distintos usuarios, debiendo
resolverse cuestiones como la identificacin, autentificacin, privilegios, y control de todos
losusuarios.

El concepto de tiempo compartido ("time sharing") es una forma de gestionar la


multiprogramacinparaobtenersistemasmultiusuario,querequierentiemposderespuesta
adecuados,dandolailusinacadausuarioqueesttrabajandoenexclusivaconlamquina.
En realidad, no se trabaja en exclusiva con el computador, ya que, una CPU slo puede
ejecutar un proceso en un instante dado. Con rigor se dice que la CPU est ejecutando
procesosconcurrentemente.Esdecir,enundeterminadointervalodetiempodeterminadola
CPUestejecutandoalternativamentevariosprocesosubicadosenlamemoriacentral.

Las tcnicas de tiempo compartido requieren elegir, adecuadamente, un algoritmo de


planificacin de multitarea. Si existen varios procesos preparados en memoria, el problema
quedeberesolvereldistribuidoreselegiraculdeellosdarleelturnoenlaCPU,esdecir,
quprocesodebecambiaraestadoactivo.Elmdulodelsistemaoperativoqueseencarga
desolventaresteproblemasedenominaplanificador(scheduler).Esteprocesoselecciona
elprocesoquevaaserejecutadoporlaCPUenbaseaunalgoritmopreestablecido.

Unodelosalgoritmosdeplanificacindemayorinters,porsuantigedad,sencillezyamplio
uso,eseldepeticincircular(roundrobin).Estealgoritmo,tambinllamadocooperativo,
hasidousadoporWindowsyMacintosh.Conelalgoritmodepeticincircular,acadaunode
los procesos en memoria, se le asigna un intervalo de tiempo fijo, o periodo, llamado
quantum. El objetivo de este algoritmo es cambiar de contexto de un proceso a otro, de
formarotatoria,conformesevanconsumiendosuquantum.

Enlossistemasoperativosdetiempocompartidosecambiadecontexto,noslocuandosele
acaba un quantum a un proceso, sino tambin, en el instante en que quede bloqueado; es
decir,eldistribuidorprovocaunaconmutacindecontextodelprocesoPialPjydaelturnoa
Pjsiemprequesecumplaunadelosdoscondicionessiguientes:

a) ElprocesoPiagotesuquantum.

b) ElprocesoPisebloquee.

siendoPjeselsiguienteprocesopreparadoquelecorrespondeelturno.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 251

Laasignacindequantumsuelehacerseconayudadeungeneradordepulsossincronizado
con la frecuencia de la red de suministro de energa elctrica, 50 Hz en Europa, 60 Hz en
Estados Unidos. Transcurrido el perodo de tiempo correspondiente, 20 ms, o 16.7 ms, se
produceunainterrupcinquelanzaaejecucinelmdulogestordelrelojdetiemporeal,que
entreotrosobjetivossirvedereferenciaparagenerareltiempoasociadoalquantum.


Graficoquemuestraelcomportamientodeunsistemadeplanificacin"roundrobin"paradaratencina
procesos(AE)quesevanejecutandodeformadinmica.Ennegrosepintaelestadodeespera.

La eleccin del tiempo de quantum es problemtica, ya que, si es demasiado pequeo hay


que hacer muchas conmutaciones de contexto y la eficiencia de la CPU es baja, pero si es
grandelostiemposderespuestaparacadausuariopuedenllegarasermuybajos,sihubiese
ejecutndose concurrentemente 20 procesos, al pulsar una simple tecla podra obtenerse
respuestastanlentascomo5segundos.

Otroalgoritmodeplanificacindeprocesoseseldeasignacindeprioridades,usadoporlos
sistemas operativos OS/2, UNIX y WindowsNT. Consiste en definir prioridades para los
procesos,pudiendoelplanificadormodificardichaprioridaddinmicamente.Eldistribuidor
da el turno al proceso preparado que tenga asignada la mayor prioridad. Existen varios
criteriosdeasignacindeprioridades;aspues,paraqueeldemayorprioridad,yportanto
activo,nomonopoliceelusodelaCPU,acadainterrupcindelrelojdetiemporealselebaja
laprioridaddelprocesoactivo.

Pueden existir prioridades estticas, dadas en funcin de la relevancia de los usuarios, o


dinmicas.Lafinalidadesobtenerunaprovechamientoequilibradodetodoslosrecursosdel
computadoryunamayorproductividad;esdecir,mayornmerodeprogramasejecutadosen
unperododeterminadodetiempo.Setratadedarmayorprioridadalosprocesosquetienen
ms tiempo de E/S. Una forma de llevar a la prctica este criterio es dar al proceso P, la
prioridad1/fisiendofilafraccindetiempodelltimoquantumasignadoaPiquerealmente
haconsumidolaCPU.
252 PROGRAMACIN C++ Y COMUNICACIONES.

Otros sistemas operativos de gran inters son los sistemas operativos de tiempo real. El
conceptodetiemporealhacereferenciaaqueelcomputadordebegarantizarlaejecucinde
unproceso,oobtencindeunresultadodentrodeunlmitedetiempopreestablecido.Este
tiempopuedeserpequeoogrande,dependiendodelaaplicacin.Lossistemasdetiempo
realseusanampliamenteencontrolindustrial,equiposdeconmutacintelefnicas,control
de vuelo, aplicaciones militares, simuladores, etc. Los sistemas operativos de tiempo real
debensercapacesderesponderaloseventos,ointerrupciones,quesepuedanproducirde
forma asncrona, a veces miles por segundo, en unos plazos de tiempo previamente
especificados. Frecuentemente son sistemas multitarea en los que los algoritmos de
planificacinsondeltipodederechopreferencial,conlosquesiempreseejecutalatareade
mayor prioridad y no se interrumpe hasta que finalice, a no ser que se genere otra de
prioridad mayor. El estndar POSIX tiene definidas unas extensiones de tiempo real,
establecindosediferentesnivelesderequisitos.

Estadosdeunproceso

Unproceso,desdeelpuntodevistadesuejecucin,puedeencontrarseenunade
diversassituacionesoestados,loscualesserepresentanesquemticamenteenlafigura9.1.
La mayora de ellos ya han sido analizados anteriormente, por lo que se resumirn muy
brevemente. Adems, cada sistema operativo implementar un determinado conjunto de
estados y unas condiciones de paso de un estado a otro, por tanto el funcionamiento aqu
descrito pretende ser una referencia para la comprensin de la problemtica relativa a la
gestin de procesos. Un proceso nonato es aquel que no ha iniciado su ejecucin. Un
ejemploesunprogramaretenidoenunacolaesperandoaqueelplanificadordetrabajosyel
distribuidorledenpasoaejecucin.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 253

Figura 9. 1. Estados de un proceso


Unprocesoestenestadopreparado,listooejecutable,cuandoseencuentraenmemoria
principal,sinoperacionesdeE/Spendientes,yaptoparaentrarenejecucin,enelinstante
queeldistribuidorleasignelaCPU.Elestadodeejecucino activocorrespondealproceso
queenesemomentoestsiendoatendidoporlaCPU.Unprocesoactivosaledelestadode
ejecucin, en un sistema de tiempo compartido, cuando pasa a estado de bloqueado o el
distribuidorleinterrumpeparaatenderaotrodemayorprioridad,oquelecorrespondeel
turnodeejecucin.

Delestadodebloqueadosepuedepasaralestadopreparadocuandoacabalaoperacinde
E/Spendiente,oseleasignaelrecursoesperado.Tambin,esnecesariotenerencuentaque
algunossistemasoperativosrealizanintercambioentrelamemoriaprincipalyeldisco,locual
lespermitelaejecucinconcurrentedemsprocesosdelosqueadmitelamemoriaprincipal,
ya que un proceso puede ser trasvasado a disco, definindose por tanto el estado de
bloqueadointercambiado,obloqueadoendisco.Unejemplodeprocesobloqueadoesaquel
quesolicitaaloperadordelcomputadormontarunadeterminadacintay,sinohaymemoria
suficienteparalosotrostrabajosenprogreso,lotrasvasaadisco.Silacargadeprocesoses
grande,inclusolosprocesospreparadospuedentrasvasarseadisco,pasandoasalestadode
preparadointercambiadoopreparadoendisco.

Cuandodesdeunterminalinteractivoseactivalacomunicacinconelcomputador,oseleda
la vez a un proceso de la cola serie, el proceso correspondiente entra en estado de
preparado, desplazndose por los estados del diagrama de la figura 9.1. Cuando finaliza la
ejecucin de un proceso o se detecta un error grave en l, el proceso pasa a estado de
muerto,liberandoelsistemaoperativolazonadememoriaqueocupaba.

Un punto importante en la gestin de procesos es la relacin que se establece cuando un


proceso crea otro, dicindose que un proceso (P) puede generar a otro proceso, llamado
proceso hijo (H). Puede ocurrir, por ejemplo, que el objetivo del proceso hijo sea generar
cierta informacin para el padre y que, por problemas de sincronizacin entre ambos
procesos, finalice la ejecucin de P sin que el padre haya captado la informacin
correspondiente.Enestecasosedicequeelpadreestaenestadozombie;osea,permanece
enmemoria,ynodebeestarenestadodepreparado,nipasaralisto,niabloqueado,yaque
finaliz su ejecucin, del estado zombie debe pasar al estado de muerto, cuando finaliza la
ejecucindetodoslosprocesoshijos.
254 PROGRAMACIN C++ Y COMUNICACIONES.

Gestin de la memoria
Enlossistemasoperativosdemonoprogramacinlamemoriaprincipalsepuedeorganizarde
diversasmaneras.Elsistemaoperativopuedeocuparlasprimerasposicionesdememoria,o
lasltimas,oinclusopartedelsistemaoperativopuedeestarenlazonaRAMdedirecciones
bajas,yotrapartedel,comosonlosgestoresdeperifricos,oelcargadorinicial,pudieran
encontrarseenROMenlasdireccionesaltas.Estaltimasituacinsecorrespondeconlade
los antoguos PCs compatibles, en los que la ROM contiene el sistema bsico de entradas y
salidasoBIOS(BasicInputOutputSystem,SistemaBsicodeEntradasySalidas).

Encualquiercaso,cuandoelusuariodaunaorden,sielprocesoquelaimplementanoesten
memoria, el intrprete de comandos del sistema operativo se encarga de cargarlo en
memoriadesdedisco,yeldistribuidordapasoasuejecucin.Cuandofinalizaelproceso,el
sistema operativo visualiza el indicador de peticin de orden y espera a que se le d una
nueva orden, en cuyo caso libera la zona de memoria ocupada, sobreescribiendo el nuevo
programasobreelanteriorproceso.

Enunsistemademultiproceso,cuandounprogramasecargaenmemoriaparaserejecutado,
ocontinuarsuejecucin,elsistemaoperativoleasignaunadireccinbase,deacuerdocon
losespacioslibresdememoria,ytransformadireccionesvirtualesendireccionesfsicas.Estas
transformacionessuelenserefectuadasporcircuitosespecializadosqueconstituyenlaMMU
(MemoryManagementUnit,UnidaddeGestindeMemoria),queenlaactualidadsesuele
integrarenelmismochipdelaCPU.

La asignacin de memoria para distintos procesos ejecutndose concurrentemente suele


hacerse, dependiendo del sistema operativo, de alguna de las formas que se indican en los
epgrafessiguientes:

Particionesestticas.

Particionesdinmicas.

Paginacin.

Segmentacin.

Memoriavirtual.

Particionesestticas

La tcnicadeparticiones estticas consiste en dividir lamemoria en cierto nmero


debloquesozonas,cadaunadelascualescontendrunproceso.Lasdireccionesdebaseson

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 255

lasdireccionesdecomienzodecadaparticin.Eltamaodelaparticinesdeterminadopor
eloperadoroporelsistemaoperativo.Tamaosusualesson8K,16K,32K,o64K.

El sistema operativo mantiene una tabla en la que cada fila corresponde a una
particin, conteniendo la posicin base de la particin; su tamao, no todas las particiones
tienenporquseriguales;yelestadodelaparticin,ocupadaonoocupada.Elplanificador
de trabajos, una vez que una particin est libre, hace que se introduzca el programa de
mximaprioridadquehayaenlacoladeesperayquequepaendichaparticin.Sielespacio
deunaparticinesmpalabrasyelprogramaocupanposiciones,severificarsiempreque:n
m.

Particionesdinmicas

Lautilizacindeparticionesdinmicassebasaenquelosprogramassonintroducidosporel
sistema operativo inicialmente en posiciones consecutivas de memoria, no existiendo, por
tanto,particionespredefinidas.Elsistemaoperativopuedegestionarelespaciodememoria
usando una tabla de procesos, en la que cada lnea contiene el nmero de proceso o
identificativo del mismo, el espacio que ocupa y la direccin base. Existe una tabla
complementariaalaanteriorconlosfragmentosohuecoslibres.Elplanificadordetrabajos
peridicamente consulta la tabla, introduciendo en memoria los programas que quepan en
losfragmentos.

Al iniciarse una sesin de trabajo se carga el primer programa, dejando un fragmento libre
donde se pueden incluir otros programas. Al finalizarse los procesos, el nmero de
fragmentoscreceryelespaciodisminuir,llegandounmomentoenqueelporcentajede
memoria aprovechado es muy reducido. El problema puede resolverse haciendo una
compactacin. Esta consiste en agrupar todos los fragmentos cuandoacaba la ejecucin de
un proceso, quedando as slo uno grande. La compactacin se efecta reubicando los
procesosenejecucin.

Paginacin

Conesteprocedimientolamemoriaprincipalseestructuraenmarcosdepginasdelongitud
fija,tambindenominadosbloques,quesuelenserde512bytes,1Kbytes,2Kbytes,4Kbytesu
8 Kbytes. De esta forma,por ejemplo, la memoria de uncomputadorde 256Kbytespodra
quedar dividida en 64 marcos de pgina de 4Kbytes cada uno. Cada marco de pgina se
identificaconunnmerocorrelativo,enelcasoanteriorde0a63.Asimismo,losprocesosde
256 PROGRAMACIN C++ Y COMUNICACIONES.

los usuarios se dividen en zonas consecutivas, denominadas pginas lgicas o virtuales, o


simplementepginas. Paraun sistemadado, lacapacidadde pginay marco de pgina son
coincidentes,deformaquecadapginasememorizaenunmarco.

Elfundamentodelapaginacinresideenquenoesnecesarioqueunprocesosealmaceneen
posicionesconsecutivas dememoria. Las pginas se almacenan enmarcos depgina libres,
independientemente de que estn o no contiguos. Cada marco de pgina contiene
instrucciones consecutivas. Una instruccin de un proceso se localiza dando el nmero de
marco y la direccin relativa dentro de l. El sistema operativo, en lugar de mantener una
tabladeprocesos,comoenelcasodeparticionesdinmicas,mantienetrestiposdetablas:

1.Tabladelmapadememoria.Contienetantasfilascomomarcosdepgina.Seindica
elidentificadordelprocesoqueestencadabloquey,ensucaso,siestlibre.

2. Tabla de procesos. Cada fila contiene informacin referente a cada proceso en


ejecucin.Seindicatamaoylaposicindememoriadondeseencuentralatabla
mapadepginasdeeseproceso.

3.Tabladelmapadepginas.Hayunaporproceso,ycontieneennmerodemarco
dondeseencuentracadaunadesuspginas.Lalongituddecadatablaesvariable,
dependiendo del nmero de pginas; es decir, depende del tamao de cada
proceso.

LastablasdepaginacinotablasdepginassonunaparteintegraldelSistemadeMemoria
Virtual en sistemas operativos, cuando se utiliza paginacin. Son usadas para realizar las
traducciones de direcciones de memoria virtual (o lgica) a memoria real (o fsica) y en
generalelsistemaoperativomantieneunaporcadaprocesocorriendoenelsistema.

Encadaentradadelatabladepaginacin(eninglsPTE,Page TableEntry)existeunbitde
presencia, que est activado cuando la pgina se encuentra en memoria principal. Otro bit
que puede encontrarse es el de modificado, que advierte que la pgina ha sido modificada
desdequefuetradadeldisco,yporlotantodeberguardarsesieselegidaparaabandonar
la memoria principal; y el bit de accedido, usado en el algoritmo de reemplazo de pginas
llamado Menos Usado Recientemente (LRU, least recently used). Tambin podran haber
otrosbitsindicandolospermisosquetieneelprocesosobrelapgina(leer,escribir,ejecutar).

Dado que las tablas de paginacin pueden ocupar un espacio considerable de la memoria
principal,estastambinpodranestarsujetasapaginacin,loquedalugaraunaorganizacin
paginadademltiplesniveles(otabladepginasmultinivel).Enlossistemasconuntamao
de direcciones muy grande ( 64 bits ), podra usarse una tabla de pginas invertida, la cual
utilizamenosespacio,aunquepuedeaumentareltiempodebsquedadelapgina.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 257

LastablassonmantenidasporelsistemaoperativoyutilizadasporlaUnidaddeGestinde
Memoria (MMU) para realizar las traducciones. Para evitar un acceso a las tablas de
paginacin, hay un dispositivo llamado Buffer de Traduccin Adelantada (TLB, Translation
LookasideBuffer),acelerandoelprocesodetraduccin

Segmentacin

Se denomina segmento a un grupo lgico de informacin, tal como un programa, una


subrutina,unapila,unatabladesmbolos,unarrayounazonadedatos.Estaunidadnoesde
un tamao preestablecido, pues depende del programa de que se trate. Un programa
ejecutable,listoparaserejecutadoporlaCPU,estformadoporunacoleccindesegmentos.
As pues,un programa se considera dividido en segmentos, unos corresponderan al cdigo
ejecutable,yotrosalosdatosutilizados.

La gestin de los segmentos la realiza el sistema operativo, como con las particiones
dinmicas, slo que cada particin no corresponde a un proceso sino a un segmento. El
sistemaoperativomantieneunatablaconlossegmentosdeunproceso,deformasimilarala
de pginas. Como el tamao de los segmentos es variable, antes de realizar un acceso a
memoria se comprueba que el desplazamiento no supere al tamao del segmento, para
protegerlaszonasdememoriaocupadasporotrosegmento.

Microprocesadores como el 80286 utilizan el direccionamiento con segmentacin. Tambin


esusualcombinarlasegmentacinconlapaginacin,taleselcasodeloscomputadoresIBM
370,GE645,microprocesadoresdeIntelcomoel80386yposteriores,etc.

Lasegmentacinpermitequeciertosprocesospuedancompartircdigo,rutinas,odatos,sin
necesidaddeestarduplicadosenmemoriaprincipal.Aspues,siseisusuariosestnutilizando
interactivamente un procesador de textos determinado, no es necesario que estuviesen
cargadasenmemoriaseiscopiasidnticasdelcdigodelprogramaprocesadordetextos.El
cdigodelprogramaestaraunasolavez,yelsistemaoperativoselimitaraaanotarenlas
tablasmapasdesegmentosdecadaunodelosprocesosladireccindondeseencuentrael
cdigo. Por tanto, en un momento dado, en memoria existiran: segmentos asignados a
trabajosconcretos,segmentoscompartidos,ybloqueslibresdememoria.

Memoriavirtual

Lamemoriavirtualpermitealosusuarioshacerprogramasdeunacapacidadmuysuperiora
laquefsicamentetienelamemoriaprincipaldelcomputador.Enrealidad,lamemoriavirtual
haceposiblequelacapacidadmximadelosprogramasestlimitadaporelespacioquesele
258 PROGRAMACIN C++ Y COMUNICACIONES.

reserveendisco,ynoporeltamaodelamemoriaprincipal.Endefinitiva,lossistemascon
memoria virtual presentan al usuario una memoria principal aparentemente mayor que la
memoriafsicareal.

Porotraparte,lamemoriavirtualpermiteaumentarelnmerodeprocesosenlamemoria
principal en ejecucin concurrente, ya que con ella slo es necesario que est en memoria
principal untrozo mnimo de cada proceso,yno elproceso completo. Para lagestinde la
memoriavirtualsueleutilizarsealgunadelasanteriorestcnicasdegestindelamemoria:

gestindememoriaporpginas,

gestindememoriasegmentada,

gestindememoriasegmentadapaginada.

La memoria virtual se basa en que las instrucciones de un programa que se ejecutan


sucesivamente,enuncortointervalodetiempo,estnendireccionesmuyprximas,locual
seconocecomoprincipiodelocalidadtemporal;yquelosprogramassuelenestarredactados
con gran linealidad; es decir, no suelen abundar los saltos entre posiciones de memoria
distantes,queconstituyeelprincipiodelocalidadespacial.

Enunsistemadememoriavirtualsemantieneendiscounarchivoconlaimagendelproceso
completo,queesttroceadoenpginasosegmentos,dependiendodelmtodo.Encambio,
enlamemoriaprincipalnicamentedebeestarlapgina,osegmento,queenesemomento
deba estar enejecucin, intercambindosepginas entredisco y memoria principal cuando
seanecesario,locualseconoceporswapping.

Lagestindememoriavirtualsegmentadaesmscomplejaqueladeltipodepaginacin,ya
que,lossegmentossondetamaovariableysonmsdifcilesdegestionar.Laspginas,por
el contrario, son de capacidad constante y preestablecida. Por ello, lo habitual es utilizar
gestindememoriaporpaginacinoporsegmentospaginados.

Lamemoriavirtualconpaginacincombinalastcnicasdepaginacineintercambio.Porlo
general, se utiliza un mtodo de intercambio perezoso (lazzy swapper), nicamente se
lleva a memoria una pgina cuando es necesaria para algn proceso, de esta forma, el
nmerodeprocesosenejecucinconcurrentepuedeaumentar.

Unodelostemasdemayorintersparaeldiseodelsistemadegestindememoriavirtual
eslabsquedadealgoritmoseficientesparadecidirqupginadebesustituirseencasode
fallo de pgina, ya que cada fallo de pgina supone una prdida de tiempo de la CPU, que
puede hacer disminuir considerablemente la productividad del computador incluso aunque

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 259

todalagestinserealiceconhardwareespecfico.Elalgoritmodescritoenelprrafoanterior,
queutilizancampodenmerosdereferencias,esdeltipoLRU.Losalgoritmosmsconocidos
sonlossiguientes:

FIFO(Firstinfirstout,PrimeroenEntrarPrimeroenSalir).Sebasaensustituirla
pginaquellevemstiempoenmemoria

LRU(LeastRecentlyUsed,ltimoRecientementeUsado).Enestecasosesustituye
lapginamenosrecientementeusada.Sebasaenelprincipiodelocalidadtemporal,
yaque,suponequelapginautilizadahacemayortiempoesmenosprobablequese
useprximamente.

NRU(NoRecentlyUsed,NoRecientementeUsado).Unadelasmltiplesformasde
implementar este tipodealgoritmo consiste enutilizar unbit de referencia que se
ponea1cadavezqueseusalapgina.Unpunterorecorrecircularmentelatablade
marcos de pgina. Inicialmente, el puntero est detenido en un marco de pgina,
cuando se tiene que desalojar una pgina analiza el bit de referencia del marco al
que apunta, si es 1, lo pone a 0 y avanza apuntando a los siguientes procesos,
cambiandolosbitsdereferenciade1a0,hastaqueencuentreunapginaconelbit
dereferenciaa0,encuyocasolaeliminadelamemoriaysedetieneenlaposicin
siguientedelatabla,hastaquesenecesitedesalojarunanuevapgina.

Gestin de entradas y salidas


Uno de los objetivos fundamentales del software de entradas y salidas (E/S) del sistema
operativo,esquelosprogramadoresdeaplicacionespuedanrealizarlasoperacionesdeE/S
conindependenciadeldispositivo,transparentealascaractersticasparticularesdelhardware
queseutiliza.Estopermitehacerprogramas
que utilicen dispositivos y archivos de forma
abstracta, sin necesidad de particularizarlos
para los dispositivos donde estn
almacenados dichos archivos; como son
disquetes, discos duros, cintas DAT, etc.
Tambin, la independencia del dispositivo
implica que se pueda asociar a cada uno de
ellos un nombre simblico, siendo las reglas
de denominacin uniformes para todos. En
UNIX, por ejemplo, los dispositivos se
referenciancomosifuesenarchivos.

Figura 9. 2 . Gestin de E/S


260 PROGRAMACIN C++ Y COMUNICACIONES.

Se comprende mejor como acta el software de E/S utilizando un modelo conceptual por
capas.Elnivelinferioreselhardware,queeselquerealmenteejecutalaoperacindeE/S,y
el nivel superior los procesos de los usuarios. Resumidamente, las funciones de cada nivel
sonlasqueseindicanenlafigura9.2.

El nivel ms cercano al usuario es el nivel de procesos. Cuando se dispone de un


programa con E/S en la fase de creacin se une con procedimientos de biblioteca que
gestionandichasentradasysalidas.Elobjetivobsicodeestosprocedimientosessituarlos
parmetros en la zona de memoria adecuada y hacer las correspondientes llamadas al
sistema operativo. El sistema operativo puede gestionar los dispositivos de E/S
considerndolosdeunadelastresformassiguientes:

1. Dispositivosasignados.Consisteenasignarciertosdispositivosaunprocesodurante
la duracin del trabajo; por ejemplo, un teclado, una impresora, una lectora de
tarjetas.

2. Dispositivos compartidos. As se asignan los dispositivos que pueden compartirse


cocurrentementeporvariosprocesos,comoeselcasodediscosocintasmagnticas.
Si dos o ms procesos requieren a la vez la misma unidad de cinta magntica, el
sistemaoperativodebeevitarlosconflictosquepudiesenplantearse.

3. Dispositivos virtuales. Se consigue que dispositivos en principio asignables que


puedan compartirse, optimizndose el rendimiento del sistema. Esta tcnica se
describeconmsdetalleacontinuacin.

ElsistemaqueimplementadispositivosdeE/Svirtualessesueledenominarspooler
(SimultaneousPeripheralOperationsOnLine,OperacionesSimultneasSobrePerifricosEn
Lnea).Laideadelgestordedispositivosvirtualesseaplicaaperifricoslentos,yconsisteen
interponer entre el proceso y el perifrico lento un dispositivo de memoria auxiliar rpido.
Usualmente, el perifrico lento es una impresora, un registrador grfico, etc., y el rpido
podraserundisco.Seobservaquelosmdulosspoolhacenquelosprocesostrabajencon
losperifricosdeE/Scomoarchivosendisco,aprovechndosedelasmejoresprestacionesde
este tipo de perifrico. Puede decirse que el disco se comporta como si se tratara de un
dispositivodeE/Stipodigitalizadoroimpresora,esdecir,eldiscosoportadispositivosdeE/S
virtuales.

En el nivel de software independiente del dispositivo se incluyen funciones tales


como la denominacin de dispositivos, que consiste en la traslacin del nombre lgico al
nombrefsico;sistemasdeproteccindedatos,solicitandocontraseadeaccesosytipode
acceso:leer,leeryescribir,etc.;agrupacindelainformacineneltamaorequeridopara
formar bloques fsicos; gestionar la memoria intermedia entre perifricos y CPU; y la
recuperacindeciertotipodeerrores.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 261

Elsiguienteniveleseldegestindeperifricos,cadatipodeperifricotieneunas
caractersticas propias y va conectado a travs de un controlador fsico. Cada perifrico es
utilizado por un programa gestor, que se encarga de programar el controlador y traducir
peticiones abstractas del nivel de software independiente del dispositivo a cdigo
directamenteinterpretableporelhardware,yenviarloaunalistadepeticiones.Porejemplo,
enelcasodeunaunidaddedisco,alpresentarseelgestorcorrespondienteaunaoperacin
deleerunsector,elgestordebecomprobarsieldiscoestarrancado,posicionarelbrazoen
elcilindrocorrespondiente,inicializarelcontroladordeDMA,transmitirelmarcodepgina
de informacin, etc. En realidad, los gestores de perifricos son los nicos programas que
debentenerencuentalaspeculiaridadesconcretasdelosdispositivos.

Comoejemploparticular,enelcasodeundiscoparaconseguirmayoresvelocidades
es habitual leer fsicamente cilindros completos, en lugar de sector a sector. Una vez
localizadoelcilindrosepuedeleerelcilindrocompletoalavelocidadderotacindeldisco.La
informacin del cilindro se almacena en la cach de disco de forma que si el programa del
usuario ordena la lectura sucesiva de sectores de un mismo cilindro, cosa muy probable a
causadelalocalidadespacialdelosdatos,nosetendrnqueconsumirtiemposadicionales
delatenciaparaaccederalosdistintossectores.Estatcnicaesimplementadaporelnivelde
gestordelperifricooinclusopuedeserincluidaenelnivelhardware,elcontroladordedisco
puedeincluirlamemoriacach.NoseincluyeenelniveldesoftwaredeE/Sindependiente,
yaquesteconsideraaldiscocomounconjuntosucesivodebloques.

Elsiguienteeselniveldegestindeinterrupciones.Esteeselniveldesoftwarede
E/Squeestencontactodirectoconelhardware.CuandounprocesotieneunaE/Sseinicia
laoperacin,pasaalestadodebloqueado,yesperahastaqueacabelaoperacindeE/S.En
lamayoradelosdispositivosdeE/Slasoperacionesdelecturayescrituraseinicianyfinalizan
por medio de interrupciones. Cuando se produce la interrupcin final un proceso debe
cambiarelestadodelprocesoquehafinalizadolaoperacindeE/S;portanto,dichoproceso
pasar de bloqueado a preparado. Los gestores de interrupciones son pequeos
procedimientos que gestionan y lanzan la ejecucin de los programas correspondientes al
nivelinmediatosuperior.

Gestin de archivos.
Unarchivopuedeestructurarseendistintossoportesfsicos,dependiendodelusoo
capacidadquevayaatener.Sedistingueentreunnivelfsico,msomenosComplejo,ynivel
lgico,queproporciona una utilizacin adecuada para el usuario. El sistema operativo hace
posibleutilizarestaltima,haciendodeinterfazentrelosdos.Enefecto,desdeelpuntode
vista hardware, para almacenar datos o programas slo existen direcciones fsicas. En un
262 PROGRAMACIN C++ Y COMUNICACIONES.

disco toda informacin se graba o lee en bloques (clusters), indicndose el nmero de


unidad, la superficie, la pista, y el sector. El sistema operativo posibilita que el usuario no
tenga que utilizar direcciones fsicas, pudindose actuar sobre un archivo y almacenar o
recuperar informacin sin ms que indicar su nombre y utilizar ciertas instrucciones del
lenguajedecontroldelsistemaoperativo.

Sobre la estructura del hardware citada anteriormente el sistema operativo


construye dos abstracciones: la de archivo y la de directorio, denominndose sistema de
archivosalconjuntodemdulosdelsistemaoperativoqueseencargadegestindearchivos
ydirectorios.

Gestindearchivos

El concepto de archivo permite aislar al usuario de los problemas fsicos de


almacenamiento.Enefecto,cuandoelusuariodeseareferirseaunconjuntodeinformacin
del mismo tipo como una unidad de almacenamiento, no tiene ms que crear un archivo
dndole el nombre correspondiente. Los archivos se conciben como estructuras con las
siguientespeculiaridades:

Debensercapacesdecontenergrandescantidadesdeinformacin

Suinformacindebepermanecerysobreviviralosprocesosquegeneranoutilizan

Distintos procesos deben poder acceder a la informacin del archivo


concurrentemente

Dependiendo del sistema operativo se pueden hacer unas u otras operaciones con los
archivos.Cadaarchivousualmentecontienenombre,atributos,ydatos.Losatributospueden
incluircuestionestalescomofechayhoradecreacin,fechayhoradelaltimaactualizacin,
bits de proteccin, contrasea de acceso, nmero de bytes por registro, capacidad mxima
delarchivoycapacidadactualmenteocupada.

Los datos se almacenan en el dispositivo de memoria masiva en forma de bloques. El


dispositivomsusadoparaalmacenamientodearchivoseseldisco.Comolaunidadfsicade
almacenamientoeselbloque,stospuedengrabarsedediversasformas:

Lista de enlaces: Cada disco dispone de una tabla con tantos elementos como
bloques fsicos, la posicin de cada elemento se corresponde biunvocamente con
cadabloque,ycontieneelpunterodellugardondeseencuentraelsiguientebloque
delarchivo.Cuandoseabreunarchivoelsistemadearchivossecargaenlamemoria
principal la lista de enlaces, pudindose obtener rpidamente las direcciones,
usualmente 3 bytes, de los bloques consecutivos del archivo. Presenta el

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 263

inconveniente de que si el disco es muy grande, la lista de enlaces ocupa una


capacidad excesiva en memoria principal. Este sistema de grabacin es propio de
MSDOS. La lista de enlaces se denomina FAT (File Allocation Table, Tabla de
Localizacin de Ficheros), y cada direccin de bloque se da con 2 bytes para los
discos duros. Como cada elemento de la FAT corresponde a un bloque, se puede
grabarenlinformacinalternativaalpuntero;porejemplo,indicarsielbloqueest
deteriorado(HFFF7),siestlibre(H0000)yportantodisponibleparasuuso,osies
elltimodelarchivo(HFFFF).

Inodos:Correspondealaformadegestionarlosarchivosporelsistemaoperativo
UNIX.Cadaarchivotieneasociadounnododendices,oinodo,queesunapequea
tabla de tamao fijo conteniendo los atributos del archivo y las direcciones de un
nmero determinado de los primeros bloques del archivo. Los tres ltimos
elementos de la tabla indican indirectamente las siguientes direcciones de los
bloquesdelarchivo.

EstodalugaraunaseriedeestndaresdegestindearchivosenlosquecabedestacarFAT,
NTFSyEXT:

SistemaFAT32

Con diferencia es el sistema de gestin de archivos ms utilizado en los dispositivos de


almacenamientomviles,dadoquepracticamentetodoslossistemasoperativoslosoportan.
Es el sistema de archivos creado por Bill Gates en las versiones iniciales de DOS, que
posteriormente ha evolucionado para ir admitiendo ms capacidad y mejorar sus
caractersitcasperomanteniendolacompatibilidadengranmedida.

Tabla de asignacin de archivos, comnmente conocido como FAT (del ingls file allocation
table),esunsistemadearchivosdesarrolladoparaMSDOS,ascomoelsistemadearchivos
principaldelasedicionesnoempresarialesdeMicrosoftWindowshastaWindowsMe.

FATesrelativamentesencillo.Acausadeello,esunformatopopularparadisquetesadmitido
prcticamente por todos los sistemas operativos existentes para computadora personal. Se
utiliza como mecanismo de intercambio de datos entre sistemas operativos distintos que
coexistenenlamismacomputadora,loqueseconocecomoentornomultiarranque.Tambin
seutilizaentarjetasdememoriaydispositivossimilares.

LasimplementacionesmsextendidasdeFATtienenalgunasdesventajas.Cuandoseborrany
seescribennuevosarchivostiendeadejarfragmentosdispersosdestosportodoelsoporte.
Con el tiempo, esto hace que el proceso de lectura o escritura sea cada vez ms lento. La
denominada desfragmentacin es la solucin a esto, pero es un proceso largo que debe
repetirseregularmenteparamantenerelsistemadearchivosenperfectascondiciones.FAT
tampoco fue diseado para ser redundante ante fallos. Inicialmente solamente soportaba
264 PROGRAMACIN C++ Y COMUNICACIONES.

nombres cortos de archivo: ocho caracteres para el nombre ms tres para la extensin.
Tambin carece de permisos de seguridad: cualquier usuario puede acceder a cualquier
archivo.

FAT32fuelarespuestaparasuperarellmitedetamaodeFAT16almismotiempoquese
mantena la compatibilidad con MSDOS en modo real. Microsoft decidi implementar una
nuevageneracindeFATutilizandodireccionesdeclusterde32bits(aunqueslo28deesos
bitsseutilizabanrealmente).

Enteora, esto debera permitir aproximadamente268.435.538 clusters, arrojando tamaos


dealmacenamientocercanosalosochoterabytes.Sinembargo,debidoalimitacionesenla
utilidadScanDiskdeMicrosoft,nosepermitequeFAT32crezcamsallde4.177.920clusters
porparticin(esdecir,unos124gigabytes).Posteriormente,Windows2000yXPsituaronel
lmitedeFAT32enlos32GiB.Microsoftafirmaqueesunadecisindediseo,sinembargo,
escapazdeleerparticionesmayorescreadasporotrosmedios.

FAT32apareciporprimeravezenWindows95OSR2.Eranecesarioreformatearparausar
las ventajas de FAT32. Curiosamente, DriveSpace 3 (incluido con Windows 95 y 98) no lo
soportaba. Windows 98 incorpor una herramienta para convertir de FAT16 a FAT32 sin
prdida de los datos. Este soporte no estuvo disponible en la lnea empresarial hasta
Windows2000.

EltamaomximodeunarchivoenFAT32es4GiB(2321bytes),loqueresultaengorroso
para aplicaciones de captura y edicin de video, ya que los archivos generados por stas
superanfcilmenteeselmite.

SistemadeficherosNTFS

NTFS (del ingls New Technology File System) es un sistema de archivos de Windows NT
incluido en las versiones de Windows 2000, Windows XP, Windows Server 2003, Windows
Server2008,WindowsVista,Windows7yWindows8.Estbasadoenelsistemadearchivos
HPFS de IBM/Microsoft usado en el sistema operativo OS/2, y tambin tiene ciertas
influenciasdelformatodearchivosHFSdiseadoporApple.

NTFS permite definir el tamao del clster a partir de 512 bytes (tamao mnimo de un
sector)deformaindependientealtamaodelaparticin.

Es un sistema adecuado para las particiones de gran tamao requeridas en estaciones de


trabajodealtorendimientoyservidores.Puedemanejarvolmenesde,tericamente,hasta
2641 clsteres. En la prctica, el mximo volumen NTFS soportado es de 2321 clsteres
(aproximadamente16TiBusandoclsteresde4KiB).

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 265

Suprincipalinconvenienteesquenecesitaparasmismounabuenacantidaddeespacioen
discoduro,porloquenoesrecomendablesuusoendiscosconmenosde400MiBlibres.

LosnombresdearchivosonalmacenadosenUnicode(UTF16),ylaestructuradeficherosen
rbolesB,unaestructuradedatoscomplejaqueaceleraelaccesoalosficherosyreducela
fragmentacin,queeralomscriticadodelsistemaFAT.

Se emplea un registro transaccional (journal) para garantizar la integridad del sistema de


ficheros(peronoladecadaarchivo).LossistemasqueempleanNTFShandemostradotener
una estabilidad mejorada, que resultaba un requisito ineludible considerando la naturaleza
inestabledelasversionesmsantiguasdeWindowsNT.

Sin embargo, a pesar de lo descrito anteriormente, este sistema de archivos posee un


funcionamientoprcticamentesecreto,yaqueMicrosoftnohaliberadosucdigo,comohizo
conFAT.

Gracias a la ingeniera inversa, aplicada sobre el sistema de archivos, se desarrollaron


controladorescomoelNTFS3GqueactualmenteproveenasistemasoperativosGNU/Linux,
Solaris,MacOSXoBSD,entreotros,desoportecompletodelecturayescrituraenparticiones
NTFS.

SistemasEXT(Linux)

ActualmenteseutilizalacuartaversindeestesistemadeficherosutilizadoporLinux.ext4
(fourth extended filesystem o cuarto sistema de archivos extendido) es un sistema de
archivostransaccional(eninglsjournaling),anunciadoel10deoctubrede2006porAndrew
Morton, como una mejora compatible de ext3. El 25 de diciembre de 2008 se public el
kernelLinux2.6.28,queeliminayalaetiquetade"experimental"decdigodeext4. Utilizaun
rbolbinariobalanceado(rbolAVL)eincorporaelasignadordebloquesdediscoOrlov.

SistemasHFS(MacOS)

HFSPlusoHFS+esunsistemadearchivosdesarrolladoporAppleInc.parareemplazaralHFS
(Sistemajerrquicodearchivos).TambineselformatousadoporeliPodalserformateado
desdeunMac.

Los volmenes de HFS+ estn divididos en sectores (bloques lgicos en HFS), de 512 Bytes.
Estos sectores estnagrupados juntos enunbloque deasignacin que contieneuno o ms
sectores;elnmerodebloquesdeasignacindependedeltamaototaldelvolumen.HFS+
usaunvalordedireccinparalosbloquesdeasignacinmayorqueHFS,32bitfrentea16bit
de HFS; lo que significa que puede acceder a 232 bloques de asignacin. Tpicamente un
266 PROGRAMACIN C++ Y COMUNICACIONES.

volumen HFS+ esta embebido en un Envoltorio HFS (HFS Wrapper), aunque esto es menos
relevante. El envoltorio fue diseado para dos propsitos; permitir a los ordenadores
MacintoshHFS+sinsoporteparaHFS+,arrancarlosvolmenesHFS+yayudaralosusuariosa
realizar la transicin a HFS+. HFS+ arrancaba con un volumen de ficheros de solo lectura
llamadoWhere_have_all_my_files_gone?,queexplicabaalosusuariosconversionesdelMac
OSsinHFS+,queelvolumenrequiereunsistemaconsoporteparaHFS+.Elvolumenorigina
HFS contiene una firma y un desplazamiento en los volmenes HFS + embebidos en su
cabeceradelvolumen.TodoslosbloquesdeasignacinenelvolumenHFSquecontienenel
volumenembebidosonmapeadosfueradelarchivodeasignacinHFScomobloquesdaados

Gestindedirectorios

Lasegundaabstraccinqueutilizaelsistemaoperativoparagestionarvolmenesde
datos es la de directorio. Los directorios son conjuntos de archivos agrupados, siguiendo
algn criterio: directorio del usuario que lo crea, directorio de cartas, directorio de
aplicaciones,etc.Laestructuraglobaldelsistemadearchivossueleorganizarseenformade
rbol en el que los nodos interiores son directorios, o archivos, y los nodos exteriores son
archivos. De un directorio pueden depender archivos u otros directorios, tambin
denominadossubdirectorios.

Un directorio se gestiona con una tabla de ndices, que contiene un elemento por
cadaarchivoodirectoriodependientedel.Cadaelementoestformadoporelnombredel
archivodadoporelusuario,yporinformacinadicionalutilizadaporelsistemaoperativo.La
informacin adicional sobreel archivo puede estar constituida por losatributos y elbloque
dondecomienzaelarchivo,casodeMSDOS.Tambin,lainformacinadicionalpuedeserun
punteroaotraestructuraconinformacinsobreelarchivo.EsteeselcasodeUNIX,enelque
el puntero sencillamente es la direccin del inodo del archivo, que contiene tanto los
atributosdelarchivocomolatabladeposiciones.

Cuando se abre un archivo, el sistema operativo utiliza el camino (path) para


buscar en el directorio el elemento correspondiente al archivo, identificndolo por su
nombre.Lainformacinseextraeapartirdelelementodelatabladedireccionesdeldiscoy
se ubica en la memoria principal. Con ayuda de esta tabla rpidamente pueden realizarse
todaslasreferenciasalarchivo.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 267

9.2. Sistemas Operativos de Microsoft

La siguiente imagen obtenida de WikiPedia, muestra grficamente el conjunto de sistemas


operativos desarrollados por Microsoft a lo largo de la historia, y las distintas familias a las
quecadaunodeellospertenece:

Sistema Operativo MS-DOS


El nombreMSDOS correspondea las siglas deMicroSoft Disk
Operating System, es decir, Sistema Operativo de Disco de
MicroSoft.Comosemuestraenlafigura2.3,laprimeraversin
apareci en 1981, como sistema operativo utilizado para los
ordenadorespersonalesdeIBM,queenunprincipioincorpor
el micro 8086 de Intel. La versin instalada por IBM se
denominabaPCDOS,mientrasqueladistribuidaporMicroSoft
paraelrestodefabricantessedenominabaMSDOS.

A partir de 1981 aparecieron sucesivas versiones y


actualizaciones del sistema operativo hasta la versin 6.0 en
1993.Encasitodosloscasoslasnuevasversionestratabande
aprovechar al mximo las prestaciones de los sucesivos
microprocesadores de la familia del 8086 de Intel. La versin
1.25 permita la utilizacin de nuevos disquetes de doble
densidad de 320 KB. La versin 2.0 apareci para el PCXT,

Figura 2. 3 . Evolucin histrica de MS-


DOS
268 PROGRAMACIN C++ Y COMUNICACIONES.

utilizaba un sistema de archivos jerrquico. Las sucesivas actualizaciones 2.01 y 2.11


eliminaban algunos errores que aparecieron. La versin 3.0 fue una de las ms difundidas
utilizndose disquetes de 1.2 MB y discos duros de mayor capacidad. Las sucesivas
actualizacioneshastala3.3,permitieronlautilizacindedisquetesdemayorcapacidadhasta
losactualesde3,5de1.5MB,eincorporabanalgunosprotocolosparalaconexinenredde
los ordenadores. En la versin 4.0 se implement la gestin de memoria EMS, pero
aparecieron numerosos errores que limitaron su difusin. En la versin 5.0 se mejor
significativamente la gestin de la memoria, y la versin 6.0 permita la utilizacin de
mecanismoparalacompresindeinformacineneldiscoduro,comoelDoubleSpace

Funciones y componentes del DOS


LasprincipalesfuncionesdeMSDOSsonorganizarlosdatosenlosdiscosylagestindelos
diferentesperifricosdelPC,pruebadeelloesquelamayoradelasrdenesdeDOSestn
relacionadas con el almacenamiento y gestin de los datos en el disco. Para lograr este
propsito, el DOS utiliza una estructura arborescente basada en tres elementos
fundamentales: unidades, directorios y ficheros. Se dice que la estructura es arborescente
porqueadoptalaformadeunrbolinvertido,conlasracesenlapartesuperiorylashojasen
laparteinferior.Lasracesdelrbolcorresponderanalaunidad.Eltroncodelrbolserael
directorio principal, que se denomina directorio raz; y a partir de ese tronco nacen varias
ramas, llamadas directorios, de mayor o menor tamao, de las cuales a su vez cuelgan los
ficheros.
El sistema operativo MSDOS se compone de tres mdulo fundamentales, que son
responsables de determinadas zonas funcionales de este sistema. Las tres partes ms
importantessonelBIOSdelDOS,noconfundirconelROMBIOS;elncleo(kernel)delDOS;
yelprocesadordecomandos.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 269

ElBIOSdelDOS

El BIOS (Basic Input Output System, Sistema Bsico de Entradas y Salidas) del DOS se
encuentraenunarchivo,queenelPCDOSdeIBMsellamaIBMIO.SYS;yqueenMSDOSse
llamaIO.SYS.EstearchivoseencuentraentodoslosPCcomoprimerarchivoeneldirectorio
raz del disco de arranque, y est equipado con los atributos de archivo HIDDEN y SYSTEM,
paraquenoaparezcaenlapantallaconlallamadadelcomandoDIR.

CuandoDOSquierecomunicarseconalgunodeestosdispositivosutilizaloscontroladoresde
dispositivoscontenidosenesemdulo,queasuvezempleanlasrutinasdelROMBIOS.Slo
elBIOSdelDOSyloscontroladoresdedispositivosentranencontactoconelhardware,esto
hacequeestosseanloselementosmsdependientesdelhardware.Enlasprimerasversiones
estapartedelDOSdebaseradaptadaporlosdiferentesfabricantesdehardware,debidoa
quelasdiferenciasentrelosPCdediferentesfabricanteseransignificativas.

ElncleodelDOS

ElncleodelDOS,tambinconocidoporsudenominacininglesaKernel,seencuentraenel
archivo IBMDOS.SYS en el PCDOS, o en el archivo MSDOS.SYS para MSDOS. Se encuentra
inmediatamentedespusdelarchivoIMBIO.SYS,oIO.SYS,eneldirectoriorazdelaunidadde
arranque.Aligualqueelanteriorarchivonoesvisibleporelusuario,yaquellevalosatributos
dearchivoSYSTEMyHIDDEN;adems,aligualquesupredecesor,nosepuedeborrarporque
ademssemarcconelatributoREADONLY.

EnestearchivoseencuentralasinnumerablesfuncionesdelDOSAPI,quesepuedenalcanzar
atravsdelainterrupcin21h.Todaslasrutinasestndiseadasdeformaindependientedel
hardware,yseutilizanparaelaccesodeotrosdispositivosdelBIOSdelDOS.Porestarazn,
estemdulonosehadeadaptaralhardwaredelosdiferentesordenadores.

Elprocesadordecomandos

Al contrario que en el caso de los dos mdulos presentados hasta ahora, el procesador de
comandos del DOS, denominado SHELL, se encuentra en un archivo visible con el nombre
COMMAND.COM.Esteeselprogramaquesellamaautomticamenteduranteelarranquedel
ordenador.Muestraelprompt(smbolodelalneadecomandos)delDOSenlapantalla(A>
oC>).Sufuncinprincipalesprocesarlassucesivasentradasdelusuario.
270 PROGRAMACIN C++ Y COMUNICACIONES.

ElprocesadordecomandoseselnicocomponentevisibledelDOS,demodoqueenalgunos
casos es errneamente considerado como el sistema operativo en s. En realidad, slo un
programanormal,quefuncionabajoelcontroldelDOS.Elprocesadordecomandosnoessin
embargo un bloque monoltico, sino que se encuentra dividido en tres mdulos, una parte
residente,unapartenoresidente,ylarutinadeinicializacin.

La parte residente, es decir, la parte que se queda constantemente en la memoria del


ordenador, contiene diferentes controladores de interrupciones del DOS; por tanto, esta
parte se ha de quedar siempre en memoria, ya que de lo contrario, el sistema se quedara
bloqueado, como muy tarde durante la llamada de la siguiente interrupcin del hardware,
cuyoscontroladoresdeinterrupcionesseencuentranenestaparte.

Lapartenoresidentecontieneelcdigodelprogramaparalasalidadelindicadordelsistema,
paraleerlasentradasdeusuariodeltecladoyparasuejecucin.Elnombredeestemdulo
sedebeaquepuedesersobrescritoporlosprogramasdeusuario,yaque,seencuentraenla
partesuperiordelamemoria,porencimadeestosprogramas.Peroestonoimporta,yaque
traslaejecucindeunprogramasevuelveapasaralaparteresidente.Estecompruebasila
parte noresidente fue sobrescrita, y la vuelve a cargar de la unidad de arranque, si fuera
necesario.

Lapartedeinicializacinsecargaduranteelarranquedelcomputador,yacogelastareasde
inicioelsistemaDOS.Cuandofinalizasutrabajo,yanoesnecesaria,ysepuedesobreescribir
porotroprograma.

El primer entorno grfico Windows


Las primeras versiones deWindows deMicrosoft deben ser consideradas como un entorno
grfico; ya que, inicialmente requera del sistema operativo para su funcionamiento. La
utilizacin del entorno de Windows presentaba grandes diferencias respecto al DOS, de las
cuales la ms inmediata es que se trata de un entorno exclusivamente grfico, con una
filosofadesmboloseiconosparafacilitarlalabordelusuarioylanecesidaddeunratno
dispositivo anlogo. A pesar de que el entorno Windows funciona bajo DOS, existen
programas que funcionan bajo DOS, y programas que slo funcionan bajo el entorno
Windows.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 271

Cuando aparecieron las primeras versiones de Windows hacia el ao 1986, tanto desde el
punto de vista del usuario, como del programador aparecieron unas prestaciones muy
limitadas.Enesencia,setratabadeunacapaqueseestablecaencimadelDOSycuyasnicas
ventajaseransusistemagrfico;laindependenciadelosdispositivos,esdecir,delhardware;
yunamultitareacooperativaentrelasescasasaplicacionesqueexistan.Enloreferenteala
presentacin,sepuededecirqueaquellaprimeraversineramuysimple.

EnpocosaosMicrosoftlanzunanuevasagaderevisionesbajolaversin2.0,conunlavado
de cara y una mayor eficacia en el cdigo, pero es en la versin 3.0 donde el impacto de
Windowsrompetodaslasprevisiones.Porprimeravez,Windowsaprovechabaporcompleto
de la arquitectura 80386 para construir un sistema de memoria virtual de forma que sta
podaextendersehastacuatroveces,siempreycuandoexistiesesuficienteespacioeneldisco
duro.LasventasinicialesdeWindows3.0fueronespectaculares.

Generalidades sobre Windows


El nombre de Windows es el propio de un sistema que est basado en ventanas. Cada
ventana tiene unos atributos particulares, entro los que destaca su posicin y tamao.
Mediante el ratn se puede alterar la mayora de ellas ajustndolas a los propsitos
necesarios.Tambinesposibleinteraccionarconelteclado,perosepartedelaideadeque
unusuariodeWindowsdisponedealgntipodedispositivoapuntador,talcomounratn,si
quierealcanzarunmnimodeprestaciones.
272 PROGRAMACIN C++ Y COMUNICACIONES.

Unaventanacompletaestconstituidaporuntrozodepantalla,habitualmenteconunttulo,
enelqueapareceenlapartesuperiorizquierdaunmengeneralconformadebotn,quese
despliega al pulsarlo. En la derecha existen otros botones que permiten actuar sobre el
tamaodelaventana.Estosltimostienenlaposibilidaddemaximizar,laventanaocupar
toda la pantalla; o minimizar la ventana, pasando a ocupar la mnima extensin,
convirtindoseenunicono.Adicionalmente,laventanapuedeserredimensionadapinchando
elbordedelamismaconelratn,deformaquealarrastrarlosemodificasutamao.Para
moverla,sepinchasobrelabarradelttuloysearrastralaventanaalaposicinrequerida.
Segnloexpuesto,eltamaodelasventanasesmuyvariableylainformacinquecontienen
puede no ser presentable toda a un tiempo. Aqu entra en juego la figura de las barras de
desplazamiento,encargadasdemoverelcontenidodelaventanasobreunespaciodetrabajo
queseconsideramsamplio.

EnsusprimerasversionesWindowsadmiaetresmodosdeejecucin:real,sloversin3.0;
estndar; y mejorada. En los dos ltimos se rompe la barrera de los 640k que tena
antiguamente el DOS, aprovechando toda la memoria que consiga almacenar nuestro
ordenador. La diferencia entre el modo estndar y el mejorado se traduce en un diferente
aprovechamiento de la memoria. El modo mejorado requiere disponer de al menos un
microprocesador80386y2MbytesdememoriaRAM.Lasventajasdeestemodoseapoyan
ms que nada en la existencia de un modo virtual de memoria que permite cuadruplicar la
cantidaddememoriavisibleparalasaplicaciones,graciasalautilizacindelespacioexistente
en el disco duro. Ms adelante, cuando se hable sobre el Panel de Control se ver el lugar
precisodondeconfigurarestaposibilidad.

Conlaversin3.0deWindowsaparecieronunaseriedeaplicacionesquecambiaron
significativamente la actuacin sobre un computador, estos elementos que en la actualidad
hansidomejoradospermitieronunainterfazmsamigableconelordenador.Loselementos
que se describen a continuacin permiten cierto control sobre la configuracin del sistema
operativo,yensumomentorepresentaronungranavanceparalagestindellosrecursosdel
computador.Losprincipalescomponenteseran:

Administradordeprogramas.Estaaplicacin,aunquesetratadeunprogramams,
tiene la peculiaridad de ser el primero en cargarse en memoria y permanecer
siempreresidente.Sufuncinprincipalespermitirlaeleccinyposteriorejecucin
de otras aplicaciones, de una forma organizada. El administrador de programas
permiteiniciarfcilmentelasaplicacionesyorganizarlosarchivosylasaplicaciones
engruposlgicos.

Administrador de archivos. Como en cualquier sistema operativo existen mtodos


para gestionar los archivos que contiene el sistema, as como sus unidades de
almacenamiento de informacin. El Administrador de archivos es una herramienta

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 273

quepuedeemplearseparalaorganizacinyutilizacindearchivosydirectorios.Las
operaciones bsicas que se pueden realizar sobre los disquetes y discos duros son
hacerunduplicadodeldisco,formatearlo,ydarleunnombredevolumen.

Administrador de impresin. La razn es que su funcin principal es meramente


fsica. Se encarga de proporcionar una cola de impresin para diferentes trabajos
enviados por una o varias aplicaciones. El Administrador de impresin proporciona
unmododeverycontrolarlaimpresindelosdocumentos.

El portapapeles es un lugar donde se guarda temporalmente una determinada


informacin.Dichainformacinpuedeseruntexto,unaimagenoinclusoformatos
particularesdedeterminadasaplicaciones.Lautilidaddeestesistemaesmuyamplia,
siendosuprincipalfuncinladeintercambiardatosentreaplicacionesobiencopiar
determinadainformacindentrodeunamismaaplicacin.Engeneral,enlamayora
delasaplicacionesexisteunmenquetieneelnombredeEdicindentrodelcual
aparecenalmenostresopciones:cortar,pegarycopiar.

Elpaneldecontrolesunprogramaqueincluyeunaseriedecomponentesquesirven
para ajustar la configuracin del sistema. El panel de control es una aplicacin
Windows que permite modificar de forma visual las caractersticas del sistema
durantelautilizacindeWindows.Cadaunadelasopcionesquepuedenmodificarse
aparece representada con el icono correspondiente en la ventada del Panel de
control. Las opciones existentes son las siguientes: los colores de la pantalla, otras
opciones del Escritorio que determinan el aspecto de la pantalla, las fuentes que
reconocernlasaplicacionesdeWindows,lasimpresorasutilizadas,losparmetros
deltecladoydeldispositivoapuntador(ratn),lasopcionesinternacionales,puertos
y redes, la fecha y hora del sistema, los sonidos que utilizar el sistema, los
parmetros MIDI que utilizar el sintetizador conectado a la computadora, y
finalmente las opciones de multitarea para la ejecucin de Windows en el modo
extendidodel80386.

Protocolos propios de Windows


ProtocoloDDE(DynamicDataExchange,IntercambioDinmicodeDatos)

ElprotocoloDDEestorientadoalintercambiodinmicodedatosquepermiteque
lasaplicacionesdeWindowspuedanintercambiarinformacinyactuarenbaseaelladeuna
forma totalmente cooperativa. Bajo DOS, cada programa se comporta como una isla en
medio de un ocano, obligando al programador a hacer ingeniosos esfuerzos cuando dos
aplicacionesnecesitancompartirdatos.Aunquesudiseoestorientadoalaejecucindeun
nicoprograma,esposibleobtenermultitareadejandoprogramasresidentesenmemoria.El
problemadelacomunicacinnoparecetalcuandounaaplicacingeneraunarchivodesalida
queotrapuedeleer,aunquenosetratedeunverdaderointercambiodeinformacin,dado
274 PROGRAMACIN C++ Y COMUNICACIONES.

quelasaplicacionesdifcilmentepuedenmantenerelcontrolsobreenqumomentosedebe
enviarorecibirlainformacin.Paraquedosaplicacionespuedanaccederareasdememoria
comunesnormalmenteseutilizaninterrupcionesquesoninstaladasamododeinterfaces.Las
aplicaciones que intervienen tienen que estar de acuerdo en la forma de acceder a las
interrupciones y en el formato de los datos sin que el DOS provea de ningn mecanismo
prcticoparallevaracabolatarea.

En un entorno multitarea como en Windows resulta imprescindible disponer de cierto


mecanismosquepermitanunacomunicacinfluidaentreaplicaciones.Existentresmtodos
quepermitencompartirlainformacin.Elprimermtodoeseldelportapapeles,quedispone
de un espacio de datos donde podemos almacenar informacin. Cuando una aplicacin
introduceinformacinenelportapapelestodaslasdemssoninformadasdeello,pudiendo
accederalamisma.Estemtodoesutilizadoparatransferirunbloquededatos,peronose
trata de un protocolo en s, pues normalmente se considera necesaria la intervencin del
usuario para decidir en qu momento se realiza la accin. El segundo mtodo requiere la
presencia de las libreras de enlace dinmico. El tercer mtodo, mucho ms eficaz, es el
protocoloDDE.Paralautilizacindeesteprotocolo,esimprescindiblequehayasidoprevisto
eneldiseodelasaplicaciones.Algunasdeellas,comolamayoradelasquesondistribuidas
con Windows, no disponen de esta capacidad, como puede ser el Write, PainBrush,
Portapapeles, etc. Tal vez, la opcin ms avanzada e interesante del DDE es el enlace
permanentededatos,queconsisteenmantenerunaconversacinentredosaplicacionesde
formaquedeterminadoconjuntodedatosesactualizadoentiemporeal.

ProtocoloOLE(ObjectLinkedandEmbeddedObjetoUnidoyEmbebido)

Antelagranimportanciadelintercambiodeinformacinentreaplicaciones,sedesarrollun
nuevoprotocolodenominadoOLE,quehizosuaparicinenlaversin3.10.ElOLE,enlneas
generales,estableceunmtodoestndarparaquedistintasaplicacionespuedanenlazary
compartirsusdocumentos.Setienendosconceptosnuevos:eldeobjetocomoconjuntode
datos;yeldedocumento,ocontenedor,dondesepuedenalmacenarlosobjetosUnobjeto,
porejemploundibujo,tieneunnicopropietarioqueeslaaplicacinquelocre,peropuede
tenermltiplesdestinos,esdecir,serutilizadopordistintasaplicaciones.

El protocolo OLE est basado en mensajes que establece una conversacin entre cliente y
servidor, informando acerca de los objetos: aplicacin origen, formatos, cambios en los
mismos, solicitud de actualizaciones, etc. OLE implica ciertos cambios en la mayora de los
programas, con el fin de que lo puedan gestionar y dejen de considerar como exclusiva la
informacin que manejas. A nivel de usuario OLE utiliza comandos a los que ya se est

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 275

acostumbrado,talescomocopiar,pegar,cortar,etc.,queaparecennormalmenteenelmen
deedicin.

Sistema Operativo: Windows 95.

Windows95supusounpasomuyimportanteenlafilosofadetrabajodelosPCs.Se
integra dentro de la familia de productos Windows de Microsoft, convirtindose en el
heredero de Windows 3.1, y compartiendo caractersticas de Windows para Trabajo en
Grupo, y Windows NT. Windows 95 es un entorno de trabajo de 32 bits con una interfaz
orientadaaobjetos,funcionesparatrabajoenredayudainteractiva,gestindemdemyfax.
Soport las ltimas tecnologas utilizadas hasta la fecha, como OLE 2.0, Plug and Play
(pincharyejecutar),llamadasaprocesosremotos,telefonamvil,etc.

En primer lugar, hay que sealar que Windows 95 es por s mismo un sistema
operativo, a diferencia de Windows 3.1 que necesita trabajar sobre el MSDOS. Esto quiere
decirqueelusuariocuandoarrancaelordenadornotieneprimeroquecargarelDOSy,luego,
ejecutarlaentoncesfamosaordenWINparacargarWindows.Ahoracuandoseenciendeel
ordenadorsearrancadirectamenteenWindows95.Porotraparte,elusuarioyanotieneque
instalarprimeroMSDOSyluegoWindows,sinosloinstalarWindows95directamente.

Ensegundolugar,esnecesariodestacarqueWindows95esunsistemaoperativode
32bits,optimizadoparalosordenadoresque,ensumayora,usanarquitecturade32bits.Las
ventajasdetrabajarconarquitecturade32bitsyenmodoprotegidosonbastantegrandes:
los programadores pueden usar un direccionamiento de memoria lineal y olvidarse de las
limitaciones que impone las direcciones segmentadas. Adems, se pueden ejecutar
controladoresdedispositivoenmodoprotegido,loquepermitevirtualizarlos;esdecir,que
un mismo dispositivo pueda ser compartido por varios programas a la vez, lo cual es un
276 PROGRAMACIN C++ Y COMUNICACIONES.

requisitoimprescindibleparaproporcionarverdaderamultitarea.Loscontroladoresvirtuales
soportantodoslosdispositivoshardwaredelordenador,incluyendodisco,teclado,monitor,
puertosparaleloyserie,etc.Tambinhaycontroladoresvirtualesparaelratn,SmartDrive,
sistema de ficheros VFAT, sistema de fichero CDROM, compresin de disco DriveSpace (y
DoubleSpace),tarjetasyprotocolosdered,dispositivosSCSI,etc.

Windows 95 es un sistema operativo multitarea,ya quepermite ejecutar mltiples


aplicacionessimultneamentemejorquelohacaWindows3.1.Ahorabien,laeficaciadela
multitarea depende engranmedida del tipo de aplicaciones que se estn ejecutando. Si se
trata de aplicaciones para Windows 3.1, que son aplicaciones de 16 bits, la multitarea es
parecidaalaqueseofreceenWindows3.1.PeroconlasaplicacionesWindowsde32bitsse
permitealcanzarmultitareacompleta.

PlugandPlay(ConectaryEjecutar)

UnadelascaractersticasmsatractivasdeWindows95esquesetratadelprimer
sistema operativo Plug and Play. El estndar o conjunto de normas Plug and Play pretende
crearunaestructuraquepermitagestionardeformainteligentelainstalacinyconfiguracin
denuevosdispositivos,sinrequerirlaintervencindelusuario.ConunsistemaPlugandPlay
el usuario puede aadir y quitar dispositivos o conectarse y desconectarse a una red o
estacin maestra sin necesidad de reinicializar el sistema y definir varios parmetros. El
sistema Plug and Play detecta automticamente la existencia de un nuevo dispositivo,
determina la configuracin ptima y permite que las aplicaciones se autoajusten
automticamenteteniendoencuentaloscambiosocurridos.Porejemplo,unaaplicacinque
muestradifuminadas,oinactivas,lasopcionesparaCDROMyquereconoceinmediatamente
lapresenciadeunaunidadCDROM,activandolaposibilidaddeseleccionarlasopcionespara
CDROM. De esta forma, los usuarios ya no necesitan conmutar puentes, activar
interruptores, seleccionar IRQs libres; ni siquiera tiene que cambiar los ficheros de
configuracindelsistemaoperativoparaadirlosnuevoscontroladores.

Paralograresteobjetivodeunainstalacininstantneayautomtica,unordenador
hadeposeertrescomponentes:unsistemaoperativoPlugandPlay,unaBIOSPlugandPlayy,
por supuesto, dispositivos compatibles Plug and Play. Estos tres componentes son
imprescindibles para evitar totalmente la intervencin del usuario durante el proceso de
instalacin, pero la existencia de dos o uno de ellos tambin simplifica la configuracin
hardware.

Enprimerlugar,losdispositivosPlugandPlaytienenquesercapacesdeidentificarse
a s mismos, es decir, informar al ordenador de qu tipo de dispositivo se trata y de los
requisitos que necesita. Por ejemplo, una tarjeta de sonido Plug and Play debe indicar al
ordenadorquesetratadeunatarjetadesonidoyquenecesitaseleccionarunaIRQ,uncanal
DMAyunadireccindememoriabase.Adems,debepermitirqueelordenadorconfigurede
formaautomticadichosrequisitos,locualimplicaquelosdispositivosPlugandPlaytienen
que poder modificarse a s mismos. Por ejemplo, en el caso de una impresora que exige la
presenciadeunpuertoparalelobidireccionalquepermitaenviardatosdesdelaimpresoraal
ordenador,ynoslodesdeelordenadoraalimpresora.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 277

Ensegundolugar,tienequehaberunaBIOSPlugandPlayqueestpreparadapara
pedir y aceptar las caractersticas y los requisitos de los nuevos dispositivos. Esta BIOS
detectarlapresenciadeunnuevodispositivoy,envezdegenerarvariospitidosseguidosde
un escueto mensaje, pedir los valores por defecto para los requisitos del dispositivo y
seleccionarautomticamentelosadecuados.

Porltimo,esnecesariounsistemaoperativoPlugandPlay,talcomoWindows95,
quegestionetodosloscomponentescargandoloscontroladoresdedispositivoadecuadosy
reconfigurandoelsistemaautomticamentesinintervencindelusuario.

ElestndarPlugandPlaynoslopretendealcanzarunaconfiguracinautomticade
losdispositivoshardware,sino sercapazdereconocercambiosdinmicosdeconfiguracin.
Esta caracterstica es fundamental en la informtica mvil, puesto que los usuarios de
porttiles necesitan poder conectarse a redes locales sin tener que apagar el ordenador o
reconfigurarlo. Un sistema operativo Plug and Play, reconoce inmediatamente los nuevos
dispositivos instalados y los recursos que necesitan, cargando de forma automtica los
controladores de dispositivos adecuados. Las aplicaciones son informadas de los cambios
dinmicosparaquepuedanaprovecharlasnuevascaractersticas,obienimpidanelaccesoa
dispositivosnoexistentes.Supuestamenteyanoesprecisoapagaryreinicializarelordenador
cuandorealicencambiosenlaconfiguracinhardware,ynisiquierahandeintervenirenel
procesodeconfiguracin.

Interfazorientadaaobjetos

Una de las principales aportaciones de Windows 95 era su nueva interfaz que


presentaba una organizacin ms racional y eficiente de los recursos, aunque supone un
cambioradicalfrentealafilosofatradicionaldeWindows.LainterfazdeWindows3.1est
orientada a iconos y su funcionamiento bsico es seleccionar un icono y aplicarle una
propiedadeligiendounaopcindeunmengeneralqueessiempreigual.Porelcontrario,la
interfazdeWindows95estorientadaaobjetosyyanoexisteunmengeneralparatodos
los iconos, sino que cada objeto posee supropio mendependiendodel tipodeobjetodel
quesetrate.EnWindows95desaparecenelAdministradordeProgramasyelAdministrador
de Archivos y en su lugar se implementa un escritorio grfico. En este escritorio el usuario
puede situar objetos de distintos tipos, ya sean programas carpetas de programas,
impresoras,unidadesdedisco,etc.

La interfaz de Windows 95 adopta la tecnologa orientada a objetos; es decir, el


usuariosiemprerealizalasmismasoperacionessobrelosobjetos,perostasoperacionesse
interpretandedistintaformasegneltipodeobjeto.Porejemplo,alhacerdobleclicsobre
uniconoseabredichoicono.Laaccindeabrireliconoesdistintasegneltipodeobjeto:si
esuniconodeprograma,seejecutaelprograma;siesuniconodedocumentoseejecutael
programa en el que se cre el documento y se carga automticamente para su revisin o
modificacin;sieseliconodeunaunidaddedisco,semuestraunaventanaconelcontenido
delaunidad;sieseliconodeunaimpresoraaparecelalistadetareasaimprimir,etc.
278 PROGRAMACIN C++ Y COMUNICACIONES.

Otro ejemplo donde se demuestra esta metodologa orienta a objetos es en el


denominado Men de Contexto, un men emergente que aparece al pulsar el botn
secundario del ratn. El botn secundario es el botn derecho del ratn en los usuarios
diestros.ElMendeContextoposeedistintasopcionessegneltipodeobjeto,perosiempre
incluye las operaciones ms utilizadas con el objeto, como: eliminar, cortar, copiar y pegar,
abrir,etc.

Sin duda alguna, la caracterstica ms importante del Men de Contexto es una


opcin denominada Propiedades que permite configurar adecuadamente el objeto.
Finalmente,otroaspectoimportantereferentealosobjetoseslaposibilidaddearrastrarun
iconosobreotro,accinqueseinterpretasegneltipodeobjetoqueseestarrastrandoyel
objetodedestino.

En la parte inferior de la pantalla existe una Barra de Tareas que cumple un papel
fundamental en la nueva interfaz adems de sustituir a la Lista de Tareas de Windows 3.1.
Cadavezqueseejecutaunaaplicacin,oseminimiza,apareceuniconoenlaBarradeTareas
querepresentadichaaplicacin.PuestoquelaBarradeTareassiempreestactiva,pulsando
el icono se accede inmediatamente a la aplicacin. Esto resuelve uno de los principales
problemas que tienen los usuarios de Windows 3.1: saber exactamente el nmero de
ventanas que tiene abiertas con aplicaciones ejecutndose y saber cmo acceder a una
ventanaquenoapareceenpantalla.

Sistema Operativo: Windows 98


Windows 98 surge de la continua mejora de Windows 95. Se considera que existen dos
grandesversionesdeWindows95,laversindeWindows95originalylaversinWindows95
OSR2, aparecida en 1996 y que slo se puede conseguir comprando un ordenador nuevo.
Entre estas dos versiones hay grandes diferencias; por ejemplo, Windows 95 OSR2 soporta
FAT32,mientrasqueWindows95originalnolohace.Ademsdeestaprimeradiferenciacin,
hay usuarios que trabajan con Windows 95 y otros que trabajan con Windows 95 ms
Internet Explorer 4. La interfaz, las posibilidades de configuracin del escritorio y otras
caractersticas importantes han cambiado con Explorer. Finalmente, Microsoft proporciona
nuevoscomponentescomounServicePackyvariasversionesnuevasdecomponentescomo
Exchange, acceso telefnico a redes, soporte USB, etc. En el ao 1999 apareci la versin
Windows98 SE que incorpor un nuevo Service Pack, que incorporaba controladores para
nuevosperifricosyutilidadesdelsistemaoperativo.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 279

Lanuevainterfaz

Windows 98 utiliza la interfaz de Explorer 4, que es similar a la de Windows 95 pero


aadiendo propiedades para la gestin de pginas Web. En realidad lo que ha hecho
Microsoft es asociar con cada directorio una pgina Web, de forma que al examinar el
contenidodeesedirectorio,semuestrelapginaWeb.EnlaterminologadeMicrosoftesto
sellamavistaWebysepuedeactivarodesactivaravoluntadencadacarpeta.

El escritorio de Windows, puede utilizar como fondo una pgina Web, permite instalar los
componentes activos, pequeos trozos de cdigo HTML que muestran informacin
cambiante, como la cotizacin de bolsa o las ltimas noticias de un determinado tema, y
soporta protectores de pantalla de canales. Todas estas caractersticas son resultado de la
vistaWeb,pueselescritorionoesmsqueunacarpetadeldiscoduroy,portanto,poseela
capacidad de entender y mostrar cdigo HTML. Las barras de herramientas incluyen ahora
nuevas opciones. Ahora puede incluir en la barra de tareas iconos que ejecutan programas
automticamente de forma rpida y cmoda. Adems hay varios iconos predefinidos entre
losquedestacaunoqueminimizatodaslasventanasabiertas,dejandoelescritoriolimpio.

Perosindudalanovedadmsinteresanteeslacapacidaddetrabajarcondosmonitores.El
funcionamientoesmuysencillo:hayqueinstalarenelordenadordostarjetasdevdeo,que
puedenser2PCIO1PCIyAGP,yaquenosepuedenusartarjetasdevdeoISA,yconectar
los monitores correspondientes. A partir de ese momento Windows funciona con una
pantallavirtualqueeslasumadelosdosmonitores.Porejemplo,sitieneenunmonitor800
x600yenotro640x480,secreaunapantallavirtualde800x1080dondesepuedecolocar
libremente los objetos. Es decir, puede arrastrar un icono desde una pantalla a otra, pues
280 PROGRAMACIN C++ Y COMUNICACIONES.

paraWindowssetratadeunasolapantallavirtual.Tambinpuedehacerqueunprogramase
ejecuteenunodelosmonitores,usandoelotroparaotrastareas.

VentajasdelaFAT32

Una de las mejoras ms importantes de Windows 98 es la coleccin de herramientas para


gestindediscosduros.Enprimerlugar,Windows98soportaFAT32,unsistemadearchivos
que presenta importantes ventajas frente a la FAT 16 tradicional. Todos los archivos se
almacenanenunidadesdeinformacinllamadasclusters,cuyotamaovarasegneltamao
del disco. La FAT (File Allocation Table, Tabla de gestin de archivos) es una tabla que
contiene la secuencia de clusters de un archivo, es decir, cul es la cadena de clusters que
componenlosdatosdeunarchivo.Cuandoseabreunarchivo,elsistemaoperativosiguela
FATparasaberenquclustersdeldiscoestnalmacenadoslosdatosdelarchivo.Windows
95, MS DOS, Windows NT, OS/2, Linux y el resto de sistemas operativos han soportado la
FAT16,unatablaqueutilizanmerosde16bitsparaidentificarcadacluster.Elproblemaes
que con nmeros de 16 bits slo se puede gestionar un mximo de 216 clusters, es decir,
65.536clusters,queparaeltamaoactualdelosdiscosesdemasiadopoco.

Herramientasdesistemayhardware

AdemsdelconvertidordeFAT32,Windows98incluyevariasherramientasdesistemacomo
elLiberadordeespacioendiscoduro,unprogramadecopiasdeseguridad,unprogramade
informacindelsistema.

Windows 98 est preparado para las ltimas tecnologas hardware y especificaciones que
estarnpresentesdeformamasivaenlosprximosaos.Sesoportanlasnuevastarjetasde
vdeo AGP (Accelerated Graphics Port, Puerto para Aceleracin de Grficos), que usan un
chipdevdeoqueaumentadrsticamentelavelocidaddeprocesamientogrficoalevitarel
busPCI,yutilizarunalneadirectaentreelsubsistemagrficoylamemoriadelordenador.
TambinsereconocenlosnuevosmdulosdecmarasdigitalesyloslectoresDVD.Windows
98estpreparadoparalosordenadoresconconectoresdetipoUSB(UniversalSerialBus,
Bus Serie Universal), que permite conectarhasta 127 dispositivos serie a unnico conector
delPC,comoescner,cmarasdigitales,ratones,mdems,impresoras,etc.Estaesunaforma
cmoda de eliminar la necesidad de cables y puertos serie adicionales. En este sentido,
Windows98soportaelestndarIEEE1394,cuyafuncinessimilaraldeUSB.Enelcampode
la administracin de energa, Windows 98 sigue el estndar ACPI (Advanced Configuration
and Power Interface, Configuracin Avanzada e Interfaz de Alimentacin), que permite al
ordenadoractivarodesactivarautomticamenteperifricoscomodiscosduros,impresoraso
tarjetasdered;porejemplo,desactivaelconsumo,yconelloelruidodeldiscoduro,cuando
se producen tiempos de inactividad, activndose automticamente al usar el teclado o el
ratn. Sealar tambin que Windows 98 soporta IrDA 3.0 (Infrared Data Association,

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 281

Asociacin de Datos por Infrarrojos), la ltima versin del estndar para comunicacin
inalmbricaatravsdeinfrarrojos.

FinalmenteWindowsScriptingHostpermiteejecutararchivosVisualBasicScriptoJavaScript,
tantodesdeelentornodeWindowscomodesdelalneadecomandosdelMSDOS.Deesta
forma,sepuedencrearenestoslenguajesverdaderosprogramasWindowsqueseejecutan
de forma sencilla y cmoda. A grandes rasgos, es una forma de retomar los habituales
archivosporlotesBAT,peroahoraconfuncionesdeWindowsyconmltiplesposibilidades.El
motor de Windows Scripting Host soporta los lenguajes VBScript y Jscript, pero compaas
independientespuedencrearcontrolesActiveXparaotroslenguajescomoPerl,TCLoREXX.

Comunicaciones

Elapartadodelascomunicacionesesunodelosmsimportantesentodosistemaoperativo
actual.LainclusindeExplorer4enWindows98suponedotarledeunvaloraadido
importante,puesaadeelnavegadorExplorer,unprogramadecorreo,ygruposdenoticias
OutlookExpress,uneditordepginasWebllamadoFrontPageExpress,yunaherramientade
telefonayvdeoconferenciadenomiandaNetMeeting.
MsnovedadesencomunicacionessonlanuevaversindeAccesotelefnicoaredes1.2,que
incluyesoporteparamultienlace;incluyndoseelprotocoloPPTPparacrearlasdenominadas
VPN(VirtualPrivateNetworks,RedesPrivadasVirtuales),quesonconexionessegurasauna
reddesdeInternet,actuandodelamismaformaquesiestuvieraconectadoalared.Unade
las novedades ms importantes de Windows 98, conocida como Web TV, se trata de la
posibilidadderecogerpginasWebatravsdelassealesdeTV,algosimilaralteletexto.

282 PROGRAMACIN C++ Y COMUNICACIONES.

Sistema Operativo: Windows Millenium


ElsistemaoperativoWindowsMilleniumfueelsucesordeWindows98SEparaelentornode
los usuarios denominados domsticos segn la terminologa de Microsoft. Apareciendo en
septiembredel2000.Deacuerdoconestefabricanteelobjetivoesproporcionarunentorno
estable,seguroysencilloalusuario,demodoquenoprecisedeavanzadosconocimientosde
administracindeusuarios,odeadministracinderedesdeordenadores.

Estenuevosistemaoperativoincorporaavancesenlosdispositivosmultimedia,acordescon
las prestaciones de los computadores en que se instalan; es decir, Pentium II o III, con
elevadascapacidadesdealmacenamientoendiscoyenmemoriaRAM.Lafinalidadesofrecer
unentornoamigablealusuarioquelepermitarealizarfcilmentetareasdeedicindevdeo,
reproduccin y/o creacin de sonido, acceder a los diferentes servicios de Internet, etc.
EjemplodeestasnuevasprestacionessonlasaplicacionesqueMicrosoft,yotrosfabricantes,
suministran para Windows Millenium; como por ejemplo: Movie Maker, Windows Media
Player,..., para las aplicaciones de multimedia; y Microsoft Explorer 5.5, MSN Messenger y
NetMeetingparaaccesoalosdiversosserviciosqueofreceInternet.

Lasherramientasdeadministracinygestindelsistemaoperativo,alasquetieneaccesoel
usuario, son similares a las de Windows 98, aunque en algunos casos cambian de aspecto.
Pocas utilidades han sido aadidas a este sistema operativo, entre ellas destaca la de
restauracindelsistema,quepretenderecuperaralordenadorencasodequedarbloqueado;
eldesarrollodevariosasistentesparafacilitarlagestinyadministracindeaplicaciones;yel
control de instalacin de aplicaciones, que tendra la finalidad de evitar sobreescrituras no
deseadasenelprocesodeinstalacindenuevosprogramas.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 283

Sistema Operativo: Windows NT


LascaractersticasmssignificativasdeWindowsNT(NewTechnology)esqueestdestinado
para ofrecer servicios avanzados de administracin alusuario, siendoun verdaderosistema
operativomultitarea.Estosedebe,entreotrasalassiguientesrazones:

Aumentodelavelocidadycapacidaddememoriadelosmicroprocesadores.

Soportedememoriavirtual.

Aumentodelasaplicacionescliente/servidorenredeslocales.

Todoestopermitiquelasaplicacionesfueranmscomplejaseinterrelacionadas,deforma
que un usuario puede estar utilizando varias aplicaciones simultneamente. Microsoft
desarrollWindowsNTconunaaparienciacaralausuariosimilaraWindows3.1,perobasado
en un concepto radicalmente distinto. Windows NT explota la potencia de sus
microprocesadores contemporneos de 32 bits y suministra una capacidad completa de
multitareaenunentornomonousuario.Adems,ofreceunagranpotenciaalpoderejecutar
aplicaciones escritas para otros sistemas operativos y cambiar de plataforma hardware sin
modificarelsistemaoperativonilasaplicaciones.

CaractersticasbsicasdeWindowsNT

Windows NT tiene una estructura modular, lo que le da una gran flexibilidad. Adems, se
puede ejecutar en una gran variedad de plataformas y soporta aplicaciones escritas para
otros sistemas operativos. Al igual que en otros sistemas operativos, en Windows NT se
distingueentreelsoftwareorientadoalasaplicaciones,queseejecutaenmodousuario;yel
software del sistema operativo, que se ejecuta en modo privilegiado como administrador.
Este ultimo tiene acceso a los datos del sistema y al hardware, mientras que el resto de
usuariostieneaccesoslimitados.

En la figura 9.4 se muestra la estructura de Windows NT. Para conseguir que NT tenga la
mismavisindelhardware,independientementedelsistemaenelqueseestejecutando,el
sistemaoperativosedivideencuatrocapas:

1. Capa de abstraccin del hardware (HAL, Hardware Abstraction Layer). El


objetivo de esta capa es que el ncleo vea por igual todo el hardware,
independientementedelaplataformaqueseuse.Paraellorealizalaconversin
entrelasrdenes,ylasrespuestas,delhardwaregenricoyeldeunaplataforma
284 PROGRAMACIN C++ Y COMUNICACIONES.

especfica;comoporejemplo,80486oPentiumdeIntel,PowerPCdeMotorola,
AlphaAXPdeDigital,etc.

2. Ncleo (kernel). Es la parte central del sistema operativo y se encarga de


gestionar la planificacin y conmutacin de contexto, los manipuladores de
excepcionesydeinterrupciones,ylasincronizacin.

3. Subsistemas. En esta capa se incluyen mdulos para funciones especficas que


hacen uso de los servicios bsicos dados por el ncleo. Estos mdulos son: el
gestor de memoria virtual, el gestor de procesos, el monitor de referencia de
seguridad, y mdulo de llamadas a los procedimientos locales. Hay un
subsistema, el gestor de entrada/salida que evita que el ncleo interaccione
directamente con hardware, esto se requiere por razones de eficiencia y,
tambin en parte, por las operaciones de E/S. En dicho gestor se incluye el
sistema de archivos, el gestor de cach, los controladores de dispositivos y de
red,etc.

4. Servicios del sistema.Estaeslaltimacapayproporcionaunainterfazparael


softwarequeseejecutaenmodousuario.

Por encima de estas capas estn los subsistemas protegidos, que se encargan de la
comunicacin con el usuario final. Un
subsistemaprotegidoproporcionauna
interfaz de usuariogrfica, la lnea de
rdenesdelusuario.Otrafuncinque
tienen asignados es suministrar la
interfaz de programacin de
aplicacin (API, Application
Programming Interface). Esto
significaqueaplicacionescreadaspara
otros sistemas operativos pueden
ejecutarse sobre NT sin ninguna
modificacin, como es el caso de
OS/2,MSDOS,oWindows.

Para soportar esta estructura, Figura 9. 4 . Estructura interna de Windows NT


Windows NT utiliza un modelo
cliente/servidor. Este tipo de modelo
de computacin cliente/servidor es
normal en los sistemas distribuidos, y se pueden adoptar para uso interno en un nico
sistema.Enestecaso,cadaservidorseimplementacomounoomsprocesos,deformaque
cada proceso espera que algn cliente realice una peticin de alguno de sus servicios. Esta
peticinsehaceenviandounmensajealservidorquerealizalaoperacinpedidaycontesta

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 285

medianteotromensaje.Aspues,elservidoresunprogramaqueselimitaarealizaraquellas
funcionesquelesonsolicitadasdesdeelexterior.

Este tipo de arquitectura cliente/servidor simplifica mucho el sistema operativo bsico, se


pueden construir nuevos API sin ningn conflicto, adems de ser una forma naturalpara el
clculodistribuido.Porotrolado,tambinseaumentalafiabilidad,puestoquecadaservidor
seejecutaenunprocesoseparadoconsupropiaparticindememoriayprotegidodeotros
servidores,deformaquesifallanocorrompealrestodelsistema.

OtroaspectoimportantedeWindowsNTessusoportedehebras (threats)dentrodelos
procesos. Las hebras incorporan algunas de las funcionalidades asociadas tradicionalmente
con los procesos. Una hebra es una unidad bsica de ejecucin, que se puede interrumpir
para que el procesador pase a otra hebra. Desde el punto de vista del planificador y del
distribuidor, este concepto es equivalente al de proceso en algunos sistemas operativos
anteriores. EnWindows NTun proceso esunconjuntode una,o ms,hebras juntocon los
recursosdelsistemaasociados,comosonlasparticionesdememoria,archivos,dispositivos,
etc.Estocorrespondealconceptodeprogramaenejecucin.

Otra de las caractersticas de Windows NT es la utilizacin de los conceptos de diseo


orientadoaobjetos.Aunquenoesunsistemaoperativoorientadoaobjetospuro,yaqueno
estimplementadoenunlenguajeorientadoaobjetos.Lasestructurasdedatosqueresiden
completamente dentro de un ejecutable no se representan como objetos. Adems NT no
incorpora algunas caractersticas que son comunes en los sistemas orientados a objetos,
comolaherenciayelpolimorfismo.

Segn la metodologa de programacin orientada a objetos que WNT usa estn la


encapsulacinylasclaseseinstanciasdeobjetos.Laencapsulacinhacereferenciaaquelos
objetos consistan de varios datos, llamados atributos; y uno o ms procedimientos que se
puedenejecutarsobreestosdatos,llamadosservicios.Unaclasedeobjetosesunaplantilla
enlaqueseguardanlosatributosyserviciosdeunobjetoysedefinenciertascaractersticas
delmismo.

En NT no todas las entidades son objetos. De hecho, los objetos se emplean en los casos
dondelosdatosestnabiertosparaaccesoenmodousuarioocuandoelaccesoalosdatoses
compartidoorestringido.Entrelasentidadesrepresentadasporobjetosestnlosprocesos,
lashebras,losarchivos,lossemforos,losrelojesylasventanas.NTmanejatodoslostiposde
objetosdeunaformasimilar,medianteelgestordeobjetos,cuyaresponsabilidadescreary
eliminar los objetos segn la peticin de las aplicaciones y otorgar acceso a servicios de
objetosydatos.Unobjeto,yaseaunprocesoounahebra,puedereferenciaraotroobjeto
abriendoungestordelmismo.
286 PROGRAMACIN C++ Y COMUNICACIONES.

En NT los objetos pueden estar etiquetados, o no. Cuando un proceso crea un objeto no
etiquetado, el gestor de objetos devuelve un gestor al objeto, y la nica forma de
referenciarlo es mediante su gestor. Los objetos etiquetados tienen un nombre que puede
usarse por otro proceso para obtener el gestor del objeto. Los objetos etiquetados tienen
asociadalainformacindeseguridadenlaformadeuntestigodeacceso.Estainformacinse
puedeutilizarparalimitarelaccesoalobjeto.Porejemplo,unprocesopuedecrearunobjeto
semforoetiquetadodeformaqueslolosprocesosquelosconozcanlopuedanutilizar.El
testigodeaccesoasociadoconelsemforotendrunalistadetodoslosprocesosquepueden
accederal.

Gestindeprocesos

El diseo de los procesos Windows NT est marcado por la necesidad de


proporcionar soporte para los diferentes entornos de sistemas operativos. Como cada SO
tienesuformaparticulardenombraryrepresentaralosprocesos,deprotegerlosrecursos
de los mismos, de efectuar la comunicacin entre procesos y la sincronizacin, etc. La
estructura de los procesos y los servicios proporcionados por el ncleo de NT son
relativamentesencillos,ydepropsitogeneral.Estopermitequecadasubsistemadelsistema
operativoemuleunafuncionalidadyestructuradelosprocesosparticular.

EntrelascaractersticasdelosprocesosdeNTsepuedenresaltar:

LosprocesosenNTsonimplementadoscomoobjetos

Unprocesoejecutablepuedetenerunaomshebras.

Tantolosobjetosdelosprocesoscomolosdalashebrasllevanincorporadaslas
capacidadesdesincronizacin.

El ncleo de NT no mantiene ninguna relacin con los procesos que crea,


incluidaslasrelacionesentreprocesospadreyprocesoshijos.

Laconcurrenciaentrelosprocesosseconsigueporquehebrasdediferentesprocesos
se pueden ejecutar concurrentemente. Adems, si se dispone de varias CPUs, se pueden
asignar distintos procesos a hebras del mismo proceso, de forma que se ejecuten
concurrentemente. Las hebras del mismo proceso pueden intercambiar informacin entre
ellas a travs de la memoria compartida y tener acceso a los recursos compartidos del
proceso.

Dentrode laarquitecturade objetosdeWindows NT seproporcionanmecanismos


desincronizacinentrelashebras.Paraimplementarlosserviciosdesincronizacinsetiene

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 287

la familia de objetos de sincronizacin, que son entre otros: procesos, hebras, archivos,
sucesos semforos y relojes. Los tres primeros objetos tienen otros usos, pero tambin se
pueden utilizar para sincronizacin, el resto de los tipos de objetos se disean
especficamenteparasoportarlasincronizacin.

Gestindelamemoria

WindowsNTsediseparaimplementarloendiferentestiposdeprocesadores,yen
uno en los que ms se pens fue en el Intel 80486. Por ello, en Windows NT se adopta el
tamaodepginade4Kbytedel80486,comobasedesuesquemadememoriavirtual.Para
entender el esquema de memoria de Windows NT es conveniente estudiar los servicios de
memoriavirtualdel80486ydel80386.

En estos procesadores de Intel se incluye un hardware especial para soportar la


segmentacinylapaginacin.Aunqueestasfuncionespuedenserdesactivadas,pudindose
elegirentrelasopcionessiguientes:

Memorianisegmentada,nipaginada

Memoriapaginadaperonosegmentada

Memoriasegmentadaperonopaginada

Memoriasegmentadaypaginada.

Cuandoseempleasegmentacin,cadadireccinvirtual,olgica,secomponedeuncampo
dereferenciaalsegmentode16bits,dosdeellosdestinadosalosmecanismosdeproteccin
ycatorceparaespecificarelsegmento.Secuentaadems,conuncampodedesplazamiento
en el segmento de 32 bits; de esta forma, el espacio de memoria virtual que puede ver un
usuario es de 246=64 TB; mientras que el espacio de direcciones fsicas que se puede
direccionarcon32bitsesde4Gb.

Existen dos formas de proteccin asociadas con cada segmento: niveles de privilegio, y de
atributos de acceso. Son cuatro los niveles de privilegio, del 0 al 3, cuando se trata de un
segmentodedatoscorrespondealaclasificacindelmismoysiesunsegmentodeprograma
es su acreditacin. Un programa slo puede acceder a segmentos de datos para los que el
nivel de acreditacin es menor o igual que el de clasificacin. El uso de estos niveles de
privilegio depende del sistema operativo. Generalmente los niveles 0 y 1 corresponden al
sistemaoperativo,elnivel2aalgunossubsistemasyelnivel3alasaplicaciones.Losatributos
288 PROGRAMACIN C++ Y COMUNICACIONES.

deaccesodeunsegmentodedatosindicansielpermisodeaccesoesdelectura/escriturao
de slo lectura, y para un segmento de programa expresan si es de lectura/ejecucin o de
slolectura.

Ladireccinvirtualsetienequetransformarenunadireccinfsicamedianteunmecanismo
anlogo al explicado anteriormente. La segmentacin es una caracterstica opcional que se
puede desactivar. Cuando no se usa segmentacin los programas emplean direcciones
lineales, que corresponden a las direcciones en el espacio de memoria del proceso que
utilizan46bits,lacualhayqueconvertirenunadireccinrealde32bits.Elmecanismode
paginacinutilizadoparahacerestoconsisteenunaoperacindebsquedaenunatablade
dosniveles.Elprimernivelesundirectoriodepginasde1024entradas,conloquesedivide
elespaciodememoriade4Gbengruposde1024pginas,de4Mbdelongitudcadaunacon
su propia tabla de pginas. Cada tabla de pginas contiene 1024 entradas y cada entrada
correspondeaunapginade4Kb.Elgestordememoriapuedeusarundirectoriodepginas
para todos los procesos, un directorio de pginas para cada proceso o una combinacin de
ellos.Eldirectoriodepginasdelatareaactualestenmemoriaprincipal,perolastablasde
pginaspuedenestarenmemoriavirtual.

Sistema Operativo: Windows 2000


Windows2000noesrealidadunnicosistemaoperativo,sinoquesetratadeuna
familiadesistemascadaunodeellosconunasprestacionesy, porlotanto,destinadoaun
pblico diferente. La familia est compuesta por cuatro sistemas operativos: Professional,
Server,AdvancedSeveryDatacenterServer.

Fundamentalmente, la versin Professional est destinada a usuarios conWindows


95,Windows98,oWindowsNT;mientrasqueelrestosonsistemasdestinadosaplataformas
dondeahoraseubicaWindowsNTServero,incluso,eninstalacionesdondeactualmentese
encuentra instalada algunade las variantes de Unix quemigrarn aWindows 2000. Lo ms
habitualeslautilizacindeWindows2000ProfessionalyServer,dejandoelAdvancedServery
elDatacenterServerparagrandescorporaciones.

Windows2000esunsistemabasadoenlatecnologaNT,esdecir,quesiguiendocon
unanumeracincoherente,Windows2000enrealidaddeberahabersidoWindowsNT5.0.
Desde el punto de vista de la gestin de los equipos, las caractersticas de Windows 2000
hacen que una red basada en ste sistema sea ms fcil de administrar, facilitando la
instalacindeequiposclientesymejorandoelsoportedeperfilesflotantesyaccesoremoto.
RespectoaWindows98haheredadolafacilidaddeusoyelsoportededispositivosplugand
play;perointentandomantenerlarobustezyfiabilidaddeWindowsNT.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 289

OtrodelosgrandesavancesquesehanproducidoenWindows2000seencuentra
enlaseguridadatodoslosniveles.Noslosehamejoradolaseguridaddecaraalaccesoal
sistemaoproteccindearchivos,sinoquetambinloscontroladoressonmssegurosqueen
Windows9x/NT.EstosedebeaqueMicrosoftcertifica los controladoresdelosfabricantes
que lo soliciten. Aunque, se pueden instalar controladores sin certificar, si se opta por los
certificados,setieneunamayorcertezadequetodovaafuncionarcorrectamente,evitando
engranmaneraelbloqueodeordenadordebidoaloscontroladores.

El encriptado de archivos forma parte de otra de las caractersticas de seguridad


interesantesdeWindows2000.As,sialguienconsiguesaltarselossistemasdeseguridady
llevarseunarchivoquenolecorresponde,nopodrleerloyaqueestarencriptado.Tambin
se ha de tener en cuenta todas las caractersticas que aporta Explorer 5.01 con respecto a
Internet, ya que es la versin del navegador que se integra en el propio sistema. A todo lo
anteriorhayqueaadirlasmejorasquetieneparalosusuariosmviles,esdecir,aquellosque
utilizanprincipalmenteWindowsenunporttil.

MejorasdeWindows2000.

Windows 2000 Professional obtiene un buen rendimiento en la ejecucin de


aplicaciones de 32 bits, ya que su arquitectura est completamente basada en 32 bits.
Soportehasta4GBdememoriaRAMyhastadosprocesadoresconmultiprocesosimtrico.
Haymuchasplacasbasequesevendenconposibilidaddeincorporardosprocesadores.Sin
embargo, con Windows 9x en una placa con dos procesadores, siempre uno de los
procesadoresestparado,yaquenosoportamultiprocesosimtrico

Para conseguir una buena escalabilidad, la versin Server soporta hasta 4


procesadores para multiproceso simtrico, llegando hasta ocho en la versin Advanced
Server,conhasta4GBdememoriaRAM,y8GBenAdvancedServer.EnelcasodeAdvanced
Server se incorpora un equilibrado de cargas entre servidores para conseguir un mayor
rendimientoenservidorescrticos.

290 PROGRAMACIN C++ Y COMUNICACIONES.

Sistema Operativo: Windows XP


ElsistemaoperativoWindowsXP(WindowseXPerience)aparecienelmercadoenoctubre
del 2001. Su principal caracterstica es que proviene de una fusin entre las versiones de
Windows9x&MeylasversionesdeWindowsNT&2000;esdecir,pretendeserunsistema
conlarobustezyseguridaddelafamiliadeWNT,ylafacilidaddeusoycompatibilidadde
W9x.ComoresultadoMicrosofthaincorporadoenWXPelncleodelsistemaoperativode
WNTylosmecanismosyherramientasdegestindeW9x.

EstafusindelasdosfamiliasdesistemasoperativosdeMicrosoftesunaviejaaspiracinde
estefabricante,quepretendefusionarlosenunsolo.Estanoesunatareafcilydehechouno
delosprincipalesrequisitosdediseoeshaciaqutipodeusuarioestdestinadoelsistema
operativo.EnelcasodeWindowsXP,elusuariodenominadodomsticosereldestinatario.
Este tipo de perfil limita significativamente el sistema operativo, ya que se supone que la
persona que va a trabajar y administrar la mquina, no debe tener problemas al instalar
aplicaciones y que todo debera instalarse casi automticamente, lo cual impide plantearse
cuestiones tan elementales como implantar una buena gestin de usuarios, el control de
procesos,etc.

AlgunasdelasprincipalesnovedadesaparecidasconWindowsXPhansidolaactivacindela
licenciadelsistemaoperativo,ylacertificacindelhardware.Laactivacindelicenciaesun
intento de lucha contra el pirateo del software, consiste en registrar cada una de las
instalaciones que realiza el usuario, de forma que combinando los nmeros series del
hardwaredelcomputadorydelalicenciadelsistemaoperativo,entoncesMicrosoftdevuelve
una clave quepermite lautilizacin correcta del ordenador,y encasocontrario se limitara
drsticamentesuuso.Evidentemente,surgennumerosascuestionesqueresolver,comoson
laactualizacindelhardwaredelequipo,elusodeequiposdiferentes,ylaaparicindecracks
queseinvalidanlosmecanismosdeactivacin.Elsegundopuntocitadodecertificacindel
hardware es un intento de estandarizacin de todos los dispositivos que puedan ser

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 291

instaladosalcomputador;aunquelafinalidadesinteresante,estetambinesunpuntocon
una gran polmica, ya que, los avances en velocidad y prestaciones del nuevo hardware
siempresonsuperioresalosavancesenlosestndares;yelotroaspectoeslagestindela
certificacin,yaquepodradarlugaraunmonopoliomuycuestionable.

Otras novedades incorporadas en WXP son referentes a la interfaz que se suministra al


usuario.Sepuedenabrirvariassesionessimultneamente;sepuedecambiarelaspectodel
escritorio volviendo al de W9x; y se pueden definir sesiones en equipos remotos, lo que
permitiralareutilizacindeequiposobsoletos.

Sistema Operativo: Windows Vista


Elprocesodedesarrolloterminel8denoviembrede2006yenlossiguientestresmesesfue
entregado a los fabricantes de hardware y software, clientes de negocios y canales de
distribucin. El 30 de enero de 2007 fue lanzado mundialmente y fue puesto a disposicin
para ser comprado y descargado desde el sitio web deMicrosoft. La aparicin de Windows
VistavienemsdecincoaosdespusdelaintroduccindeWindowsXP,esdecir,eltiempo
mslargoentredosversionesconsecutivasdeMicrosoftWindows

El WindowsVistaeselprimersistemaoperativodeMicrosoftconcebidoparagarantizaruna
compatibilidad total con EFI (Extensible Firmware Interface), la tecnologa llamada a
reemplazar a las arcaicas BIOS que desde hace ms de dos dcadas han formado parte
indisoluble de los ordenadores personales, por lo tanto no emplear MBR (Master Boot
Record),sinoGPT(GUIDPartitionTable).

IntroducelasventanasdibujadascongrficosvectorialesusandoXAMLyDirectX.Paraello,
se utilizara una nueva API llamada Windows Presentation Foundation, cuyo nombre en
cdigoesAvalon,querequiereunatarjetagrficaconaceleracin3DcompatibleconDirectX.

AgregaunainterfazdelneadecomandodenominadaWindowsPowerShell,quefinalmente
seofrecicomounadescargaindependienteparaWindowsVistayWindowsXPSP2.

SeanunciunanuevaextensindebasededatosalsistemadearchivosllamadaWinFS.El
desarrollo de dicho sistema de ficheros ha sido abandonado por Microsoft, por lo tanto no
ser incluido en Windows Vista, por el momento, siendo compensado por un sistema de
bsquedabasadoenlaindexacin.

IntegradirectamenteenelsistemaunlectordenoticiasRSS(ReallySimpleSyndication,por
sussiglaseningls).

EnWindowsVistalautilidadderestauracindelsistemahasidoactualizadaeimplementada
comoherramientadeiniciodesesin,facilitandoaselrescatedelsistema.Ademsincluye
292 PROGRAMACIN C++ Y COMUNICACIONES.

un sistema unificado de comunicaciones llamado Windows Comunication Foundation, cuyo


nombreencdigoesIndigo.

Un sistema antispyware denominado Windows Defender, que tambin se liber para


WindowsXPconSP2(aunquerequierelavalidacindelsistema).

Aadealfirewalldesistemalacapacidaddebloquearconexionesquesalendelsistemasin
previaautorizacin.

Se incluye Windows ReadyBoost, la cual es una tecnologa de cach de disco incluida por
primera vez en el sistema operativo Windows Vista. Su objetivo es hacer ms veloces a
aquellos computadores que se ejecutan con el mencionado sistema operativo mediante
pendrives,tarjetasSD,compactFlashosimilares.

YseincorporaalsistemalaherramientaEncriptadordediscoBitLocker,paralaproteccinde
datosextraviadosenlasversionesEnterpriseyUltimate.

Mejoranotablementeelsistemadecontroldecuentasdeusuario,queesunacaracterstica
del sistema que limita las operaciones de determinados tipos de usuarios en el equipo. A
diferencia de las anteriores versiones de Windows, los nuevos usuarios de Windows Vista
(concuentaestndar)notienenderechosdeadministradorpordefecto,comolainstalaciny
lamodificacinderegistrosdelsistema.Secaracterizaportenerunavariantedelabandera
deWindowsendoscolores,azulclaroyamarilloenlaesquinainferiorderechadecadabotn
o archivo de instalacin. Para realizar tareas administrativas, el monitor se oscurece, se
bloqueacualquierordendelratnoteclado;yapareceunaventanadeconfirmacin,lacual
solo autoriza aceptando la orden o tecleando una contrasea. Solo permite la activacin o
desactivacindeste.

IncluyeunSyncCenterparasincronizacindeWindowsVistaconPocketPCsinnecesidadde
instalarelActiveSync.

IncorporaunsistemadeproteccinllamadoWindowsSoftwareProtectionPlatform(WSPP)
queesmspotentequeelactualWindowsGenuineAdvantage(WGA).Cuandodetecteque
lacopiaesilegal,loprimeroqueharseravisaralusuario ysielusuarionolograobtener
unacopiaautnticaelprogramaempezarairdesactivandoopcionesdelsistema,comoson
el Aero o el Windows Defender hasta nicamente dejar activo lo ms bsico como es el
navegador.

Cargaaplicacionesun15%msrpidoqueWindowsXPgraciasalacaractersticaSuperFetch.

Sereduceenun50%lacantidaddevecesqueesnecesarioreiniciarelsistemadespusdelas
actualizaciones.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 293

Sistema Operativo: Windows 7


A diferencia del gran salto arquitectnico y de caractersticas que sufri su antecesor
WindowsVistaconrespectoaWindowsXP,Windows7fueconcebidocomounaactualizacin
incrementalyfocalizadadeVistaysuncleoNT6.0,loquepermitimantenerciertogrado
de compatibilidad con aplicaciones y hardware en los que ste ya era compatible.4 Sin
embargo, entre las metas de desarrollo para Windows 7 se dio importancia a mejorar su
interfazparavolverlamsaccesiblealusuarioeincluirnuevascaractersticasquepermitieran
hacertareasdeunamaneramsfcilyrpida,almismotiempoqueserealizaranesfuerzos
paralograrunsistemamsligero,estableyrpido.Diversaspresentacionesofrecidasporla
compaa en 2008 se enfocaron en demostrar capacidades multitctiles, una interfaz
rediseada junto con una nueva barra de tareas y un sistema de redes domsticas
simplificado y fcil de usar denominado Grupo en el hogar, adems de importantes
mejorasenelrendimientogeneraldelsistemaoperativo.

Windows 7 incluye varias caractersticas nuevas, como mejoras en el reconocimiento de


escrituraamano,soporteparadiscosdurosvirtuales,rendimientomejoradoenprocesadores
multincleo,mejorrendimientodearranque,DirectAccessymejorasenelncleo.Windows7
aadesoporteparasistemasqueutilizanmltiplestarjetasgrficasdeproveedoresdistintos
(heterogeneousmultiadapteromultiGPU),unanuevaversindeWindowsMediaCentery
un gadget, y aplicaciones como Paint, Wordpad y la calculadora rediseadas. Se aadieron
varioselementosalPaneldecontrol,comounasistenteparacalibrarelcolordelapantalla,
un calibrador de texto ClearType, Solucin de problemas, Ubicacin y otros sensores,
Administrador de credenciales, iconos en el rea de notificacin, entre otros. El Centro de
Seguridad de Windows se llama aqu Centro de actividades, y se integraron en l las
categorasdeseguridadyelmantenimientodelequipo.
294 PROGRAMACIN C++ Y COMUNICACIONES.

Labarradetareasfuerediseada,esmsancha,ylosbotonesdelasventanasyanotraen
texto, sino nicamente el icono de la aplicacin. Estos cambios se hacen para mejorar el
desempeoensistemasdepantallatctil.EstosiconossehanintegradoconlabarraInicio
rpido usada en versiones anteriores de Windows, y las ventanas abiertas se muestran
agrupadasenunnicoiconodeaplicacinconunborde,queindicaqueestnabiertas.Los
accesos directos sin abrir no tienen un borde. Tambin se coloc un botn para mostrar el
escritorioenelextremoderechodelabarradetareas,quepermiteverelescritorioalposar
elpunterodelratnporencima.

SeaadieronlasBibliotecas,quesoncarpetasvirtualesqueagreganelcontenidodevarias
carpetasylasmuestranenunasolavista.Porejemplo,lascarpetasagregadasenlabiblioteca
Vdeos son: Mis vdeos y Vdeos pblicos, aunque se pueden agregar ms,
manualmente. Sirven para clasificar los diferentes tipos de archivos (documentos, msica,
vdeos,imgenes).

Una caracterstica llamada Jump lists guarda una lista de los archivos abiertos
recientemente.Haciendoclicderechoacualquieraplicacindelabarradetareasapareceuna
jump list, donde se pueden hacer tareas sencillas segn la aplicacin. Por ejemplo, abrir
documentosrecientesdeOffice,abrirpestaasrecientesdeInternetExplorer,escogerlistas
de reproduccin en el reproductor, cambiar el estado en Windows Live Messenger,anclar
sitosodocumentos,etctera

Existen seis ediciones de Windows 7, construidas una sobre otra de manera incremental,
aunquesolamentesecentrarnencomercializardosdeellasparaelcomndelosusuarios:
las ediciones Home Premium y Professional. A estas dos, se suman las versiones Starter,
Home Basic, y Ultimate, adems de la versin Enterprise, que est destinada a grupos
empresarialesquecuentenconlicenciamientoOpenoSelectdeMicrosoft.

Starter:EslaversindeWindows7conmenosfuncionalidades. Poseeunaversin
incompletadelainterfazAeroquenoincluyelosefectosdetransparenciaGlass,Flip
3D o las vistas previas de las ventanas en la barra de inicio y adems no permite
cambiar el fondo de escritorio. Est dirigida a PC de hardware limitado como
netbooks, siendo licenciada nicamente para integradores y fabricantes OEM.
Incluye una serie de restricciones en opciones de personalizacin y de programas,
adems de ser la nica edicin de Windows 7 sin disponibilidad de versin para
hardwarede64bits.
Home Basic: Versin con ms funciones de conectividad y personalizacin, aunque
su interfaz seguir siendo incompleta como en la edicin Starter. Slo estar
disponible para integradores y fabricantes OEM en pases en vas de desarrollo y
mercadosemergentes.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 295

HomePremium:Ademsdeloanterior,seincluyeWindowsMediaCenter,eltema
Aerocompletoysoporteparamltiplescdecsdeformatosdearchivosmultimedia.
Disponible en canales de venta minoristas como libreras, tiendas y almacenes de
cadena.
Professional:EquivalenteaVistaBusiness,peroahoraincluirtodaslasfuncionesde
la versin Home Premium ms Proteccin de datos con Copia de seguridad
avanzada,redadministradaconsoporteparadominios,impresinenredlocalizada
mediante Location Aware Printing y cifrado de archivos. Tambin disponible en
canalesdeventaalpblico.
Ultimate: Aadecaractersticas de seguridadyproteccin de datoscomo BitLocker
endiscosdurosexternoseinternos,Applocker,DirectAccess,BranchCache,soporte
a imgenes virtualizadasdediscos duros (en formatoVHD)y elpaquete de opcin
multilenguaje.
Enterprise: Esta edicin provee todas las caractersticas de Ultimate, con
caractersticas adicionales para asistir con organizaciones IT. nicamente se vende
porvolumenbajocontratoempresarialMicrosoftsoftwareAssurance.Tambinesla
nica que da derecho a la suscripcin del paquete de optimizacin de escritorio
MDOP.
EdicionesN:LasedicionesNestndisponiblesparaactualizacionesynuevascompras
de Windows 7 Home Premium, Professional y Ultimate. Las caractersticas son las
mismasquesusversionesequivalentes,peronoincluyenWindowsMediaPlayer.El
precio tambin es el mismo, ya que Windows Media Player puede descargarse
gratuitamentedesdelapginadeMicrosoft

Sistema Operativo: Windows 8


ElWindows8eslaversinactualdelsistemaoperativodeMicrosoftWindows,producidopor
Microsoftparasuusoencomputadoraspersonales,incluidascomputadorasdeescritorioen
casa y de negocios, computadoras porttiles, netbooks, tabletas, servidores y centros
multimedia.AadesoporteparamicroprocesadoresARM,ademsdelosmicroprocesadores
tradicionalesx86deIntelyAMD.Suinterfazdeusuariohasidomodificadaparahacerlams
adecuada para su uso con pantallas tctiles, adems de los tradicionales ratn y teclado.
MicrosofttambinanunciqueAeroGlassnoestarpresenteenlaversinfinaldeWindows
8.
296 PROGRAMACIN C++ Y COMUNICACIONES.

MicrosoftlanzalaventalaversinfinaldeWindows8,el26deoctubrede2012,3aos
despusdellanzamientodesupredecesorWindows7.Selanzalpblicogeneralunaversin
dedesarrollo("ConsumerPreview")el29defebrerode2012.Microsoftfinalmenteanunci
unaversincasicompletadeWindows8,laReleasePreview,quefuelanzadael31demayo
de 2012 y es la ltima versin preliminar de Windows 8 antes de su lanzamiento oficial. El
desarrollodeWindows8concluyconelanunciodelaversinRTMel1deagostode2012

Windows8 ha recibido duras crticas desde su lanzamiento, lo que ha motivado ventas por
debajo de las expectativas para la empresa desarrolladora. Incluso el propio Paul Allen, co
fundador de Microsoft, ha dicho que este sistema operativo es extrao y confuso en un
primercontacto,perosehamostradoconfiadoenquelosusuariosaprendernaquererla
nuevaversin.

TheVergepensqueelnfasisdeWindows8enlatecnologafueunaspectoimportantede
laplataforma,yquelosdispositivosdeWindows8(especialmenteaquellosquecombinanlos
rasgosdelascomputadorasporttilesylastabletas)convertirainmediatamentealiPaden
algopasadodemodadebidoalascapacidadesdelmodelohbridodelsistemaoperativoyel
crecienteintersenelserviciodelanube.AlgunasdelasaplicacionesincluidasenWindows8
fueronconsideradasbsicasyconcarenciadeunafuncionalidadprecisa,perolasaplicaciones
deXboxfueronelogiadasporsupromocindeunaexperienciadeentretenimientoenmulti
plataforma. Otras mejoras y caractersticas (como el historial de archivos, los espacios de
almacenamiento y las actualizaciones para el administrador de tareas) fueron considerados
comocambiospositivos.36PeterBrightdeArsTechnicasintiquemientrassuscambiosde
interfazdeusuarioquizsloseclipse,lamejora,eladministradordearchivosactualizados,la
funcionalidaddeunnuevoalmacenamiento,lascaractersticasexpandidasdeseguridadyla

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 297

actualizacindelAdministradordeTareasdeWindows8fueronnotablesmejoraspositivas
paraelsistemaoperativo.BrightpensqueesadualidaddeWindows8hacialastabletasylos
PCtradicionalesfueronunaspectoextremadamenteambiciosodelaplataforma,perose
mantuvo crtico ante la decisin de Microsoft de emular el modelo de Apple como una
plataformadedistribucindondeimplementaunaWindowsStore.

LainterfazdeWindows8hasidoobjetodereaccionesmixtas.Brightindicqueelsistemade
Edge UI del puntero y desplazamiento no fueron muy obvios debido a la carencia de
instruccionesproporcionadasporelsistemaoperativoenlasfuncionesaccedidasatravsdel
interfazdelusuario,inclusoporelmanualdevdeoaadidoenellanzamientodelRTM(que
solamente instruye a los usuarios a apuntar las esquinas de la pantalla y el toque de sus
lados).Apesardeesteobstculoautodescrito,BrightaclaraquelainterfazdeWindows8
trabajmuybienenalgunoslugares,peroempezaserincoherentecuandosecambiaentre
los ambientes Metro y de escritorio, algunas veces a travs de medios inconsistentes.37
TomWarrendeTheVergeaclarquelanuevainterfazfueasombrosacomosorprendente,
contribuyendoaunaexperienciaincreblementepersonalunavezqueespersonalizadopor
el usuario. Al mismo tiempo, Warren vio que la interfaz tiene una empinada curva de
aprendizaje,yfuedifcildeusarconuntecladoyunratn.Sinembargo,sesealque,sibien
obligaalosusuariosautilizarlanuevainterfazconunautilidadmstctil,fueunmovimiento
arriesgado para Microsoft en su conjunto, que era necesario con el fin de impulsar el
desarrollodeaplicacionesparaelalmacndeWindows.

Dos notables desarrolladores de videojuegos criticaron a Microsoft por adoptar una


aplicacindejardnvalladosimilaraotrasplataformasdemvilesconlaintroduccindela
Windows Store ya que sentan que estaba en conflicto con la visin tradicional de la PC
comounaplataformaabierta,debidoalanaturalezacerradadelatiendaylosrequisitosde
certificacinparalacompatibilidadylaregulacindeloscontenidos.Markus"Notch"Persson
se neg a aceptar una ayuda de un desarrollador de Microsoft para certificar su popular
videojuegoMinecraftparalacompatibilidaddeWindows8,replicandoconunapeticinpara
lacompaaacesardeintentararruinarlaPCcomounaplataformaabierta.GabeNewell
(cofundadordeValveCorporationquedesarrollelsoftwareSteam)describiaWindows8
comounacatstrofeparacualquieraenelespaciodelaPCdebidoalanaturalezacerrada
delWindowsStore

Sistemas Operativos para pequeos dispositivos: CE, Mobile yPhone


Windows CE (conocido oficialmente como Windows Embedded Compact y anteriormente
como Windows Embedded CE,1 tambin abreviado como WinCE) es un sistema operativo
desarrolladoporMicrosoftparasistemasembebidos.WindowsCEnodebeconfundirsecon
298 PROGRAMACIN C++ Y COMUNICACIONES.

WindowsEmbeddedStandard,queesunsistemabasadoenWindowsNT;WindowsCEest
desarrolladoindependientemente.

Windows Mobile es un sistema operativo mvil compacto desarrollado por Microsoft, y


diseadoparasuusoentelfonosinteligentes(Smartphones)yotrosdispositivosmviles.

Se basa en el ncleo del sistema operativo Windows CE y cuenta con un conjunto de


aplicacionesbsicasutilizandolasAPIdeMicrosoftWindows.Estdiseadoparasersimilara
las versiones de escritorio de Windows estticamente. Adems, existe una gran oferta de
software de terceros disponible paraWindows Mobile, la cual se podaadquirira travs de
WindowsMarketplaceforMobile.

OriginalmenteaparecibajoelnombredePocketPC,comounaramificacindedesarrollode
WindowsCEparaequiposmvilesconcapacidadeslimitadas.Enlaactualidad,lamayorade
lostelfonosconWindowsMobilevienenconunestiletedigital,queseutilizaparaintroducir
comandospulsandoenlapantalla.

SibienmuchospensamosqueWindowsMobilehabiasidodescontinuadotemporalmenteen
favordelnuevosistemaoperativoWindowsPhone,laampliagamadetelfonosindustriales

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 299

hahechoaMicrosoftoptarporunaterceralineadesistemasoperativosparamvilesqueha
llamado Windows Embedded Handheld 6.5, que vendra a ser la nueva linea de sistemas
operativosbasadosenWindowsMobile6.5

WindowsPhoneesunsistemaoperativomvildesarrolladoporMicrosoft,comosucesorde
laplataformaWindowsMobile.2Adiferenciadesupredecesor,estenfocadoenelmercado
de consumo generalista en lugar del mercado empresarial3 por lo que carece de muchas
funcionalidades que proporcionaba la versin anterior. Microsoft ha decidido no hacer
compatible Windows Phone con Windows Mobile por lo que las aplicaciones existentes no
funcionan en Windows Phone haciendo necesario desarrollar nuevas aplicaciones. Con
WindowsPhone,Microsoftofreceunanuevainterfazdeusuarioqueintegravariosservicios
en el sistema operativo. Microsoft planeaba un estricto control del hardware que
implementara el sistema operativo, para evitar la fragmentacin con la evolucin del
sistema,perohanreducidolosrequisitosdehardwaredetalformaquepuedequeesonosea
posible.4

El 29 de octubre de 2012 se lanz al mercado Windows Phone 8 solo para nuevos


dispositivos, debido a un cambio completo en el kernel que lo hace incompatible con
dispositivos basados en la versin anterior. Esta versin incluye nuevas funciones que de
acuerdo a Microsoft lo harn competitivo con sistemas operativos como iOS de Apple o
AndroiddeGoogle.5ConestaversincomienzalafragmentacindeWindowsPhoneyaque
quelosdispositivosbasadosenWindowsPhone7nopuedenactualizarseaWindowsPhone8

300 PROGRAMACIN C++ Y COMUNICACIONES.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 301

9.3. Sistema Operativo: Unix

UnixesunsistemaoperativomultiusuarioymultitareaescritoenellenguajeC.Ensu
diseosepusoespecialcuidadoenaislarlasrutinasdependientesdehardware,deformaque
fuera fcil transportarlo a diferentes plataformas. As se disponen de versiones para
prcticamente todo tipo de computadores, desde ordenadores personales, o estaciones de
trabajo,hastalossupercomputadores.

Historia

Unixtieneunalargaeinteresantehistoria.ElprimerdesarrollodeUnixsehizoenlos
laboratoriosBellenellenguajeensambladordelamquina.Prontosevioquenoeraprctico
tener que reescribir el sistema completamente para cada mquina, por lo que decidieron
hacerloenC,unlenguajedealtonivel.

La descripcin de Unix se hizo dedominio pblico en una comunicacin tcnica de


RitchieyThompsonen1974.PoresetrabajoambosrecibieronelpremioTuringdelaACM.La
publicacin de Unix hizo que se despertara un gran inters por su estudio. AT&T, duea
entoncesdelaslaboratoriosBell,notuvoinconvenienteenotorgarlicenciasgratuitasdeUnix
ainstitucionesyuniversidadesparaquepudieranincorporarsuspropiasideasymejorasenle
sistema.ProntosurgierondoslneasprincipalesdedesarrollodeUnix.Porunaparte,apareci
en1976laversin6,quefueelprimerestndardelmundoacadmico,seguidaen1978por
laversin7.SelespuedeconsiderarcomolosantecesoresdelasversionescomercialesUnix
desarrolladasenlosaos80porAT&T.

Porotraparte,laUniversidaddeCaliforniaenBerkeleymodificsustancialmenteel
cdigooriginalygenerunaversindenominadaUnixBSD(BerkeleySoftwareDistributions,
Distribuciones de Software de la Universidad de Berkeley). Las numerosas mejoras de Unix
BSDhicieronquefabricantescomoSunMicrosystemsyDECbasaransusversionesdeUnixen
ladeBerkeley.

Mientrastanto,AT&Tcontinudesarrollandoymejorandosusistemayen1982sali
deloslaboratoriosBellunanuevaversincomercialdeUnixdenominadaUnixSystemIII,que
notuvogranxitoyfueseguidarpidamenteporUnixSystemV.Alfinaldeladcadadelos
80 se tenan dos versiones incompatibles de Unix, la Unix 4.3 BSD y la versin 3 de Unix
System V, con sus respectivos dialectos, puesto que cada vendedor aada a sus propias
caractersticas.Debidoaestepanoramahahabidodistintosintentosdecrearunestndar.El
primer intento serio se realiz bajo los auspicios del IEEE Standards Board, a travs del
proyecto POSIX (Portable Operating System Interface X, Interfaz X Portable del Sistema
Operativo).Esteestndar,conocidocomo1003.1eslainterseccindelUnixSystemVydel
302 PROGRAMACIN C++ Y COMUNICACIONES.

Unix4.3BSD.elresultadofuealgoparecidoalantepasadocomndelosdos,laversin7de
Unix.

La realidad es que en la actualidad sigue habiendo tantos sistemas Unix como


vendedores,yalgunosmsdesarrolladosconunafinalidadacadmica,comoLinux,BSDUnix.
IBM sigue comercializando sus mquinas con su propia versin denominada AIX, Hewllettt
Packard suministra sus equipos con su versin HPUX, Sun Microsystems ha pasado de su
versinSUNOS,basadaenelUnix4.3BSD,aSolaris,dondesehanincorporadonuevasideas
para soportar sus nuevas mquinas RISC con multiprocesadores. As se poda continuar
indicando otras versiones comerciales. En lo que sigue, el sistema que se describe es Unix
SystemV,aunquesecomentenalgunascaractersticasdePosix.

Descripcin.

ElhardwareestrodeadoporelncleodeUnix,queeselautnticoSO,denominadoaspara
enfatizarsuaislamientodelasaplicacionesydelosusuarios.Sigueacontinuacinlacapade
libreras,quecontieneunprocedimientoparacadallamadaalsistema.EnelestndarPosixse
especificalainterfazdelalibreraynoeldelallamadaalsistema.Porencimadeestascapas,
todas las versiones de Unix proporcionan una serie de programas de utilidades, como el
procesador de rdenes (shell), los compiladores, los editores, los programas de
procesamientodetextoylasutilidadesparaelmanejodelosarchivos.Desdeelterminalel
usuariollamadirectamenteaestosprogramas.

Sepuedenconsiderartresinterfacesdistintas:

Lainterfazdellamadasalsistema.

Lainterfazdelibrera.

La interfaz del usuario, que est formada por los programas de utilidades
estndar.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 303

Elautnticosistemaoperativoeselncleoqueinteractadirectamenteconelhardwareylas
rutinasprimitivas,quecorrespondenalbloquedecontroldelhardwareyenlapartesuperior
estlainterfazdellamadasalsistema,quepermitealsoftwaredealtonivelteneraccesoa
funcionesespecficasdelncleo.Elrestodelncleosepuededividirendospartesprincipales,
queestnasociadasalcontroldeprocesosyalagestindearchivosydelaentrada/salida.

La parte de control de procesos se responsabiliza de la planificacin y distribucin de los


procesos,delasincronizacinycomunicacinentreprocesos,ydelagestindelamemoria.
La parte de gestin de archivos intercambia datos entre la memoria y los dispositivos
externos, tanto de cadena de caracteres como de bloques, para lo que se disponen de
distintos controladores de perifricos. En la transferencia orientada a bloques, se utiliza un
mtododecachdedisco,queinterponeunbufferdelsistemaenlamemoriaprincipalentre
elespacio dedireccionesdeusuarioyeldispositivoexterno.

Controlysincronizacindeprocesos.

En Unix todos los procesos, excepto dos procesos bsicos del sistema, se crean mediante
rdenesdelprogramadeusuario.Losdosprocesossonlosdearranqueeinicializacin.Los
nueveestadosenlosqueestarunprocesoson:

Ejecucinenmodousuario.

Ejecucinenmodoncleo.
304 PROGRAMACIN C++ Y COMUNICACIONES.

Preparadoparaejecucinenmemoriaprincipal,tanprontocomoloplanifiqueel
ncleo.

Esperaenmemoriaprincipal.Elprocesoestenlamemoriaprincipalesperando
queocurraunsuceso.

Preparado para ejecucin pero en memoria secundaria. El intercambiador, el


proceso0,debetransferirloalamemoriaprincipalantesdequeelncleopueda
planificarsuejecucin.

Espera en memoria secundaria. El proceso est aguardando un suceso y tiene


queintercambiarsedesdelamemoriasecundaria.

Adelantado. El proceso se est ejecutando desde el modo ncleo al modo


usuario,peroelncleoloadelantayhaceuncambiodecontextoparaplanificar
otroproceso.Esencialmenteeslomismoqueestadodepreparado,ladistincin
sehaceparaenfatizarlaformadeentrarenelestadoadelantado.

Creado o nonato. El proceso se ha creado de nuevo y est en un estado de


transicin.Elprocesoexisteperoannoestpreparadoparaejecucin.Estees
elestadoinicialparatodoslosprocesos,exceptoparaelproceso0.

Zombi. El proceso ejecuta la llamada exit() (fin del programa), pero todava no
puede finalizar por lo que queda en estado zombi. Normalmente, un proceso
pasa a estado de zombi cuando est a la espera de que finalice alguno de sus
hijos.

Comunicacinentreprocesos

EnUnixsetienendistintosalgoritmosparalacomunicacinysincronizacinentreprocesos.
Entreestos,losmsimportantesson:

Tuberas(pipes).

Seales.

Mensajes.

Memoriacompartida.

Semforos.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 305

Lastuberaspermitentransferirdatosentreprocesosysincronizarlaejecucindelosmismos.
Usanunmodelodeproductorconsumidor,yhayunacolaFIFOdondeunprocesoescribeyel
otrolee.

Otra forma de comunicacin es mediante el envo de seales. Una seal es un mecanismo


softwarequeinformaaunprocesodequehaocurridoalgnsucesoasncrono.Unaseales
similaraunainterrupcinhardware.Todaslassealessetratanigual,aquellasqueocurrenal
mismo tiempo se presentan al proceso simultneamente, sin ningn orden en particular.
Cuandoseenvaunasealaunproceso,elncleoactualizaunbitenuncampodesealesde
laentradadelatabladelproceso,dependiendodeltipodeseal.

Las tuberas y las seales constituyen una forma limitada de comunicacin. Los otros
mecanismosestndardecomunicacinson:

1. Los mensajes,quepermitena los procesos enviar acualquier procesocadenas


dedatosconundeterminadoformato.

2. La memoria compartida, que posibilita que los proceso comparten parte de su


espaciodedireccionesvirtuales.

3. Lossemforos,quepuedensincronizarlaejecucindelosprocesos.

Losmensajessoncadenasdedatosconunformatoestablecido.Elprocesoqueenvaun
mensajeespecificaeltipodelmismoconcadaunodelosqueenva.Elreceptorpuede
usarestedatocomouncriteriodeseleccin,deformaquepuedeatenderalosmensajes
segnelordendellegadaenunacolaoporeltipo.Cuandounprocesointentaenviarun
mensajeaunacolaqueestllena,elprocesoquedasuspendido,lomismoocurresi
intentaleerdeunacolavaca.

Pero quiz, la forma ms rpida de comunicacin entre procesos en Unix es mediante la


memoria compartida, que permite que varios procesos accedan al mismo espacio de
direcciones virtuales de memoria. Los procesos leen y escriben en la memoria compartida
utilizando las mismas instrucciones mquina. Para manipular la memoria compartida se
utilizanllamadasalsistemasimilaresalasllamadasdelosmensajes.

Lossemforossincronizanygestionanelusoderecursos.Secreanenconjuntos,unconjunto
consta de uno o ms semforos. Esta generalizacin de los semforos da una considerable
flexibilidadenelfuncionamientodelasincronizacinycoordinacindelosprocesos.

Gestindelamemoria
306 PROGRAMACIN C++ Y COMUNICACIONES.

EnlasprimerasversionesdeUnixnosetenanesquemasdememoriavirtual,nicamentese
utilizaban particiones variables de memoria. En la actualidad, muchas de las
implementaciones hacen uso de memorias virtual paginada, utilizndose esquemas de
intercambioypaginacin.

Aunqueelesquemadegestindelamemoriavaradeunsistemaaotro,enUnixSystemVse
emplean unas estructuras de datos, que con pequeos cambios, son independientes de la
mquina.Estasestructurasson:latabladepginas,eldescriptordebloquesdeldisco,latabla
de datos de pgina y la tabla del intercambiador. Se tiene una tabla de pginas para cada
proceso, con una entrada para cada una de las pginas de memoria virtual del proceso.
Asociada con cada pgina de un proceso hay una entrada en el descriptor de bloques del
discoquedescribelacopiaeneldiscodelapginavirtual.Enlatabladedatosdelmarcode
pgina se describe cada uno de los marcos de la memoria real. El ndice de la tabla es el
nmero del marco. Hay varios punteros utilizados para crear listas dentro de la tabla. Los
marcosdisponiblesseenlazanjuntosenunalistademarcoslibres.

Por ltimo, la tabla de intercambio tiene una entrada por cada pgina en el dispositivo y
existeunaporcadadispositivodeintercambio.Estatablatienedosentradas:elcontrolador
dereferencia,queeselnmerodepuntosdeentradasdelatabladepginasaunapginaen
eldispositivodeintercambio,yelidentificadordelapginaenlaunidaddealmacenamiento.

Sistemadearchivos

EnUnixsedistinguencuatrotiposdearchivos:

Ordinarios. Son los archivos que contiene la informacin del usuario, los
programasdeaplicacinodeutilizacindelsistema.

Directorios. Son archivos que contiene listas de nombres de archivos, ms los


punterosasociadosalosnodosi.Estnorganizadosdeunaformajerrquica.

Especiales.Estoscorrespondenalosperifricos:impresoras,discos,etc.

Etiquetados.Sonlostubosetiquetadosdiscutidosanteriormente.

TodoslostiposdearchivosdeUnixsegestionanporelsistemaoperativomediantelos
nodosi.Estoscorrespondenaunatablaquecontienelosatributosylasdireccionesdelos
bloquesdelarchivo.Losarchivosseubicandinmicamente,segnesnecesario,sinusar
unapreubicacin,deestaforma,losbloquesdeunarchivoeneldisconoson
necesariamentecontiguos.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 307

Subsistemadeentrada/salida

ParaelsistemaoperativoUnixtodoslosperifricosestnasociadosaunarchivoespecial,que
segestionaporelsistemadearchivos,pudindoseleeryescribircomootroarchivoms.Se
consideran dos tipos de perifricos: de bloque y de carcter. Los perifricos de bloque son
perifricos dealmacenamiento deacceso arbitrario (porejemplo los discos). Losperifricos
orientados a caracteres incluyen a los otros tipos, por ejemplo las impresoras o los
terminales.

LaE/Ssepuederealizarutilizandounbuffer,comounazonadealmacenamientointermedio
de los datos procedentes o con destino a los perifricos. Hay dos mecanismos de buffer:
sistema de cach y colas de caracteres. El cach de buffer es esencialmente una cach de
disco.LatransferenciadedatosentrelacachdelbufferyelespaciodeE/Sdelprocesodel
usuarioserealizamedianteDMA,yaqueambosestnlocalizadosenlamemoriaprincipal.El
otro mecanismo de buffer, las colas de caracteres, resulta apropiado para los perifricos
orientados a caracteres. El dispositivo de E/S escribe una cola de caracteres que son ledos
porelprocesoo,inversamente,elprocesolosescribeyelperifricoloslee.Enamboscasos
seutilizaunmodelodeproductorconsumidor.

LaE/Ssinbufferessimplementeunaoperacindeaccesodirectoamemoria(DMA,Direct
MemoryAccess),entreelperifricoyelespaciodememoriadelproceso.Esteeselmtodo
msrpidopararealizarunaentrada/salida,sinembargo,unprocesoqueestrealizandouna
transferenciadeentrada/salidasinbufferestbloqueadoenlamemoriaprincipalynopuede
intercambiarse.
308 PROGRAMACIN C++ Y COMUNICACIONES.

9.4. Sistema Operativo: Linux

LinuxfueelproyectooriginaldeunestudiantedeinformticallamadoLinusTorvalds
que entonces tena veintitrs aos. Linux empez siendo un pasatiempo para Linus, que
esperaba crear una versin ms slida de UNIX para usuarios de Minix. Tal y como
apuntbamos antes, Minix es un programa desarrollado por el profesor de informtica
AndrewTannebaum.

El sistemaMinix se escribiparademostrar algunosconceptos informticos que se


encuentran en los sistemas operativos. Torvalds incorpor estos conceptos en un sistema
autnomo que imitaba a UNIX. El programa se puso a disposicin de los estudiantes de
informtica de todo el mundo y muy pronto cont con muchos seguidores, incluyendo a
aquellos que participaban en sus grupos de debate de Usenet. Linus Torvalds decidi
entoncesproporcionarunaplataformamsaccesibleparalosusuariosdeMimixquepudiera
ejecutarseencualquierIBMPCycentrsuatencinenlasrecinaparecidascomputadoras
basadas en 80386 debido a las propiedades de conmutacin de tareas que incorporaba la
interfazenmodoprotegidodel80386.

PropiedaddeLinux

Linus Torvalds conserva los derechos de autor del kernel bsico de Linux. Red Hat,
Inc,poseelosderechosdeladistribucinRedHatyPaulVolkerding,queseacogenalaGPL
(GeneralPublicLicense,LicenciaPblicaGerenal)deGNU.Deecho,Linuxymuchosdelos
quehancontribuidoaldesarrollodeLinux,hanprotegidosutrabajoconlaGPLdeGNU.

Enocasiones,estalicenciasedenominaGNUCopyleft,quenoesmsqueunjuego
de palabras con el trmino ingls Copyright. Esta licencia cubre todos los programas
producidos por GNU y por la FSF (Free Software Foundation, Fundacin de Software de
Libredistribucin).Estalicenciapermitealosdesarrollarescrearprogramasparaelpblicoen
general.LapremisafundamentaldeGNUesladepermitiratodoslosusuariosaccesolibrea
losprogramasconlaposibilidaddemodificarlos,siaslodesean.Lanicacondicinimpuesta
es que no puede limitarse el cdigo modificado; es decir, que el resto de usuarios tiene
derechotambinautilizarelnuevocdigo.

El GNU Copyleft, o GPL, permite a los creadores de programas conservar sus derechos de
autor,peropermitiendoalrestodeusuarioslaposibilidaddecopiarlos,modificarlosyhasta
de venderlos. Sin embargo, al hacerlo, no pueden limitar ningn derecho similar a los que
comprenelprograma.Sisevendeelprogramatalycomoest,ounamodificacindelmismo,

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 309

el usuario debe facilitar adems el cdigo fuente. Por ello, cualquier versin de Linux
incorporasiempreelcdigofuentecompleto.

LadistribucindeLinuxcorreacargodedistintascompaas,cadaunadeellascon
su propio paquete de programas, aunque todas faciliten un ncleo de archivos que
conformanunaversindeLinux.Lasmsdifundidasson:DebianLinux,RedHat,Slackware,
MandrakeyUbuntu.

CaractersticasdeLinux

La mayora de variantes de UNIX integran un tipo de multitareas llamado multitarea


preferente,esdecir,quecadaprogramatienegarantizadalaoportunidaddeejecutarseyse
ejecutaprecisamenteeltipodemultitareaqueincorporaLinux.

Alguna de las ventajas que ofrece la multitarea preferente, adems de reducir los tiempos
muertos, es decir, aquellos momentos en los que no puede ejecutar ninguna aplicacin
porquetodavanosehacompletadounatareaanterior,poseeunagranflexibilidad,quele
permiteabrirnuevasventanassintenerquecerrarotrasconlasqueesttrabajando.

Linux y otros sistemas operativos de multitarea preferentes ejecutan los procesos


preferentes,controlandolosprocesosqueesperanparaejecutarse,ascomolosqueseestn
ejecutando. Despus, el sistema programa cada proceso para que todos tengan acceso al
microprocesador.Elresultadoesquelasaplicacionesabiertasparecenestarejecutndoseal
mismo tiempo, aunque en realidad existe una demora de una aplicacin y el momento
programadoporLinuxparavolveraocuparsedeeseproceso.Laotragrancaractersticade
LinuxesquelepermiteaccederaloscdigosdefuentedelsistemaoperativoLinuxsegnsus
preferencias. Los fabricantes comerciales nunca le permitiran acceder a estos cdigos de
fuenteparamodificarsusproductos.

LacapacidaddeLinuxparaasignareltiempodemicroprocesadorsimultneamenteavarias
aplicaciones,lgicamentepermitiofreceraccesoavariosusuariosalavez,ejecutandocada
uno de ellos una o varias aplicaciones. La gran ventaja de Linux y de sus caractersticas de
multitareaymultiusuarioesquemsdeunusuariopuedetrabajarconlamismaversindela
aplicacin al mismo tiempo y desde el mismo terminal o desde terminales distintos. Sin
embargo,estacapacidaddeLinuxnodebeconfundirseconelhechodequevariosusuarios
puedanactualizarelmismoarchivosimultneamente,algoquepodrallevaralaconfusiny
alcaostotal,yporelloresultaindeseable.

Shellprogramables
310 PROGRAMACIN C++ Y COMUNICACIONES.

El proceso de exploracin que realiza el shell se denomina anlisis y consiste en la


descomposicin de las rdenes en componentes que se puedan procesar ms fcilmente.
Cadacomponenteseinterpretayejecuta,incluyendoloscaracteresespecialesqueconfieren
un significado adicional al shell. Estos caracteres especiales se amplan an ms en sus
correspondientesprocesosderdenesyseejecutan.

Aunque muchas versiones UNIX y Linux incluyen ms de un tipo de shell, todos ellos
funcionanbsicamentedelmismomodo.Unshellrealizalatareademediarentreelusuarioy
el ncleo del sistema operativo Linux. La diferencia esencial entre los tres shell disponibles
radicaenlasintaxisdelalneaderdenes.Aunquenosuponeunalimitacinestrictamente
hablando,elusodelasrdenesdelshellColasintaxisdelosshellsBourneobashpueden
traerleproblemas.

Algunosusuariosvaninclusomsall,diseandoprogramasqueenlazanprocesosy
aplicaciones para reducir su trabajo a veces hasta una nica sesin de entrada de datos,
consiguiendo as que el sistema actualice de una sola vez los numerosos paquetes de
programas.

IndependenciadedispositivosbajoLinux

UNIX soluciona los problemas que supone aadir otros perifricos, contemplando
cada uno de ellos como un archivo aparte. Cuando se necesitan nuevos dispositivos, el
administrador del sistema aade al kernel el enlace necesario. Este enlace, tambin
denominadocontroladordedispositivo,seocupadequeelkernelyeldispositivosefusionen
delmismomodocadavezquesesolicitaelserviciodeldispositivo.

A medida que se van desarrollando y distribuyendo mejores perifricos, el sistema


operativodeUNIXpermitealusuariounaccesoinmediatoysinrestriccionesasusservicios,
en cuanto los dispositivos se enlazan al kernel. La clave de la independencia de los
dispositivosresideprecisamenteenlaadaptabilidaddelkernel.

VentajasydesventajasdelusodeLinux

Linux integra adems una implementacin completa del protocolo de red TCP/IP.
Linux permite conectarse a Internet y acceder a toda la informacin que incluye. Linux
tambindisponedeunsistemacompletodecorreoelectrnicoconelquesepuedeenviary
recibirmensajesatravsdeInternet,yotrasredesdeordenadores.

Igualmente, incorpora una completa interfaz grfica de usuario (GUI), la Xfree86


basada en el popular sistema XWindows, y que supone una implementacin completa del
sistema XWindows, al que se puede acceder libremente con Linux. Xfree86 ofrece los

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 9. INTRODUCCIN A LOS SISTEMAS OPERATIVOS 311

elementosGUIhabitualesqueincluyenotrasplataformasGUIcomerciales,comoWindowsy
OS/2.

Muchas especificaciones de los sistemas abiertos requieren el cumplimiento de


POSIX (Portable Operating System Interface X), lo que significa alguna forma de UNIX.
Actualmente,Linuxcumpleconestosestndares,dehecho,Linuxsediseparapermitirla
portabilidaddelcdigofuente,porloquestieneunprogramadelaempresaqueseejecute
sobre una versin de UNIX, podr trasladar fcilmente dicho programa a un sistema que
ejecuteLinux.

Linux no dispone de un servicio tcnico, lo cual supone un problema para su


utilizacin dentro de una estructura empresarial. Lo mismo sucede con las aplicaciones de
Linux porque, aunque existan algunos programas comerciales, la mayora los desarrollan
pequeos grupos que despus los ponen a disposicin del pblico. No obstante, muchos
desarrolladoresprestansuayudacuandoselesolicita.

OtradesventajadeLinuxesquesuinstalacinpuederesultardifcilynofuncionaen
todas las plataformas de hardware. A diferencia de los programas comerciales, donde un
mismo equipo de desarrolladores pasa meses construyendo y probando un programa en
distintascondicionesycondiferenteshardware,losdesarrolladoresdeLinuxseencuentran
repartidos por todo el mundo. No existe un programa formal que garantice la calidad de
Linux,sinoquelosdistintosdesarrolladoreslanzansusversionescuandoquiere.Adems,el
hardware admitido por Linux depende del utilizado por el desarrollador en el momento de
escribir esa parte del cdigo. Por tanto, Linux no funciona con todo el hardware disponible
actualmenteparaPC.

312 PROGRAMACIN C++ Y COMUNICACIONES.

9.5. Mquinas virtuales

Una mquina virtual es un conjunto de programas que simulan la ejecucin de otros


programasinclusodeotrossistemasoperativos.

Varios sistemas operativos distintos pueden coexistir sobre el mismo ordenador, en slido
aislamiento el uno del otro, por ejemplo para probar un sistema operativo nuevo sin
necesidaddeinstalarlodirectamente.

La mquina virtual puede proporcionar una arquitectura de instrucciones que sea algo
distintadeladelaverdaderamquina.Esdecir,podemossimularhardware.

Ejemplos:VmWare,VirtualBox,MicrosoftVirtualServer,etc.

UPM-EUITI-2015. Miguel Hernando.


10. Sistemas Distribuidos: Redes

10.1. Fundamentos de redes.

Definicin y tipos.
Unareddecomputadoresesunaagrupacindedosomscomputadoresquesecomunican
entres.Segnladimensindelaredsesuelendividirendosgrupos:

Redesderealocal(LAN,LocalAreaNetwork).Conectancomputadorescercanos
unosdelasotros.Enalgunoscasos,"local"significadentrodelamismahabitacino
edificio; en otros casos, se refiere a computadoresubicados a varios kilmetros de
distancia.
Redes de rea extendida o redes de gran alcance (WAN, Wide Area Network).
Constan de computadores que se encuentran en diferentes ciudades o incluso
pases. Son redes de larga distancia, debido al gran trayecto que debe recorrer la
informacinqueintercambian.

Departamento de Electrnica Automtica e Informtica Industrial


314 PROGRAMACIN C++ Y COMUNICACIONES.

Objetivos de las redes.


El gran auge que han tenido las redes de computadores se debe a la enorme ventaja que
supone disponer de equipos de trabajo interconectados. Las principales ventajas se
enumeranacontinuacin.

Compartir recursos. Todos los programas, datos y equipos, estn disponibles para
cualquier ordenador de la red que lo solicite, sin importar la localizacin fsica del
recursoydelusuario.
Mejora de la fiabilidad. Proporcionan una alta fiabilidad, al contar con fuentes
alternativasdesuministro.LapresenciademltiplesCPU,significaquesiunadeellas
deja de funcionar, las otras son capaces de su trabajo, aunque se tenga un
rendimientoglobalmenor.
Ahorro econmico. Los ordenadores pequeos tienen una mejor relacin
coste/rendimiento,comparadaconlaofrecidaporlasmquinasgrandes.Estasson,a
grandesrasgos,diezvecesmsrpidasqueelmsrpidodelosmicroprocesadores,
perosucostoesmilesdevecesmayor.
Mediodecomunicacin.Unareddeordenadorespuedeproporcionarunpoderoso
mediodecomunicacinentrepersonasqueseencuentranmuyalejadasentres.Ala
largaelusoderedes,comounmedioparaenriquecerlacomunicacinentreseres
humanos, puede ser ms importante que los mismos objetivos tcnicos, como por
ejemplo,lamejoradelafiabilidad.

En la figura 10.1, se muestra la clasificacin de sistemas multiprocesadores distribuidos de


acuerdo con su tamao fsico. En la parte superior se encuentran las mquinas de flujo de
datos,quesonordenadoresconunaltoniveldeparalelismoymuchasunidadesfuncionales
trabajando en el mismo programa. En el siguiente nivel se encuentran las mquinas
multiprocesador, que son sistemas que se comunican a travs de memoria compartida.
Seguidamente, las redes locales, que son ordenadores que se comunican por medio del
intercambio de mensajes. Finalmente, a la conexin de dos o ms redes se le denomina
interconexinderedes.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 10. SISTEMAS DISTRIBUIDOS: REDES 315

Figura 10. 1 Clasificacin de procesadores segn su interconexin

Aplicaciones de las redes.


Paradarunaideasobrealgunosusosimportantesderedesdeordenadores,Acontinuacin
sedescribenbrevementevariosejemplos.

Accesoaprogramasremotos.Unaempresaquehaproducidounmodeloquesimula
la economa mundial puede permitir que sus clientes se conecten usando la red y
ejecuten el programa para ver cmo pueden afectar a sus negocios las diferentes
proyeccionesdeinflacin,detasasdeintersydefluctuacionesdetiposdecambio.
Acceso a bases de datos remotos. Hoy en da, ya es muy fcil ver, por ejemplo, a
cualquierpersonahacerdesdesucasareservasdeavin,autobs,barcoyhoteles,
restaurantes, teatros, etc., para cualquier parte del mundo y obteniendo la
confirmacindeformainstantnea.Enestacategoratambincaenlasoperaciones
bancariasquesellevanacabodesdeeldomicilioparticular,ascomolasnoticiasdel
peridicorecibidasdeformaautomtica.
Medios alternativos de comunicacin. La utilizacin del correo electrnico, que
permite mandar y recibir mensajes de cualquier parte del mundo, muestra el gran
potencial de las redes en su empleo como medio de comunicacin. El correo
electrnicoescapazdetransmitirlavozdigitalizada,fotografaseimgenesmviles
devdeo.
316 PROGRAMACIN C++ Y COMUNICACIONES.

Arquitecturas de redes
Lamayoradelasredesseorganizanenunaseriedecapasoniveles,conobjetodereducirla
complejidaddesudiseo.Cadaunadeellasseconstruyesobresupredecesora.Elnmerode
capas, el nombre, el contenido, y la funcin de cada una varan de una red a otra. Sin
embargo,encualquierred,elpropsitodecadacapaesofrecerciertosserviciosalascapas
superiores,liberndolasdelconocimientodetalladosobrecmoserealizandichosservicios.

Lacapanenunamquinaconversaconlacapandeotramquina.Lasreglasyconvenciones
utilizadasenestaconversacinseconocencomoprotocolodelacapan.Alasentidadesque
formanlascapascorrespondientesenmquinasdiferentesselesdenominaprocesopares;es
decir de igual a igual. En otras palabras, son los procesos pares los que se comunican
medianteelusodelprotocolo.

Enrealidad,noexisteunatransferenciadirectadedatosdesdelacapandeunamquinaala
capa n de otra, sino ms bien, cada capa pasa la informacin de datos y control a la capa
inmediatamente inferior; y as sucesivamente, hasta que se alcanza la capa localizada en la
partemsbajadelaestructura.Debajodela1estelmediofsico,atravsdelcualserealiza
lacomunicacinreal.

Entre cada par de capas adyacentes existe una interfaz, la cual define los servicios y
operaciones primitivas que la capa inferior ofrece a la superior. Al conjunto de capas y
protocolos se le denomina arquitectura de la red. Las especificaciones de sta debern
contener la informacin suficiente que le permita al diseador escribir un programa o
construirelhardwarecorrespondienteacadacapa,yquesigaenformacorrectaelprotocolo
apropiado. Tanto los detalles de realizacin, como las especificaciones de las interfaces, no
forman parte de la arquitectura, porque se encuentran escondidas en el interior de la
mquinaynosonvisiblesdesdeelexterior.Msan,noesnecesarioquelasinterfacesde
todaslasmquinasenunaredseaniguales,supuestoquecadaunadelasmquinasutilice
correctamentetodoslosprotocolos.

La abstraccin del proceso par es importante para el diseo de redes, sin esta tcnica de
abstraccin sera difcil, dividir el diseo de una red completa; es decir, sera un problema
intratable si no se divide en varios ms pequeos y manejables, el diseo de capas
individuales. En la figura 10.2 se muestra un esquema del significado de los trminos capa,
protocoloeinterfaz.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 10. SISTEMAS DISTRIBUIDOS: REDES 317

Figura 10. 2 Capas, protocolos e interfaces

10.2. Modelo de referencia OSI

Elmodeloquesevaatrataracontinuacinestbasadoenunapropuestadesarrolladaporla
Organizacin Internacional de Normas (ISO). Este modelo supuso un primer paso hacia la
normalizacin internacional de varios protocolos, [Stallings 00] y [Tanenbaum 97]. A este
modelo se le conoce como Modelo de Referencia Interconexin de sistemas abiertos, ms
conocido como modelo OSI de ISO, (OSI, Open System Interconnection). Este modelo de
referenciaserefierealaconexindesistemasheterogneos,esdecir,asistemasdispuestosa
establecercomunicacinconotrosdistintos.

El modelo OSI consta de 7 capas. Los principios aplicados para el establecimiento de siete
capasfueronlossiguientes:

1. Una capa se crear en situaciones donde se necesita un nivel diferente de


abstraccin.

2. Cada capa deber efectuar una funcin bien definida, que le proporcione entidad
propia.

3. Lafuncinquerealizarcadacapadeberseleccionarseconlaintencindedefinir
protocolosnormalizadosinternacionalmente.
318 PROGRAMACIN C++ Y COMUNICACIONES.

4. Loslmitesdelascapasdebernseleccionarsetomandoencuentalaminimizacin
delflujodeinformacinatravsdelasinterfaces.

5. El nmero de capas deber ser lo suficientemente grande para que funciones


diferentes no tengan que ponerse juntas en la misma capa y, por otra parte,
tambindeberserlosuficientementepequeoparaquesuarquitecturanollegue
aserdifcildemanejar.

Obsrvese que le modelo OSI, por s mismo, no es una arquitectura de red, dado que no
especifica, en forma exacta, los servicios y protocolos que se utilizarn en cada una de las
capas.Sloindicaloquecadacapadeberhacer.

Capas del modelo OSI.

Capa fsica.
La capa fsica se ocupa de la transmisin de bits a lo largo del canal de comunicacin. Los
problemas de diseo a considerar aqu son los aspectos mecnico, elctrico, de
procedimiento de interfaz y el medio de transmisin fsica, que se encuentra bajo la capa
fsica.

Capa de enlace.
La tarea primordial de la capa de enlace consiste en, a partir de un medio de transmisin
comnycorriente,transformarloenunalneasinerroresdetransmisinparalacapadered.
Estatarearequierequeelemisortroceelaentradadedatosentramasdedatos,tpicamente
construidas por algunos cientos de octetos. Las tramas as formadas son transmitidas de
forma secuencial, y requieren de un asentimiento del receptor que confirme su correcta
recepcin.

Capa de red.
La capa de red se ocupa del control de la operacin de la subred. Un punto de suma
importanciaensudiseo,esladeterminacinsobrecmoencaminarlospaquetesdeorigen
a destino. Si en un momento dado hay demasiados paquetes presentes en la subred, ellos
mismos se obstruirn mutuamente y darn lugar a un cuello de botella. El control de tal
congestin depender de la capa de red. Adems, es responsabilidad de la capa de red
resolverproblemasdeinterconexinderedesheterogneas.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 10. SISTEMAS DISTRIBUIDOS: REDES 319

Capa de transporte.
La funcin principal de la capa de transporte consiste en aceptar los datos de la capa de
sesin,dividirlos,siemprequeseanecesarioenunidadesmspequeas,pasarlosalacapade
red, y asegurar que todos ellos lleguen correctamente al otro extremo. Adems, todo este
trabajo se debe hacer de manera eficiente, de tal forma que asle la capa de sesin de los
cambiosinevitablesalosqueestsujetalatecnologadelhardware.

Es una capa de tipo origendestino, o extremo a extremo. Es decir, un programa en la


mquina origen lleva una conversacin con un el correspondiente programa par, que se
encuentraenlamquinadestino,utilizandoparaellolascorrespondientescabecerasdelos
mensajes de control. Los protocolos de las capas inferiores se llevan a cabo entre cada
mquina y su vecino inmediato, y no entre las mquinas de origen y destino, que podran
estar separadas grandes distancias. Antes de multiplexar varios flujos de mensajes en un
canal,lacapadetransportedebeocuparsedelestablecimientoyliberacindeconexionesa
travsdelared.

Capa de sesin.
La capa de sesin permite que los usuarios de diferentes mquinas puedan establecer
sesiones entre ellos. A travs de una sesin se puede llevar a cabo un transporte de datos
ordinario, tal y como lo hace la capa de transporte, pero mejorando los servicios que sta
proporcionayqueseutilizanenalgunasaplicaciones.

Uno de los servicios de la capa de sesin consiste en gestionar el control de dilogo. Las
sesionespermitenqueeltrficovayaenambasdireccionesalmismotiempo,obien,enuna
sola direccin en un instante dado. Otros servicios relacionados con esta capa son la
administracindeltestigoylasincronizacin.

Capa de presentacin.
A diferencia de las capas inferiores, que nicamente estn interesadas en el movimiento
fiabledebitsdeunlugaraotro,lacapadepresentacinseocupadelosaspectosdesintaxisy
semnticadelainformacinquesetransmite.

Lacapadepresentacinesttambinrelacionadaconotrosaspectosderepresentacindela
informacin. Por ejemplo, la compresin de datos se puede utilizar aqu para reducir el
320 PROGRAMACIN C++ Y COMUNICACIONES.

nmerodebitsquetienenquetransmitirse,yelconceptodecriptografasenecesitautilizara
menudoporrazonesdeprivacidadydeautentificacin.

Capa de aplicacin.
Lacapadeaplicacincontieneunavariedaddeprotocolosquesenecesitanfrecuentemente.
Porejemplo,haycentenaresdetiposdeterminalesincompatiblesenelmundo.Unaformade
resolveresteproblemaconsisteendefinirunterminalvirtualderedabstracto.

Otra funcin de la capa de aplicacin es la transferencia de archivos. Distintos sistemas de


archivos tienen diferentes convenciones para denominar un archivo, as como diferentes
formas para representar las lneas de texto, etc. La transferencia de archivos entre dos
sistemasdiferentesrequieredelaresolucindestasydeotrasincompatibilidades.

Transmisin de datos en el modelo OSI.


Enlafigura3.3,semuestraunejemplodecmopuedentransmitirselosdatosmedianteel
empleodelmodeloOSI.Elprocesoemisortienealgunosdatosqueenviaralprocesoreceptor.
Este entrega los datos a la capa de aplicacin, la cual aade entonces la cabecera de
aplicacin(AH,applicationheader),lacualpuedesernulayentregaelelementoresultante
alacapadepresentacin.

Lacapadepresentacintransformaesteelementodediferentesformas,conlaposibilidadde
introducir una cabecera en la parte frontal, dando el resultado a la capa de sesin. Es
importanteobservarquelacapadepresentacindesconocequpartedelosdatosqueledio
lacapadeaplicacin,correspondeaAH,yculessonlosquecorrespondenalosverdaderos
datosdelusuario.

Esteprocesosesiguerepitiendohastaquelosdatosalcanzanlacapafsica,lugarendonde
efectivamentesetransmitendatosalamquinareceptora.Laideafundamental,alolargode
esteproceso,esquesibienlatransmisinefectivadedatosesvertical,comosemuestraen
lafigura3.3,cadaunadelascapasestprogramadacomosifueraunatransmisinhorizontal.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 10. SISTEMAS DISTRIBUIDOS: REDES 321

Figura 3. 3 Ejemplo de utilizacin del modelo OSI de ISO


322 PROGRAMACIN C++ Y COMUNICACIONES.

Terminologa y servicios del modelo OSI


Sellamanentidadesaloselementosactivosqueseencuentranencadaunadelascapas.Las
entidades pueden ser software, como un proceso; o hardware, como el procesamiento
realizado un chip inteligente de E/S. Las entidades de la misma capa, pero de diferentes
mquinas, se conocen como entidades pares o iguales. A las entidades de la capa 7 se les
conocecomoentidadesdeaplicacin;alasdelacapa6comoentidadesdepresentacin,etc.

LasentidadesdelacapaNdesarrollanunservicioqueutilizalacapa(N+1),enestecasoala
capaNseledenominaproveedordelservicioyalacapa(N+1)usuariodelservicio.LacapaN
puedeutilizarserviciosdelacapa(N1)conobjetodeproporcionarsuservicio.

Los servicios se encuentran disponibles en el correspondiente Punto de Acceso al Servicio


(SAP, Service Access Point). Los SAP de la capa N son los lugares en donde la capa (N+1)
puedeaccederalosserviciosqueseofrecen.CadaunodelosSAPtieneunadireccinquelo
identificadeformaparticular.

Para que se lleve a cabo el intercambio de informacin entre dos capas, deber existir un
acuerdosobreunconjuntodereglasacercadelainterfaz.Enunainterfaztpica,laentidadde
lacapa(N+1)pasaunaUnidaddeDatosdelaInterfaz(IDU,InterfaceDataUnit)alaentidad
delacapaN,atravsdelcorrespondienteSAP.

El IDU consiste en una Unidad de Datos del Servicio (SDU, Service Data Unit) y de alguna
informacindecontrol.LaSDUeslainformacinquesepasa,atravsdelared,alaentidad
paryposteriormente,alacapa(N+1).Lainformacindecontrolesnecesariaporqueayudaa
quelascapasinferioresrealicensutrabajo;porejemplo,elnmerodebytesenelSDU,que
noformapartedelosdatos.

ParahacerlatransferenciadeunaSDU,podrsernecesariosufragmentacinporpartedela
entidaddelacapaNenvariaspartes,detalformaqueacadaunadeellasseleasigneuna
cabecerayseenvecomounadistintaUnidaddeDatosdelProtocolo(PDU,ProtocolData
Unit).LasentidadesparesutilizanlascabecerasdelaPDUparallevaracabosuprotocolode
igualaigual.PormediodeellosseidentificaculessonlasPDUquecontienendatosycules
lasquellevaninformacindecontrol.

Con frecuencia a las PDU de transporte, sesin y aplicacin se les conoce como Unidad de
DatosdelProtocolodeTransporte(TPDU,TransportProtocolDataUnit),UnidaddeDatos
delProtocolodeSesin(SPDU,ServiceProtocolDataUnit)yUnidaddeDatosdelProtocolo
deAplicacin(APDU,ApplicationProtocolDataUnit),respectivamente.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 10. SISTEMAS DISTRIBUIDOS: REDES 323

Servicios orientados a conexin y sin conexin.

Las capas pueden ofrecer dos tipos diferentes de servicios a las capas que se encuentran
sobreellas;unoorientadoaconexinyotrosinconexin.

El servicio orientado a la conexin:


Semodelbasndoseenelsistematelefnico.Parahablarconalguienportelfono,sedebe
tomareltelfono,marcarelnmero,hablarycolgar.Similarmente,parautilizarunaredcon
servicio orientado a conexin, el usuario del servicio establece primero una conexin, la
utilizaydespusterminalaconexin.

El aspecto fundamental de la conexin es que acta de forma parecida a un tubo: el que


enva,introduceobjetosporunextremo,yelreceptorlosrecoge,enelmismoorden,porel
otroextremo.

El servicio sin conexin:


Se modela con base en el sistema postal. Cada mensaje, o carta, lleva consigo la direccin
completadeldestinoycadaunodeellosseencamina,enformaindependiente,atravsdel
sistema.

Relacin entre servicios y protocolos

Losconceptosdeservicioyprotocolotienenunsignificadodiferente,ysoncomplementarios
entres,ladefinicindeservicioyprotocolosegnlaterminologaOSIeslasiguiente:

Un servicio es un conjunto de primitivas, u operaciones, que una capa proporciona a la


superior.Elserviciodefinelasoperacionesquelacapaefectuarenbeneficiodelosusuarios,
peronodicenadaconrespectoacmoserealizandichasoperaciones.Unservicioserefierea
una interfaz entre dos capas, siendo la capa inferior la que provee el servicio y la capa
superiorlaqueutilizaelservicio.

Unprotocolo,adiferenciadelconceptodeservicio,esunconjuntodereglasquegobiernanel
formatoyelsignificadodelastramas,paquetesomensajesquesonintercambiadosporlas
entidadescorresponsalesdentrodeunacapa.Lasentidadesutilizanprotocolospararealizar
324 PROGRAMACIN C++ Y COMUNICACIONES.

susdefinicionesdeservicio,teniendolibertadparacambiardeprotocolo,peroasegurndose
denomodificarelserviciovisiblealosusuarios.

Normalizacin de redes

Enlosprimerostiemposenqueaparecielconceptoderedes,cadacompaafabricantede
ordenadorestenasuspropiosprotocolos;porejemplo,IBMtenamsdeunadocena.Esto
daba como resultado que aquellos usuarios que adquiran ordenadores de diferentes
compaas,nopodanconectarlosyestablecerunasolaredconellos.Elcaosgeneradopor
esta incompatibilidad dio lugar a la exigencia de los usuarios para que se estableciera una
normalizacinalrespecto.

Esta normalizacin no solamente iba a facilitar la comunicacin entre ordenadores


construidospordiferentescompaas,sinotambintraeracomobeneficio,elincrementoen
el mercado para los productos que se plegaran a dicha norma, que conducira a una
produccinmasiva,unaeconomadeescalaporincrementodelaproduccin,ascomootro
tipodebeneficioscuyatendenciaseradisminuirsuprecioyalentarsuposterioraceptacin.

Lasnormassedividenendoscategorasquepuedendefinirsecomo:defactoydejure.Las
normas De Facto (derivado del latn, que significa "del hecho"), son aquellas que se han
establecidosinningnplanteamientoformal.LasnormasIBMPCysussucesorassonnormas
de facto para ordenadores pequeos de oficina, porque docenas de fabricantes decidieron
copiar fielmente las mquinas que IBM sac al mercado. En contraste, las normas De Jure
(derivadodellatn,quesignifica"porley"),sonnormasformales,legales,adoptadasporun
organismo que se encarga de su normalizacin. Las autoridades internacionales encargadas
delanormalizacinsedividen,porlogeneral,endosclases:laestablecidaporconvenioentre
gobiernosnacionales,ylaestablecidasinuntratadoentreorganizacionesvoluntariamente.

Las normas internacionales son producidas por la ISO (Organizacin Internacional de


Normalizacin), que es una organizacin voluntaria, fuera de tratados y fundada en 1946,
cuyos miembros son las organizaciones nacionales de normalizacin correspondientes a los
89 pases miembros. Entre sus miembros se incluyen a la ANSI (Estados Unidos), UNE
(Espaa),BSI(GranBretaa),AFNOR(Francia),DIN(Alemania)yotros85organismos.

LaISOconstadeaproximadamente200comitstcnicos(TC),cuyoordendenumeracinse
basa en el momento de su creacin, ocupndose cada uno de ellos de un tema especfico.
CadaunodelosTCtienesubcomits(SC),loscualesasuvezsedividenengruposdetrabajo
(WG).

Otro participante importante en el mundo de las normas es el IEEE (Instituto de Ingenieros


Elctricos y Electrnicos), que es la organizacin profesional ms grande del mundo. Esta

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 10. SISTEMAS DISTRIBUIDOS: REDES 325

institucin,ademsdepublicarnumerosasrevistasyprogramarunnmeromuyimportante
deconferenciasanuales,haestablecidoungrupodedicadoaldesarrollodenormasenelrea
delaingenieraelctricaycomputacin.

Ejemplos de redes
Actualmenteseencuentrafuncionandounnmeromuygrandederedesentodoelmundo.
Algunas de ellas son redes pblicas operadas por proveedores de servicios portadores
comunesoPTT,otrasestndedicadasalainvestigacin,tambinhayredesencooperativa
operadasporlosmismosusuariosyredesdetipocomercialocorporativo.Lasredes,porlo
general,secaracterizanporlospuntoscitadosacontinuacin:

La historia y la administracin pueden variar desde una red cuidadosamente elaborada


por una sola organizacin, con un objetivo muy bien definido, hasta una coleccin
especfica de mquinas, cuya conexin se fue realizando con el paso del tiempo, sin
ningnplanmaestrooadministracincentralquelasupervisara.

Losserviciosofrecidos,quepuedenvariardesdeunacomunicacinarbitrariadeproceso
a proceso, hasta el desarrollo de un sistema de correo electrnico, transferencia de
archivosoaccesoremoto.

Los diseos tcnicos se diferencian segn el medio de transmisin empleado, los


algoritmosdeencaminamientoydenominacinutilizados,elnmeroycontenidodelas
capaspresentesylosprotocolosusados.

Porltimo,lascomunidadesdeusuarios,quepuedenvariardesdeunasolacorporacin,
hasta aquella que incluye todos los ordenadores cientficos que se encuentran en el
mundoindustrializado.

Algunos ejemplos de redes son:

Redes pblicas: Las empresas privadas, y los gobiernos de varios pases han
comenzado a ofrecer servicios de redes a cualquier organizacin que desee
subscribirse a ellas. La subred es propiedad de la compaa operadora de redes y
proporcionaunserviciodecomunicacinparalosclientesyterminales.Aunquelas
redespblicas,endiferentespases,sonengeneral,muydiferentesencuantoasu
estructura interna, todas ellas utilizan el modelo OSI y las normas CCITT o los
protocolosOSIparatodaslascapas.

ARPANET es la Red de la Agencia de Proyectos de Investigacin Avanzada, cuyo


origen est en la red ARPA. Esta red es propiedad de la Agencia de Proyectos de
326 PROGRAMACIN C++ Y COMUNICACIONES.

Investigacin Avanzada de la Defensa, que pertenece al Departamento de Defensa


deEstadosUnidos.Granpartedelconocimientoactualsobreredesdeordenadores
sedebedirectamentealresultadodelproyectoARPANET.

CSENETrealmente,CSNETnoesunaredrealcomoARPANET,sinomsbienesuna
metared que utiliza los servicios de transmisin brindados por otras redes y aade
una capa protocolo uniformadora en la parte superior, para hacer que todo ello
parezcacomounasolaredlgicaparalosusuarios.

BITNETseinicienelao1981poriniciativadelaUniversidaddeNuevaYorkydela
UniversidaddeYale.Laideaporlaquesemontestaredfuelacreacindeunared
universitaria,parecidaaCSNET,queincluyeratodoslosDepartamentosdelamisma.
Estaseextendienalrededorde150localidadesdeEstadosUnidosyentre260de
Europa,atravsdesuequivalentedenominadaEARN,denominadaRedEuropeade
InvestigacinAcadmica(REIA).

USENET esta red fue desarrollada en las Universidades de Duke y North Carolina,
ofreceunserviciodereddenoticiasparalossistemasUNIX.Lasnoticiasporredse
dividenencientosdegruposdenoticiasconunagrandiversidaddetemas,algunos
de ellos son de carcter tcnico y otros no. Los usuarios de USENET se pueden
subscribiracualquiergrupoquelesinterese.

SNAeslaarquitecturaderedesdeIBM,ysetraduceporArquitecturadeRedesde
Sistemas.ElmodeloOSIseconfigurtomandocomobaselaredSNA,incluyendoel
concepto de estratificacin, el nmero de capas seleccionadas y sus funciones
aproximadas. SNA es una arquitectura de red que permite que los clientes de IBM
construyan sus propias redes privadas, tomando en cuenta a los hosts y la subred.
AunqueesposiblellevaracabounacorrespondenciaaproximadadelascapasSNA
conlascapasdelmodeloOSI,siseobservacondetalle,sepuedeapreciarquelosdos
modelosnotienenunacorrespondenciacompleta,especialmenteenlascapas3,4y
5.

INTERNET:Redderedes.Sehablaextensamentedeellaenelapartadosiguiente.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 10. SISTEMAS DISTRIBUIDOS: REDES 327

10.3. Protocolo TCP/IP

ElprotocoloTCP/IP(TransmissionControlProtocol/InternetProtocol,ProtocolodeControlde
Transmisin/ProtocolodeInternet)proporcionaunsistemaindependientedeintercambiode
datosentreordenadoresyredeslocalesdedistintoorigen,[Comer96],[Orfali98],y[Hahn
94]. Este protocolo ha evolucionado hasta nuestros tiempos a pesar de que han aparecido
otros como el ATM (Asynchronous Transfer Mode, Modo de Transferencia Asncrono), que
handemostradosermspotentesperomenosdifundidos.

Las funciones propias de una red de computadoras pueden ser divididas en las siete capas
propuestas por ISO para su modelo de referencia OSI; sin embargo la implantacin real de
unaarquitecturapuedediferirdeestemodelo.LasarquitecturasbasadasenTCP/IPproponen
cuatro capas en las que las funciones de las capas de sesin y presentacin son
responsabilidaddelacapadeaplicacinylascapasdeenlaceyfsicasonvistascomolacapa
deInterfazalaRed.Portalmotivo,paraTCP/IPsloexistenlascapasInterfazdeRed,lade
Intercomunicacin en Red, la de Transporte y la de Aplicacin. Como puede verse TCP/IP
presuponeindependenciadelmediofsicodecomunicacin,sinembargoexistenestndares
biendefinidosalosnivelesdeenlacededatosyfsicoqueproveenmecanismosdeaccesoa
los diferentesmedios y queen el modeloTCP/IP debenconsiderarse la capa de Interfazde
Red;siendolosmsusualeselproyectoIEEE802,Ethernet,TokenRingyFDI.

LascuatrocapasdelmodeloTCP/IPsedescribenseguidamente:
328 PROGRAMACIN C++ Y COMUNICACIONES.

Capa de Aplicacin. Invoca programas que acceden servicios en la red.


Interactuanconunoomsprotocolosdetransporteparaenviarorecibirdatos,
enformademensajesobienenformadeflujosdebytes.

Capa de Transporte. Provee comunicacin extremo a extremo desde un


programadeaplicacinaotro.Regulaelflujodeinformacin.Puedeproveerun
transporte confiable asegurndose que los datos lleguen sin errores y en la
secuencia correcta. Coordina a mltiples aplicaciones que se encuentren
interactuando con la red simultneamente de tal manera que los datos que
enveunaaplicacinseanrecibidoscorrectamenteporlaaplicacinremota,esto
lo hace aadiendo identificadores de cada una de las aplicaciones. Realiza
adems una verificacin por suma, para asegurar que la informacin no sufri
alteracionesdurantesutransmisin.

Capa Internet. Controla la comunicacin entre un equipo y otro, decide qu


rutas deben seguir los paquetes de informacin para alcanzar su destino.
ConformalospaquetesIPqueserenviadosporlacapainferior.Desencapsula
lospaquetesrecibidospasandoalacapasuperiorlainformacindirigidaauna
aplicacin.

CapadeInterfazdeRed.Emitealmediofsicolosflujosdebitsyrecibelosque
delprovienen.Consisteenlosgestoresdelosdispositivosqueseconectanal
mediodetransmisin.

Para entender el funcionamiento de los protocolos TCP/IP debe tenerse en cuenta la


arquitectura que ellos proponen para comunicar redes. Tal arquitectura ve como iguales a
todaslasredesalasqueseconecta,sintenerencuentaeltamaodeellas,yaseanlocaleso
decoberturaamplia.Seestablecequetodaslasredesqueintercambiarninformacindeben
estar conectadas a un mismo computador o equipo de procesamiento (dotados con
dispositivosdecomunicacin);atalescomputadorasselesdenominacompuertas,pudiendo
recibirotrosnombrescomoenrutadores,routers,opuentes.

Para que en una red dos computadoras puedan comunicarse entre s ellas deben estar
identificadas con precisin Este identificador puede estar definido en niveles bajos
(identificador fsico) o en niveles altos (identificador lgico) de pendiendo del protocolo
utilizado. TCP/IP utiliza un identificador denominado direccin Internet o direccin IP, cuya
longitud es de 32 bites. La direccin IP identifica tanto a la red a la que pertenece una
computadoracomoaellamismadentrodedichared.Enlasiguientetablaseestablecenlos
diferentestiposderedesquesepuedenestablecersegnladireccinIP.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 10. SISTEMAS DISTRIBUIDOS: REDES 329

TeniendoencuentaunadireccinIPpodrasurgirladudadecmoidentificarqupartedela
direccinidentificaalaredyqupartealnodoendichared.Loanteriorseresuelvemediante
ladefinicindelas"ClasesdeDireccionesIP".Paraclarificarloanteriorpuedeversequeuna
redcondireccinclaseAquedaprecisamentedefinidaconelprimeroctetodeladireccin,la
claseBconlosdosprimerosylaCconlostresprimerosoctetos.Losoctetosrestantesdefinen
losnodosenlaredespecfica.

Las subredes tienen una gran importancia en la implantacin de redes. Estas subredes son
redesfsicasdistintasquecompartenunamismadireccinIP.Debenidentificarseunadeotra
usandounamscaradesubred.Lamscaradesubredesdecuatrobytesyparaobtenerel
nmero de subred se realiza un operacin AND lgica entre ella y la direccin IP de algn
equipo.LamscaradesubreddeberserlamismaparatodoslosequiposdelaredIP.

UnodelosinconvenientesdeestasdireccionesIPessucomplicadamemorizacinporparte
delosusuarios.Parasolucionarlo,seadoptunatabladenominadanombrededominioque
traducalasdireccionesIPaunaseriedecdigosmscomprensibles.Estopermitequeuna
direccin IP como 123.89.100.102 puede traducirse mediante la tabla de dominios en
copernico.latoa.upm.e. La primera parte del dominio indica el nombre de la mquina a
quiencorrespondeladireccinIP,enestecasocopernico;acontinuacin,vieneelnombrede
la organizacin a la que pertenece el servidor, que sera el latoa.upm; en tercer lugar, se
encuentra un cdigo que puede referirse al tipo de organizacin a la que pertenece el
sistema,oalpasdondereside.As,existencdigoscomo.gov(organismogubernamental),
.edu (universidades o centros educativos), .com (redes comerciales pertenecientes a
empresas)ocdigosdepasescomo.itparaItalia,.mxparaMxico,o.esparaEspaa.

Conversin de direcciones en la red

El Protocolo de Resolucin de Direcciones ARP (Address Resolution Protocol) permite a un


equipo obtener la direccin fsica de un equipo destino, ubicado en la misma red fsica,
proporcionandosolamenteladireccinIPdestino.
330 PROGRAMACIN C++ Y COMUNICACIONES.

LasdireccionesIPyfsicadelacomputadoraqueconsultaesincluidaencadaemisingeneral
ARP,elequipoquecontestatomaestainformacinyactualizasutabladeconversin.ARPes
unprotocolode bajo nivelque oculta eldireccionamiento de la reden las capas inferiores,
permitiendoasignar,anuestraeleccin,direccionesIPalosequiposenunaredfsica.

Una conversin dinmica de direcciones Internet a direcciones fsicas es la ms adecuada,


debido a que se obtiene la direccin fsica por respuesta directa del nodo que posee la
direccinIPdestino.Unavezqueladireccinfsicaseobtienestaesguardadaenunatabla
temporal para subsecuentes transmisiones, de no ser as podra haber una sobrecarga de
trfico en la red debido a la conversin de direcciones por cada vezque se transmitiera un
paquete.

LaimplementacindelprotocoloARPrequierevariospasosquesedescribenacontinuacin.
Enprimer lugar, la interfaz de red recibeun datagrama IP a enviar a un equipodestino, en
estenivelsecotejalatablatemporaldeconversin,siexisteunalareferenciaadecuadasta
se incorpora al paquete y se enva. Si no existe la referencia un paquete ARP de emisin
general,conladireccinIPdestino,esgeneradoyenviado.Todoslosequiposenlaredfsica
reciben el mensaje general y comparan la direccin IP que contiene con la suya propia,
enviando un paquete de respuesta que contiene su direccin IP. El computador origen
actualizasutablatemporalyenvaelpaqueteIPoriginal,ylossubsecuentes,directamentea
lacomputadoradestino.

El funcionamiento de ARP no es tan simple como parece. Supngase que en una tabla de
conversinexistaunmapeodeunamquinaquehafalladoyselehareemplazadolainterfaz
dered;enestecasolospaquetesquesetransmitanhaciaellaseperdernpueshacambiado
ladireccinfsica,portalmotivolatabladebeeliminarentradasperidicamente.

Protocolo de Internet (IP)

El Protocolo Internet proporciona un servicio de distribucin de paquetes de informacin


orientadoanoconexindemaneranofiable.Laorientacinanoconexinsignificaquelos
paquetes de informacin, que ser emitido a la red, son tratados independientemente,
pudiendo viajar por diferentes trayectorias para llegar a su destino. El trmino no fiable
significa ms que nada que no se garantiza la recepcin del paquete. Las principales
caractersticasdeesteprotocoloson:

Protocoloorientadoanoconexin.

Fragmentapaquetessiesnecesario.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 10. SISTEMAS DISTRIBUIDOS: REDES 331

DireccionamientomediantedireccioneslgicasIPde32bits.

Siunpaquetenoesrecibido,estepermanecerenlaredduranteuntiempo
finito.

Realizael"mejoresfuerzo"paraladistribucindepaquetes.

Tamaomximodelpaquetede65635bytes.

Slo ser realiza verificacin por suma al encabezado del paquete, no a los
datosstequecontiene

La unidad de informacin intercambiada por IP es denominada datagrama. Tomando como


analoga los marcos intercambiados por una red fsica los datagramas contienen un
encabezado y una rea de datos. IP no especifica el contenido del rea de datos, sta ser
utilizadaarbitrariamenteporelprotocolodetransporte.

LaUnidaddeTransferenciaMximadeterminalalongitudmxima,enbytes,quepodrtener
un datagrama para ser transmitida por una red fsica. Obsrvese que este parmetro est
determinado por la arquitectura de la red: para una red Ethernet el valor de la MTU es de
1500 bytes. Dependiendo de la tecnologa de la red los valores de la MTU pueden ir desde
128hastaunoscuantosmilesdebytes.Laarquitecturadeinterconexinderedespropuesta
porTCP/IPindicaquestasdebenserconectadasmedianteunacompuerta.Sinobligaraque
la tecnologa de las redes fsicas que se conecten sea homognea. Por tal motivo si para
interconectar dos redes se utilizan medios con diferente MTU, los datagramas debern ser
fragmentadosparaquepuedansertransmitidos.Unavezquelospaqueteshanalcanzadola
redextremalosdatagramasdebernserreensamblados.

Enrutamiento de paquetes

El enrutamiento es el proceso quedeterminar la trayectoria queundatagramadebe seguir


paraalcanzarsudestino.Alosdispositivosquepuedenelegirlastrayectoriasselesdenomina
enrutadores. En el proceso de enrutamiento intervienen tanto los equipos como las
compuertas que conectan redes. El termino compuerta es impuesto por la arquitectura
TCP/IPdeconexinderedes,sinembargounacompuertapuederealizardiferentesfunciones
adiferentesniveles,unadeesasfuncionespuedeserladeenrutamientoyportantorecibirel
nombredeenrutador.

Existendostiposdeenrutamiento;eldirectoyelindirecto.Debidoaqueenelenrutamiento
directolosdatagramassetransmitedeunequipoaotro,enlamismaredfsica,elprocesoes
muyeficiente.LavinculacinentreladireccinfsicaylaIPserealizamedianteelARP.
332 PROGRAMACIN C++ Y COMUNICACIONES.

En el enrutamiento directo la transmisin de datagramas IP entre dos equipos de la misma


redfsicasinlaintervencindecompuertas.Elemisorencapsulaeldatagramaenlatramade
la red, efectuando la vinculacin entre la direccin fsica y la direccin IP, y enva la trama
resultante en forma directa al destinatario. En el enrutamiento indirecto las compuertas
formanunaestructuracooperativa,interconectada.Lascompuertasseenvanlosdatagramas
hastaquesealcanzaalacompuertaquepuededistrubuirlaenformadirectaalareddestino.

El enrutamiento en IP se basa en la gestin de tablas. Las tablas de enrutamiento estn


presentesentodoequipoquealmaceneinformacindecmoalcanzarposiblesdestinos.En
las tablas no se almacena la ruta especfica a un equipo, sino aquellas a la red donde se
encuentre.CadapuertodecomunicacindelacompuertadebeposeerunadireccinIP.Para
queenlosequiposnoexistaunatablaexcesivamentegrande,quecontengatodaslasrutasa
lasredesqueseinterconectaunequipo,esdegranutilidaddefinirunarutapordefecto.A
travsdeestarutasedebernalcanzartodaslasredesdestino.Larutapordefectoapuntaa
un dispositivo que acta como compuerta de la red donde se encuentre ubicado el equipo
quelaposee.

laarquitecturadeinterconexinderedesdeTCP/IPcadaparderedesseconectanmediante
compuertas.Paraquelospaquetesalcancensusredesdestinolascompuertasdebencontar
con mecanismos mediante los cuales ntercambien la informacin de las redes que conecta
cadauno.

LaarquitecturadeenrutamientoporCompuertaNcleosebasaesdefinirunacompuertaque
centraliza las funciones de enrutamiento entre redes, a esta compuerta se le denomina
ncleo. Cada compuerta en las redes a conectar tiene como compuerta por defecto a la
compuertancleo.Variascompuertas ncleo pueden conectarse paraformar una gran red;
entrelascompuertasncleoseintercambiarinformacinconcernientealasredesquecada
una de ellas alcanzan. La arquitectura centralizada de enrutamiento fue la primera que
existi.Susprincipalesproblemasradicannotantoenlaarquitecturaens,sinoenlaforma
enquesepropagabanlasrutasentrelascompuertasncleo.

Conforme las complejidades de las redes aumentaron se debi buscar un mecanismo que
propagase la informacin de rutas entre las compuertas. Este mecanismo deba ser
automticoestoobligadoporelcambiodinmicodelasredes.Denoseraslastransiciones
entrelascompuertaspodansermuylentasynoreflejarelestadodelaredenunmomento
dado. Para resolver este problema se define el vector de distancia. Se asume que cada
compuerta comienza su operacin con un conjunto de reglas bsicas de cmo alcanzar las
redesqueconecta.Lasrutassonalmacenadasentablasqueindicanlaredylossaltospara
alcanzaresared.Peridicamentecadacompuertaenvaunacopiadelastablasquealcanza
directamente. Cuando una compuerta recibe el comunicado de la otra actualiza su tabla

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 10. SISTEMAS DISTRIBUIDOS: REDES 333

incrementando en uno el nmero de saltos. Este concepto ayud a definir cuantas


compuertasdeberaviajarunpaqueteparaalcanzarsureddestino.Medianteelvectoruna
compuerta puede saber a que otra compuerta enviar el paquete de informacin, sabiendo
que sta podra no ser la ltima compuerta por la que el paquete tendra que viajar. Este
esquemapermite tener varios caminosauna misma red, eligiendo el camino mscorto, es
deciraquellacompuertaqueconmenossaltosconduzcaalareddestino.

Protocolo de Control de Transferencia (TCP)

El Protocolo de Control de Transferencia (TCP) proporciona una comunicacin bidireccional


completamediantecircuitosvirtuales.Desdeelpuntodevistadelusuariolainformacines
transmitidaporflujosdedatos.Lafiabilidadenlatransmisindedatossebasaen:

Asignacindenmerosdesecuenciaalainformacinsegmentada.

Validacionesdelainformacinrecibida.

Reconocimientodepaquetesrecibidos.

Se utiliza el principio de ventana deslizable para esperar reconocimientos y reenviar


informacin.Estemecanismoproporcionaunatransferenciafiabledeflujosdeinformacin.
AunqueestntimamenterelacionadoconIPTCPesunprotocoloindependientedepropsito
general. Al ser un protocolo de alto nivel su funcin es que grandes volmenes de
informacinlleguenasudestinocorrectamente,pudiendorecobrarlaprdidaespordicade
paquetes.

Cadavezqueunpaqueteesenviadoseinicializauncontadordetiempo,alalcanzareltiempo
de expiracin, sin haber recibido el reconocimiento, el paquete se reenva. Al llegar el
reconocimiento el tiempo de expiracin se cancela. A cada paquete que es enviado se le
asignaunnmerodeidentificador,elequipoquelorecibedeberenviarunreconocimiento
334 PROGRAMACIN C++ Y COMUNICACIONES.

de dicho paquete, lo que indicar que fue recibido. Si despus de un tiempo dado el
reconocimiento no ha sido recibido el paquete se volver a enviar. Obsrvese que puede
darseelcasoenelqueelreconocimientoseaelquesepierda,enestecasosereenviarun
paqueterepetido.

Protocolo de Datagramas de Usuario

Este protocolo (UDP) proporciona de mecanismos primordiales para que programas de


aplicacin de se comuniquen con otros en computadoras remotas. Utiliza el concepto de
puertoparapermitirquemltiplesconexionesaccedanaunprogramadeaplicacin.

Proveeunservicionoconfiableorientadoanoconexin.Elprogramadeaplicacintienela
totalresponsabilidaddelcontroldeconfiabilidad,mensajesduplicadosoperdidos,retardosy
paquetes fuera de orden. Este protocolo deja al programa de aplicacin a ser explotado la
responsabilidaddeunatransmisinfiable.Conlpuededarseelcasodequelospaquetesse
pierdan o bien no sean reconstruidos en forma adecuada. Permite un intercambio de
datagramasmsdirectoentreaplicacionesypuedeelegirseparaaquellasquenodemanden
unagrancantidaddedatagramasparaoperarptimamente.

pseudocabeceraIP

cabeceraUDP

MensajeUDP

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 10. SISTEMAS DISTRIBUIDOS: REDES 335
336 PROGRAMACIN C++ Y COMUNICACIONES.

10.4. Orgenes y servicios de Internet.

Origen y evolucin
Para evitar que un ataque nuclear pudiera dejar aisladas a las instituciones militares y
universidades,en1969elARPA(AdvancedResearchProjectsAgency),unaagenciasubsidiaria
del Departamento de Defensa de Estados Unidos, desarroll una red denominada ARPAnet
basadaenelprotocolodeintercambiodepaquetes.

Unprotocolodeintercambiodepaquetesesunsistemaquedividelainformacinenpartesy
lasenvaunaporunaalordenadordedestinoconuncdigodecomprobacin.Sielcdigode
comprobacin no es correcto, se solicita al ordenador de destino que vuelva a enviar los
paquetescorruptos.

La ventaja de este sistema de transmisin es principalmente su fiabilidad de los datos,


independientemente de la calidad de la lnea utilizada. Los datos llegan incluso si no
funcionan, o son destruidos parte de los nodos de la red, factor que influy decisivamente
parasuadopcinporpartedelgobiernonorteamericano.

Otraventajaesqueestetipodesistemaspermitedistribuirmsfcilmentelosdatos,yaque
cada paquete incluye toda la informacin necesaria para llegar a su destino, por lo que
paquetes con distinto objetivo pueden compartir un mismo canal. Adems, es posible
comprimircadapaqueteparaaumentarlacapacidaddetransmisin,oencriptarsucontenido
paraasegurarlaconfidencialidaddelosdatos.Estasvirtudeshanaseguradolasupervivencia
delosprotocolosdesdelasprimeraspruebasrealizadasen1968porelLaboratorioNacional
deFsicadelReinoUnidohastanuestrosdas.

ElprimerprotocoloutilizadoporARPAnetfueeldenominadoNCP(NetworkControlProtocol,
ProtocolodeControldeRed),queseempleenlaredhasta1982.Enesteaoseadoptel
protocolo TCP/IP procedente de los sistemas Unix, que cada vez tenan ms importancia
dentrodeARPAnet.

En 1969 el ARPA instal el primer servidor de informacin en un ordenador Honeywell 516


queincorporabanadamenosque12KBytesdememoria.Prontoseaadiranotrosservidores
porpartedelInstitutodeInvestigacindeStanford,delaUniversidaddeCaliforniaenSanta
Barbara,ydelaUniversidaddeUtahqueformaronlosprimerosnodosdeARPAnet.

Sinembargo,laredInternetcomoredderedesnocomenzafuncionarhastadespusde
la primera conferencia de comunicaciones por ordenador en octubre de 1972. En esta
convencin ARPAnet presentaba una red de 40 nodos y se propuso su conexin con otras
redesinternacionales.RepresentantesdevariospasesformaronaselINWG(InterNetwork

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 10. SISTEMAS DISTRIBUIDOS: REDES 337

WorkingGroup)paraestablecerunprotocolocomnconelARPA,empezandoadarformalo
quehoyendaconocemosporInternet.

Con el tiempo ARPAnet fue sustituida por NSFnet, la red de la fundacin nacional para la
ciencia de EEUU, como organismo coordinador de la red central de Internet. Desde los
primeros pasos de ARPAnet, hasta hoy enda, la red hasufrido pocos cambios, comparado
con los avances de la informtica. Los cambios ms drsticos se han producido en la
infraestructura de la red, aumentando la velocidad de transmisin hasta permitir el
funcionamientodeaplicacionesmultimediaylatransmisindevdeoosonidoentiemporeal.

Tambin han sufrido cambios el tipo de servicios ofrecidos por Internet, ya que si bien las
utilidadesenmodotextohansobrevividohastanuestrosdas,laverdaderaestrelladelaRed
eslaWorldWideWeb,unserviciodeconsultadedocumentoshipertextualesquehalogrado
granpopularidadtantoentreexpertoscomoentreprofanos.

UnodeloscambiosmsespectacularesquehasufridoInterneteseldelnmerodeusuarios.
Desde los primeros tiempos de ARPAnet en los que slo una decena de ordenadores y un
centenar de usuarios tenan acceso a la red, hemos pasado a cifras importantes. Se calcula
que existen unos 4 millones de sistemas conectados actualmente a Internet, facilitando
accesoaunos50millonesdeusuariosentodoelmundo.

Lascifrassonanmssorprendentessiseconsideraqueelcrecimientoactualdelcensode
usuariosdeInternetesaproximadamentedeundiezporcientomensual.Estascifrasindican,
porejemplo,queenelsigloXXIlosusuariosdeInternetpodranalcanzarennmeroalosque
ven televisin actualmente. Esto hace que Internet se est convirtiendo en una realidad de
nuestro tiempo, y puede provocar una pequea revolucin en nuestra forma de vida, del
mismomodoquelohanhecholosordenadores,telfonosmviles,discoscompactos,etc.

Estefenmenohaatradolosinteresesdemuchasempresasdetodoslossectores,queven
enInternetunvehculoidealparaactividadescomerciales,tcnicasodemarketing,adems
deunmediodedistribucindirectadesoftware,yengeneraldeinformacindetodotipo.

Los servicios ms importantes de la Red


HastaahorahemoshabladodeInternetcomosimplemediodecomunicacin,graciasalcual
los ordenadores pueden intercambiar datos mediante un determinado protocolo. Sin
embargo,atravsdeestaslneasdecomunicacinexistenmultituddeserviciosdetodotipo,
algunosdeloscualessedescribenacontinuacin.

CORREO ELECTRNICO
338 PROGRAMACIN C++ Y COMUNICACIONES.

Uno de los primeros servicios que la red ARPAnet incorpor desde sus inicios fue el correo
electrnico. Como el correo normal, su versin electrnica, tambin denominada email,
proporcionaunmedioparaquecualquierusuariodeunaredpuedaenviarmensajesaotras
personas.

Apesardequecadausuariopuedeestarutilizandounordenadorounaaplicacindecorreo
electrnico diferente, e incluso pertenecer a redes de ordenadores no conectadas
directamente a Internet, el protocolo utilizado SMTP (Simple Mail Transfer Protocol,
Protocolo de Transmisin de Mensajes Simples), asegura una absoluta compatibilidad en el
intercambiodemensajes.

En un principio, este servicio se limitaba a poner en contacto a las personas mediante el


intercambiomsomenosrpidodemensajes.Enlaactualidad,esposiblemandartodotipo
dedatosbinariospudiendoseincluirennuestrosmensajestodotipodeimgenes,sonidosy
ficherosbinarios,incluidosprogramaejecutables.

Existen tambin otros servicios que pueden ser utilizados a travs del correo electrnico:
accesoalibrerasdesoftware,consultadeinformacinsobreciertostemas,participacinen
juegosdeestrategia,odiscusinconotrosusuariosenforostemticos.

Lasdireccionesdecorreoelectrnicoestncompuestasporunnombredeusuario,elsmbolo
@ y el nombre completo del dominio del ordenador que estamos utilizando o del
proveedordeaccesoquehemoscontratado.Sielusuarioconelquequeremoscontactarno
seencuentraenunaredunidadirectamenteaInternet,existenunastablasdeconversinque
permitirnanuestrosmensajesllegarasudestinoatravsdelasoportunaspasarelas,que
no son otra cosa que ordenadores que hacen de puente entre dos redes y que permiten
ciertointercambiodeinformacinentreellas.

Si se dispone de un acceso a Internet se puede contar con una direccin propia de correo
electrnicoyunespacio,denominadobuzn,eneldiscodelordenadorquefuncionacomo
servidordecorreo.Enesteespacioseirnalmacenandolosmensajesdecorreoelectrnico
que vayan llegando con nuestra direccin para que, cuando nos conectemos, podamos
comprobarsitenemoscorreonuevoyaccederal.Enmuchoscasoseltamaodeestebuzn
ser limitado. Al enviar o recibir un mensaje de correo electrnico debe tenerse en cuenta
que su viaje por Internet va a ser ms lento que con otro tipo de servicios, ya que tiene
asignadounanchodebandamenorqueeldeotrosdeaccesodirecto.

Desde su creacin el correo electrnico es sin duda el servicio ms utilizado dentro de


Internet.Millonesdepersonasdetodoelmundoenvansusmensajes,incluyendoenalgunos
casosimgenesdigitalesymsica.Porotrolado,estemedioestdesplazandoenimportancia
al Fax en muchos ambientes empresariales, ya que ofrece grandes ventajas de costes y

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 10. SISTEMAS DISTRIBUIDOS: REDES 339

calidad adems de una gran flexibilidad, a pesar del inconveniente de su escasa rapidez de
transmisin.

TELNET

ElprogramaTelnetpermiteaccedermedianteunterminalvirtualaunamquinaconectadaa
Internet,siemprequeseconozcasudireccinIP,onombrededominio,ysedispongadeun
nombre de usuario y la correspondiente clave de acceso. Segn sea el sistema al que se
accede, se tendr que utilizar un tipo de terminal distinto. Los ms habituales son el vt100
paramquinasUnixoVAXyelANSIparaPCs.

UnaimagendelprogramaTELNETsobreWindowssepuedeobservarenlafigura3.5.Parala
conexinconlaotramquinadeberemosintroducirelNombredehostosudireccinIP,el
PuertoporelqueserealizarlaconexinyelTipodeterminal.

Figura 10. 4 Interfaz para Telnet, o conexin remota

Adems de acceder a cuentas privadas en ordenadores remotos, es posible introducirse en


servicios gratuitos o en programas de bsqueda como el Archie. Este tipo de servicios
medianteTelnethaperdidomuchapopularidadenlosltimosaos,yaqueotrosprogramas
como los navegadores de World Wide Web ofrecen acceso a informacin con todo lujo de
340 PROGRAMACIN C++ Y COMUNICACIONES.

grficos y con posibilidad de usar el ratn, mientras que el Telnet slo puede funcionar en
modotexto.Sinembargo,ansonmuchoslosserviciosqueseofrecenmedianteTelnetpara
losnostlgicosdelosterminalesdetexto,yentodocasosuutilidadcomoherramientapara
trabajardesdecasasiguesiendoimportante.

FTP

EsteesotrodelosserviciosmspopularesdentrodeInternetysiguesiendounodelosms
tilesalahoradetransmitirorecibirficherosdecualquiertipo.ElFTP(FileTransferProtocol,
Protocolo de Transferencia de Ficheros). Es un programa que funciona con el protocolo
TCP/IP y que permite acceder a un servidor de este sistema de intercambio para recibir o
transmitirarchivosdetodotipo.

Ademsdeconocerladireccindelamquinadelaquesequiereextraerficheros,tambin
esnecesarioasegurarsedequeeneseordenadorestfuncionandounprogramademonio
oservidordeFTP.Enelcasodequeexista,tendremosqueconocerunnombredeusuarioy
unaclavedeaccesovlidos,amenosqueelservidorpermitaefectuarFTPannimos.

ExistenmultituddesistemasalolargodelareddedicadosaofrecerserviciodeFTPannimo,
poniendo a disposicin ficheros de todo tipo. Muchas empresas como Creative Labs, IBM o
Microsoftutilizanestemtodoparaofreceralosusuarioslasltimasversionesdelosdrivers
outilidadesdisponiblesparasusproductos.

Tambin existen servidores dedicados exclusivamente a recoger todo tipo de software con
licenciasharewareyfreewareparacualquiersistemaoperativo.Adems,dentrodeInternet
encontramos servidores dedicados a recoger documentos como las famosas FAQ
(FrequentlyAskedQuestions,Preguntasyrespuestashabituales),quetienenrespuestaalas
preguntasmsfrecuentesrealizadasporlosusuariosdeInternetdentrodelserviciodeNews,
olosdocumentosFYI(ForYourInformation,Informacinparausted),coninformacinde
todotiposobrelaRed.

AunqueyahanpasadomuchosaosdesdelaprimeraimplementacindelFTP,esteservicio
siguesiendoelmtododetransportededatosporexcelenciaenInternet.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 10. SISTEMAS DISTRIBUIDOS: REDES 341

Figura 10. 5 Comandos de FTP

WWW: (World Wide Web, Extensa Telaraa Mundial)

LaWWWesunareddeservidoresdentrodeInternetqueofrecepginashipertextualesenun
formato denominado HTML (HyperText Markup Language, Lenguaje de Marcas de
Hipertexto).Esunlenguajededefinicindepginasconextensioneshipertextualesportable
a cualquier tipo de plataforma grfica. Estas pginas contienen, adems de texto en varios
formatos, imgenes, sonidos o vdeo, y permiten lanzar la lectura de pginas de otros
servidoresactivandociertaspalabrasresaltadasdentrodelmismodocumento.

En otras palabras, al consultar un documento de WWW se encontrarn algunas palabras o


direccionesresaltadasoenotrocolor.Alactivarestaspalabrasmedianteelratnpasaremos
aotrapginaquepuedeperteneceralmismoservidoroacualquierotramquinadentrode
Internet,opuedeactivarcualquierotroserviciodeInternetcomolaconsultadeungrupode
NewsolatransmisinorecepcindeficherosmedianteFTP.

Tanto las pginas Web como otros servicios de Internet tienen asignada su propia URL
(Uniform Resource Locator, Cdigo Uniforme de Recursos). Se trata de un cdigo que
342 PROGRAMACIN C++ Y COMUNICACIONES.

contienelaidentificacindelservicio,ladireccindelservidorysiesnecesarioeldirectorio
dondeseencuentranlosficherosnecesariosdentrodelsistemaremoto.

As,unaURLdelaformahttp://www.mec.esindicaquequeremosconsultarunapginade
WorldWideWebenformatohttp(HyperTextTransferProtocol,ProtocolodeTransferencia
de Hipertexto). En el servidor de direccin de dominio completa www.mec.es. Si
quisiramosrealizarunFTP,laURLseraporejemploftp://ftp.microsoft.com/pub,donde
ftp.microsoft.com es la direccin del servidor y /pub es el directorio donde se
encuentranlosficherosquenosinteresan.

Los documentos de hipertexto no son propios de Internet, sino que se encuentran en


numerosasaplicacionesinformticas.Unejemplodesuutilizacinsonlasayudasdelpropio
SistemaOperativoWindows;queincorporan,enelpropiotexto,enlacesaotraspginasde
ayudaparaaclararciertosconceptos.

El lenguaje HTML
NavegarporInternetmedianteunprogramaclientedeWorldWideWebseconvierteenuna
tareasumamentesencillayagradable,aprovechandotodaslasposibilidadesdelaRed.Esta
sensacin ha sido aumentada considerablemente gracias a empresas como Netscape, que
han desarrollado programas cliente realmente amistosos con el usuario y de muy sencillo
manejo,incorporandomultituddeutilidadesparafacilitarlaexploracindelaRed.

Todas estas virtudes son posibles gracias al lenguaje HTML propuesto por vez primera, en
marzo del ao 1989, en los laboratorios de investigacin de fsica de partculas de Suiza, el
CERN. Esta institucin encarg a uno de sus departamentos el desarrollo de un sistema de
lecturadedocumentosquefacilitaraladivulgacincientfica,[Alvarez97],[Musciano98]

Nofuesinohastaelao1990,cuandoelproyectodeestaprestigiosainstitucin,recibiel
nombredefinitivodeWorldWideWeb.Afinalesdeesemismoaoempezaronafuncionar
lasprimerasversionesdelsistemaenplataformasNeXT.Apartirdelapresentacindeeste
prototipo en determinadas convenciones y especialmente en un seminario que ofreci el
propioCERN,enjuniode1991,muchasinstitucionesseinteresaronporelproyecto.

En 1992 ya se encontraba disponible elprimer clientede WorldWideWeby sudifusin se


realizabamedianteFTPannimo,distribuyndoserpidamenteyganandociertapopularidad
enelentornodeInternet.

En1994,aodelaprimeraconferenciainternacionaldeWorldWideWeb,yaseencontraban
registrados oficialmente unos 1.500 servidores de este sistema. En la actualidad se calcula

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 10. SISTEMAS DISTRIBUIDOS: REDES 343

quelosservidoresdeestetipopuedenllegaraservariasdecenasdemiles,aunqueelclculo
probablementesequedecortodadaladificultaddelrecuentoporelrpidocrecimientodel
nmerodeellos.

Desde que el CERN sacara a la luz su primera especificacin, el lenguaje HTML fue
adquiriendo cada vez ms posibilidades, incorporando capacidades multimedia y ms
recientementelaposibilidaddecrearpginasentresdimensiones.Casisindarsecuentalos
responsables del CERN haban creado uno de los fenmenos de mayor repercusin en
Internetalolargodesuhistoria.

Actualmente el lenguaje HTML ha llegado ya a su versin 4, estando la versin 5 en


implantacin.Enlaversin4lasespecificacionesabarcabanyamuchasmsposibilidadesque
las propuestas originales. Esta versin fue diseada para superar ciertas limitaciones de
desarrollosanteriores,admitiendoverdaderastablasysolucionandociertosproblemasconla
alineacinyjustificacindetextoreseadasenanterioresversiones.Enestanuevadefinicin
tambin es posible introducir objetos multimedia con distintos formatos. Adems, permite
incluir applets, que son pequeos mdulos ejecutables, como los de Java, o los COM
(Component Object Model, Modelo de Objetos de Componentes) desarrollados por
Microsoft,yquepermitenaadirenlacesocontrolesOLE.

Gracias a estas facilidades proporcionadas por el lenguaje muchas otras empresas han
empezadoadesarrollarmultituddeappletscondistintasfunciones.Unappletesunpequeo
programaejecutablequeenvaelservidoralprogramaclienteparaquefuncioneincorporado
alapgina.
344 PROGRAMACIN C++ Y COMUNICACIONES.

Figura 10. 6 Ejemplo de un applet que simula una calculadora

De esta manera, aunque el lector de pginas no incorpore ciertas funciones, stas pueden
aadirsedesdeelservidorparaquepuedaleer,porejemplo,diversosformatosmultimedia
sinincorporarenelmismoprogramaellectorparadichosdocumentos.

Aplicaciones externas

Ademsdelosapplets,muchasempresasydesarrolladoresindependienteshandesarrollado
aplicaciones externas que proporcionan a los navegadores ms posibilidades. Mediante
ciertasaplicacionessepuedeescucharsonidoenvivoovertelevisinatravsdeunapgina
deWeb.

Entre las aplicaciones accesorias que han sido desarrolladas ltimamente encontramos
aquellas que permiten hablar y recibir sonido a travs de Internet. Estos programas
convierten nuestro ordenador en un verdadero telfono digital de cobertura mundial con
funcionesinteresantesyunahorroconsiderableenllamadasinternacionales.

La ventaja de los applets frente a este tipo de aadidos es que se cargan mientras se est
consultandolapginayluegosonborradosdeldiscolocal.Adems,sielpropioservidoresel

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 10. SISTEMAS DISTRIBUIDOS: REDES 345

queproporcionalaaplicacinparareproducirlosficherosquecontiene,lacompatibilidadde
mediosestasegurada.

Para sacar el mximo partido a la navegacin por la World Wide Web es aconsejable
conseguir un navegador de 32 bits que pueda funcionar en cualquiera de los sistemas
operativos de la actualidad que admitan multitarea. De esta manera podemos esperar la
cargadeunapginadeWeb,mientrasnosocupamosdeotrascosas,einclusoutilizaralavez
otroservicioInternetparanodesperdiciarelanchodebandadelacomunicacin.

Algunos de los navegadores, como es el caso de la ltima versin del Netscape Navigator,
incorporanherramientasparaelusodeotrosserviciosdeInternetcomocorreoelectrnicoo
News,facilitandolainteraccinconlaRed.

Ademsdelasfuncionesdelospropiosnavegadores,hayquetenerencuentalasmltiples
utilidades que ofrecen los servidores de WWW. Las ms tiles y populares son las
herramientas de bsqueda por la Red, que mediante determinados criterios y consultando
unabasededatosdedireccionesdepginasmsomenosextensanosofrecenunalistade
direccionesquecumplenconloscriteriosquehemosespecificado.

Navegadores.
DesdequedierasusprimerospasosenellaboratoriosuizodefsicanucleardelCERNallpor
elao1989,laWorldWideWebhaexperimentadounespectacularaumento,tantoenoferta
de servidores,como ennmero de usuarios, convirtindose sin lugar adudas en el servicio
mspopulardentrodeInternet,sobretodoporlafacilidaddeaccesoalosrecursosdelared.

LaWorldWideWeb,porsupropiaestructura,tienelavirtuddeconvertirlaexploracinde
Internet en una tarea sencilla y agradable, ya que ofrece la posibilidad de acceder a gran
cantidaddeinformacindeunamaneraintuitivamedianteunsistemadeconsultabasadoen
unentornogrfico.Sinembargo,esteconjuntodeposibilidadesslosonaccesiblesatravs
del programa adecuado, se precisa de un navegador, o programa cliente que sea capaz de
interpretarellenguajededescripcindepginaqueutilizalaWWW.

Casi todas estas aplicaciones son de libre distribucin para la mayora de las plataformas,
utilizando entornos grficos tan extendidos como XWindow y Windows. La utilizacin del
346 PROGRAMACIN C++ Y COMUNICACIONES.

entorno grfico permite sacar el mximo partido de las posibilidades hipertextuales de la


WWW,ofreciendofuncionesquefacilitanelaccesoalosrecursosdeInternet.

Los programas clientes de WWW, o navegadores, empezaron a desarrollarse en los


laboratoriosdeprogramacindelNCSA(NationalCentreforSupercomputingApplications,
Centro Nacional para Aplicaciones de Supercomputacin). Desde los primeros aos, se ha
mantenido en la vanguardia de los diseadores de este tipo de aplicaciones. En estos
laboratoriossecomenzadarformalaprimerainterfazparalaconsultadepginasdeWorld
Wide Web, que en el ao 1993 recibi el nombre de Mosaic. A partir del lanzamiento del
primerMosaic,otrascompaascomoNetscapeempezaronadesarrollarsuspropiosclientes
Web,ofreciendosolucionesparticularesypropuestasparamejorarelsistemadeconsultade
pginasWebyoptimizaraslasprestacionesdelservicio.

Dehecho,existeunagrandiferenciaentreexplorarlaredconunbuenprogramaclientede
WWWqueabarquetodaslasposibilidadesdellenguajededescripcinHTMLyqueaadasus
propiasutilidades,arealizarestamismaoperacinconunprogramademenorsofisticacin
tcnicaquepuederecortarsensiblementelasposibilidadesdelsistema.

UPM-EUITI-2015. Miguel Hernando.


11. Comunicacin por Sockets

Como se ha visto en el captulo anterior, para que varios ordenadores se comuniquen entre s, es
claro que deben estar de acuerdo en cmo transmitirse informacin, de forma que cualquiera de
ellos pueda entender lo que estn transmitiendo los otros, de la misma forma que nosotros nos
ponemos de acuerdo para hablar en ingls cuando uno es italiano, el otro francs, el otro espaol y
el otro alemn.

Al "idioma" que utilizan los ordenadores para comunicarse cuando estn en red se le
denomina protocolo. Como se ha visto, hay muchos protocolos de comunicacin, entre los cuales el
ms extendido es el TCP/IP porque entre otras cosas es el que se utiliza en Internet.

De hecho, tanto en Linux/Unix como en Windows contamos con serie de libreras que nos permiten
enviar y recibir datos de otros programas, en C/C++ o en otros lenguajes de programacin, que
estn corriendo en otros ordenadores de la misma red.

En este captulo se presenta una introduccin a los sistemas distribuidos, los servicios
proporcionados en POSIX para el manejo de Sockets, que son los conectores necesarios (el recurso
software) para la comunicacin por la red, y su uso en nuestra aplicacin. No pretende ser una gua

Departamento de Electrnica Automtica e Informtica Industrial


348 PROGRAMACIN C++ Y COMUNICACIONES.

exhaustiva de dichos servicios sino una descripcin prctica del uso ms sencillo de los mismos, y
como integrarlos en nuestra aplicacin para conseguir nuestros objetivos. De hecho, en el curso del
captulo se desarrolla una clase C++ que encapsula los servicios de Sockets, permitiendo al usuario
un uso muy sencillo de los mismos que puede valer para numerosas aplicaciones, aunque
obviamente no para todo.

11.1. LOS SOCKETS


Una forma de conseguir que dos programas se transmitan datos, basada en el
protocoloTCP/IP, es la programacin desockets. Unsocketno es ms que un "canal de
comunicacin"entredosprogramasquecorrensobreordenadores distintosoinclusoenel
mismoordenador.

Desdeelpuntodevistadeprogramacin,unsocketnoesmsqueun"fichero"queseabre
de una manera especial. Una vez abierto se pueden escribir y leer datos de l con las
habitualesfuncionesderead()ywrite()dellenguajeC.Hablaremosdetodoestocondetalle
msadelante.

Existen bsicamente dos tipos de "canales de comunicacin" osockets, losorientados a


conexinylosnoorientadosaconexin.

Enelprimercasoambosprogramasdebenconectarseentreellosconunsocketyhastaque
no est establecida correctamente la conexin, ninguno de los dos puede transmitir datos.
Esta es la parteTCPdelprotocoloTCP/IP, y garantizaque todos losdatos van a llegar deun
programaalotrocorrectamente.Seutilizacuandolainformacinatransmitiresimportante,
no se puede perder ningn dato y no importa que los programas se queden "bloqueados"
esperandoo transmitiendodatos. Si unode los programas est atareado en otracosa yno
atiende la comunicacin, el otro quedar bloqueado hasta que el primero lea o escriba los
datos.

En el segundo caso, no es necesario que los programas se conecten. Cualquiera de ellos


puedetransmitirdatosencualquiermomento,independientementedequeelotroprograma
est"escuchando"ono.EselllamadoprotocoloUDP,ygarantizaquelosdatosquelleguen
soncorrectos,peronogarantizaquelleguentodos.Seutilizacuandoesmuyimportanteque
el programa no se quede bloqueado y no importa que se pierdan datos. Imaginemos, por
ejemplo, un programa que est controlando la temperatura de un horno y enva dicha
temperaturaaunordenadorenunasaladecontrolparaquestepresenteunosgrficosde
temperatura.Obviamenteesmsimportanteelcontroldelhornoqueelperfectorefrescode
los grficos. El programa no se puede quedar bloqueado sin atender al horno simplemente
porqueelordenadorquemuestralosgrficosestocupadoenotracosa.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 11. COMUNICACIN POR SOCKETS 349

11.2. ARQUITECTURA CLIENTE SERVIDOR


A la hora de comunicar dos programas, existen varias posibilidades para establecer la
conexin inicialmente. Una de ellas es la utilizada aqu. Uno de los programas debe estar
arrancadoy en espera de que otro quiera conectarse al. Nunca da "el primer paso" en la
conexin. Al programa que acta de esta forma se le conoce comoservidor. Su nombre se
debeaquenormalmenteeselquetienelainformacinqueseadisponibleyla"sirve"alque
se la pida. Por ejemplo, el servidor de pginas web tiene las pginas web y se las enva al
navegadorqueselosolcite.

El otro programa es el que da el primer paso. En el momento de arrancarlo o cuando lo


necesite, intenta conectarse al servidor. Este programa se denominacliente. Su nombre se
debeaqueeselquesolicitainformacinalservidor.ElnavegadordeInternetpidelapgina
webalservidordeInternet.

Enesteejemplo,elservidordepginaswebsellamaservidorporqueest(odeberadeestar)
siempre encendido y pendiente de que alguien se conecte a l y le pida una pgina. El
navegadordeInterneteselcliente,puestoquesearrancacuandonosotrosloarrancamosy
solicitaconexinconelservidorcuandonosotrosescribimosenlabarradelnavegador,por
ejemplo,http://www.elai.upm.es.com

En los juegos de red, por ejemplo el Age of Empires, debe haber unservidorque es el que
tiene el escenario del juego y la situacin de todos los jugadores en l. Cuando un nuevo
jugador arranca el juego en su ordenador, se conecta al servidor y le pide el escenario del
juegoparapresentarloenlapantalla.Losmovimientosquerealizaeljugadorsetransmitenal
servidoryesteactualizaescenariosatodoslosjugadores.

Resumiendo,servidores el programa que permanece pasivo a la espera de que alguien


solicite conexin con l, normalmente, para pedirle algn dato.Clientees el programa que
solicitalaconexinpara,normalmente,pedirdatosalservidor.

EL SERVIDOR
ApartirdeestepuntocomenzamosconloqueeslaprogramacinenC/C++delossockets.
Unavezincluidaeinicializadalalibreradesockets(pasoquehayquehacerenWindows,no
asenLinux)enClospasosquedebeseguirunprogramaservidorsonlossiguientes:

Apertura de un socket, mediante la funcin socket(). Esta funcin devuelve un


descriptordeficheronormal,comopuededevolverloopen().Lafuncinsocket()no
haceabsolutamentenada,salvodevolvernosyprepararundescriptordeficheroque
elsistemaposteriormenteasociaraunaconexinenred.
350 PROGRAMACIN C++ Y COMUNICACIONES.

Avisaralsistemaoperativodequehemosabiertounsocketyqueremosqueasocie
nuestroprogramaadichosocket.Seconsiguemediantelafuncinbind().Elsistema
todava no atender a las conexiones de clientes, simplemente anota que cuando
empiece a hacerlo, tendr que avisarnos a nosotros. Es en esta llamada cuando se
debeindicarelnmerodepuertoalquesequiereatender.
Avisar al sistema de quecomience a atender dicha conexinde red. Se consigue
mediantelafuncinlisten().Apartirdeestemomentoelsistemaoperativoanotar
la conexin de cualquier cliente para pasrnosla cuando se lo pidamos. Si llegan
clientes ms rpido de lo que somos capaces de atenderlos, el sistema operativo
haceuna"cola"conellosynoslosirpasandosegnvayamospidindolo.
Pedir yaceptar las conexionesde clientes al sistema operativo. Para ello hacemos
unallamadaalafuncinaccept().Estafuncinleindicaalsistemaoperativoquenos
dalsiguienteclientedelacola.Sinohayclientessequedarbloqueadahastaque
algnclienteseconecte.
Escribir y recibir datosdel cliente, por medio de las funcioneswrite()yread(), que
son exactamente las mismas que usamos para escribir o leer de un fichero.
Obviamente,tantoclientecomoservidordebensaberqudatosesperanrecibir,qu
datosdebenenviaryenquformato.
Cierre de la comunicaciny del socket, por medio de la funcinclose(), que es la
mismaquesirveparacerrarunfichero.

EL CLIENTE
Lospasosquedebeseguirunprogramaclientesonlossiguientes:

Aperturadeunsocket,comoelservidor,pormediodelafuncinsocket()
Solicitar conexinconel servidor por medio de la funcinconnect(). Dicha funcin
quedarbloqueadahastaqueelservidoraceptenuestraconexinobiensinohay
servidorenelsitioindicado,saldrdandounerror.Enestallamadasedebefacilitar
ladireccinIPdelservidoryelnmerodepuertoquesedesea.
Escribiryrecibirdatosdelservidorpormediodelasfuncioneswrite()yread().
Cerrarlacomunicacinpormediodeclose().

Acontinuacinsepresentaelcdigodeunprogramaclienteydeunprogramaservidor,para
describir breve y generalmente los servicios de sockets implicados. Este cdigo es
prcticamente el ms bsico posible, sin comprobacin de errores. El funcionamiento ser
como sigue: Primero se arranca el programa servidor, que inicializa el socket servidor y se
quedaalaesperadeunaconexin.Acontinuacinsedebelanzarelprogramaclientequese
conectar al servidor. Una vez que ambos estn conectados, el servidor enviara al cliente
unosdatos(unafrase)queelclientemostrarporpantalla,yfinalmenteterminarnambos
programas.Elfuncionamientoenlneasgeneralesquedarepresentadoenlasiguientefigura:

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 11. COMUNICACIN POR SOCKETS 351

Programa cliente
Elcdigodelprogramacliente,mssimplequeeldelservidor,eselsiguiente:

//includes necesarios para los sockets


#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>

#define INVALID_SOCKET -1

int main()
{
//declaracion de variables
int socket_conn;//handle del socket utilizado
struct sockaddr_in server_address;
char address[]="127.0.0.1";
int port=12000;
// Configuracion de la direccion IP de connexion al servidor
352 PROGRAMACIN C++ Y COMUNICACIONES.

server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = inet_addr(address);
server_address.sin_port = htons(port);
//creacion del socket
socket_conn=socket(AF_INET, SOCK_STREAM,0);
//conexion
int len= sizeof(server_address);
connect(socket_conn,(struct sockaddr *) &server_address,len);
//comunicacion
char cad[100];
int length=100; //lee un mximo de 100 bytes
int r=recv(socket_conn,cad,length,0);
std::cout<<"Rec: "<<r<<" contenido: "<<cad<<std::endl;
//cierre del socket
shutdown(socket_conn, SHUT_RDWR);
close(socket_conn);
socket_conn=INVALID_SOCKET;
return 1;
}
Acontinuacinsedescribebrevementeelprograma:

Lasprimeraslneassonalgunos#includesnecesariosparaelmanejodeserviciosdesockets.
EnelcasodequererutilizarlossocketsenWindows,elficherodecabeceraylalibreraconla
quehayqueenlazarsepodranestablecerconlaslneas:

#include <winsock2.h>
#pragma comment (lib, "ws2_32.lib")
Enlasprimeraslneasdelmain()sedeclaranlasvariablesnecesariasparaelsocket.

int socket_conn;//the socket used for the send-receive


struct sockaddr_in server_address;
Laprimeralneadeclaraeldescriptorohandledelsocket(detipoentero)queseutilizatanto
paralaconexincomoparalacomunicacin.Estenmeronoesmsqueunidentificadorque
nosdarelsistemaoperativoparapoderindicarunsocketdeterminado.

Lasegundadeclaracindeclaraunaestructuradedatosquesirveparaalmacenarladireccin
IP y el nmero de puerto del servidor y la familia de protocolos que se utilizaran en la
comunicacin.Comoyasehaexplicado,unordenadorpuedecomunicarsesimultneamente
con muchos programas y muchos ordenadores. De alguna forma el puerto es como una
extensin a la direccin IP. Haciendo una analoga, la direccin podra entenderse como la
direccindelaescuela,mientrasqueelpueetoesundespachooextensindeterminado.La
asignacindeestaestructuraapartirdelaIPdefinidacomounacadenadetextoyelpuerto
definidocomounenterosehacecomosigue:

char address[]="127.0.0.1";
int port=12000;
server_address.sin_family = AF_INET;

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 11. COMUNICACIN POR SOCKETS 353

server_address.sin_addr.s_addr = inet_addr(address);
server_address.sin_port = htons(port);

NtesequelaIPqueutilizaremosserla127.0.0.1.EstaIPesunaIPespecialquesignificala
mquina actual (direccin local). Realmente ejecutaremos las dos aplicaciones (cliente y
servidor)enlamismamquina,utilizandoladireccinlocaldelamisma.Noobstanteestose
puedecambiar.ParaejecutarelservidorenunamquinaquetienelaIP192.168.1.13por
ejemplo, basta poner dicha direccin en ambos programas, ejecutar el servidor en esa
mquina,yelclienteencualquierotra(queseacapazdeenrutarmensajeshaciaesaIP).

Tambin es posible utilizar funciones del sistema operativo para intentar obtener una
direccinIPenbasealconocimientodelosnombresdelosordenadores.

Hay dos ficheros en Unix/Linux y en Windows que nos facilitan esta tarea, aunque hay que
tenerpermisosderootparamodificarlos.Estosficherosseranelequivalenteaunaagenda
de telfonos, en uno tenemos apuntados el nombre de la empresa con su nmero de
telfonoyenelotroficheroelnombredelapersonaysuextensin(UPMEUITI,tlfn91336
6799;MiguelHernando,extensin6878;...)

/etc/hosts en UNIX/LINUX o \system32\drivers\etc\hosts.en Windows: Esta es la


agendaenlaquetenemoslasempresasysusnmerosdetelfono.Enestefichero
hayunalistadenombresdeordenadoresconectadosenredyladireccinIPdecada
uno.Habitualmenteenelladodelclientesesuelecolocarelnombredelservidory
su direccin IP. Luego, desde el programa, se puede realizar una llamada a la
funcingethostbyname(),lacualsilepasamoselnombredelordenadorcomouna
cadena de caracteres, devuelve una estructura de datos entre los que est la
direccinIP.
/etc/serviceso system32\drivers\etc\services: Este fichero es el equivalente a la
agenda donde tenemos apuntados los distintos departamentos/personas de la
empresa y sus nmeros de extensin telefnica. En este fichero hay una lista de
servicios disponibles, indicando nombre de servicio, nmero de servicio y tipo
(ftp/udp). Tanto el servidor como el cliente deben tener en este fichero el servicio
queestnatendiendo/solicitandoconelmismonmeroytipodeservicio.Elnombre
puede ser distinto, igual que cada uno en su agenda pone el nombre que quiere,
pero no es lo habitual. Desde programa, tanto cliente como servidor, deben hacer una
llamada a la funcin getservbyname(), a la que pasndole el nombre del servicio, devuelve
una estructura de datos entre los que est el nmero de puerto y el tipo.

354 PROGRAMACIN C++ Y COMUNICACIONES.

Note que para iniciar un tipo de comunicacin mediante un socket se requiere designar un
puerto de comunicaciones. Esto significa que algunos puertos deben reservarse para stos
usosbienconocidos.

01023:Estospuertospuedensersloenlazadosporelsistema.
10245000:Puertosdesignadosaaplicacionesconocidas.
500164K1:Puertosdisponiblesparausosparticulares.

A continuacin se muestran algunos de los servicios registrados enservice deuna mquina


Windows:
# Copyright (c) 1993-2004 Microsoft Corp.
#
# This file contains port numbers for well-known services defined by IANA
#
# Format:
#
# <service name> <port number>/<protocol> [aliases...] [#<comment>]
#

echo 7/tcp
echo 7/udp
discard 9/tcp sink null
discard 9/udp sink null
systat 11/tcp users #Active users
systat 11/udp users #Active users
daytime 13/tcp
daytime 13/udp
qotd 17/tcp quote #Quote of the day
qotd 17/udp quote #Quote of the day
chargen 19/tcp ttytst source #Character generator
chargen 19/udp ttytst source #Character generator
ftp-data 20/tcp #FTP, data
ftp 21/tcp #FTP. control
ssh 22/tcp #SSH Remote Login Protocol
telnet 23/tcp
smtp 25/tcp mail #Simple Mail Transfer Protocol
time 37/tcp timserver
time 37/udp timserver
rlp 39/udp resource #Resource Location Protocol
nameserver 42/tcp name #Host Name Server
nameserver 42/udp name #Host Name Server
nicname 43/tcp whois
domain 53/tcp #Domain Name Server
domain 53/udp #Domain Name Server
bootps 67/udp dhcps #Bootstrap Protocol Server
bootpc 68/udp dhcpc #Bootstrap Protocol Client
tftp 69/udp #Trivial File Transfer
gopher 70/tcp
finger 79/tcp
http 80/tcp www www-http #World Wide Web
hosts2-ns 81/tcp #HOSTS2 Name Server
hosts2-ns 81/udp #HOSTS2 Name Server
kerberos 88/tcp krb5 kerberos-sec #Kerberos
kerberos 88/udp krb5 kerberos-sec #Kerberos
hostname 101/tcp hostnames #NIC Host Name Server

Se puede observar como el protocolo http del navegador aparece reflejado en el conocido
puerto80,ocomoelprotocolosmtpserealizaenprincipiosobreelpuerto25.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 11. COMUNICACIN POR SOCKETS 355

A continuacin se crea el socket, especificando la familia de protocolos (en este caso


protocolodeInternetAF_INET)yeltipodecomunicacinquesequiereemplear(orientadaa
laconexin=SOCK_STREAM,noorientadaalaconexin=SOCK_DGRAM).

ElprimerparmetroesAF_INEToAF_UNIXparaindicarsilosclientespuedenestarenotros
ordenadoresdistintosdelservidorovanacorrerenelmismoordenador.AF_INETvalepara
losdoscasos.AF_UNIXsloparaelcasodequeelclientecorraenelmismoordenadorqueel
servidor,peroloimplementadeformamseficiente.SipusieramosAF_UNIX,elrestodelas
funcionesvaranligeramente.
Elsegundoparmetroindicasielsocketesorientadoaconexin(SOCK_STREAM)TCP/IPono
loes(SOCK_DGRAM)UDP/IP.DeestaformapodremoshacersocketsderedodeUnixtanto
orientadosaconexincomonoorientadosaconexin.

Eltercerparmetroindicaelprotocoloaemplear.Habitualmentesepone0,locualsignifica
queelsistemaloescogerpordefecto.

Ennuestrocasovamosautilizarcomunicacinorientadaalaconexinyportantofiable.
//creacion del socket
socket_conn=socket(AF_INET, SOCK_STREAM,0);
Estafuncingeneralmentenoproduceerrores,aunqueenalgncasopodrahacerlo.Como
reglageneralconvienecomprobarsuvalor,queseriguala1(INVALID_SOCKET)silafuncin
hafallado.

Acontinuacinseintentalaconexinconelsocketespecificadoenladireccindelservidor.
Comoseobservaenelejemplo,estadireccinvienedadaporunaestructuraqueyacontiene
enelformatopropiodelaredladireccin,elpuertoyelprotocolodered.Loscamposque
obligatoriamentehayquerellenarsonlosreflejadosenelejemplo:

server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = inet_addr(address);
server_address.sin_port = htons(port);

sin_familyeseltipodeconexin(porredointerna),igualqueelprimerparmetro
desocket().
sin_portes el nmero de puerto correspondiente al servicio que podriamos haber
obtenidocongetservbyname().Elvalorestaraenenelcampos_portdePuertode
laestructuradevueltaporgetserbyname().Enelejemplosinembargoseespecifica
el nmero de puerto directamente, pero convirtindolo al formato
Finalmentesin_addr.s_addresladireccindelclientealquequeremosatender
356 PROGRAMACIN C++ Y COMUNICACIONES.

Paraentenderelusodehtonsyinet_addr,esnecesarioindicarcomoesimportantequeenla
redseenvienlosdatosconunformatoclaro.Lasmquinasenfuncindelaarquitecturayel
procesador utilizan un modo diferente de representar los nmeros. inet_addr, adems de
conseguirqueladireccinquederepresentadaconunordendebytescorrecto,loquelogra
es traducir una direccin IP dada como una secuencia de caracteres en un long int de 32
bytes.

NetworkbyteorderyHostbyteordersondosformasenlasqueelsistemapuedealmacenar
los datos en memoria. Est relacionado con el orden en que se almacenan los bytes en la
memoriaRAM.

Sialalmacenarunshortint(2bytes)ounlongint(4bytes)enRAM,yenlaposicinmsalta
sealmacenaelbytemenossignificativo,entoncesestennetworkbyteorder,casocontrario
eshostbyteorder.

Cuando enviamos los datos por la red deben ir en un orden especificado, sino enviaramos
todos los datos al revs. Lo mismo sucede cuando recibimos datos de la red, debemos
ordenarlosalordenqueutilizanuestrosistema.Debemoscumplirlassiguientesreglas:

Todoslosbytesquesetransmitenhacialared,seannmerosIPodatos,debenestar
ennetworkbyteorder.
Todoslosdatosqueserecibendelared,debenconvertirseahostbyteorder.

Pararealizarestasconversionesutilizamoslasfuncionesquesedescribenacontinuacin.

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 11. COMUNICACIN POR SOCKETS 357

htons()hosttonetworkshortconvierteunshortintdehostbyteorderanetwork
byteorder(eselcasodelnmerodeservicioopuerto).
htonl()hosttonetworklongconvierteunlongintdehostbyteorderanetwork
byteorder.
ntohs()networktohostshortconvierteunshortintdenetworkbyteorderahost
byteorder.
ntohl()networktohostlongconvierteunlongintdenetworkbyteorderahost
byteorder.

Puede ser que el sistema donde se est programando almacene los datos en network byte
order y no haga falta realizar ninguna conversin, pero si tratamos de compilar el mismo
cdigofuenteenotraplataformahostbyteordernofuncionar.Comoconclusin,paraque
nuestrocdigofuenteseaportablesedebeutilizarsiemprelasfuncionesdeconversin.

//conexion
int len= sizeof(server_address);
connect(socket_conn,(struct sockaddr *) &server_address,len);

Estafuncinconnect()fallarsinoestaelservidorpreparadoporalgnmotivo(loquesucede
muy a menudo). Por lo tanto es ms que conveniente comprobar el valor de retorno de
connect()paraactuarenconsecuencia.Sepodrahaceralgocomo:

if(connect(socket_conn,(struct sockaddr *)
&server_address,len)!=0)
{
std::cout<<"Client could not connect"<<std::endl;
return -1;
}
Si la conexin se realiza correctamente, el socket ya esta preparado para enviar y recibir
informacin.

Enestecasohemosdecididoquevaaserelservidorelqueenvadatosalcliente.Estoesun
convenio entre el cliente y el servidor, que adopta el programador cuando disea e
implementaelsistema.

Comoelclientevaarecibirinformacin,utilizamoslafuncinderecepcin.Enestafuncin,
selesuministraunbufferenelqueguardalainformacinyelnmerodebytesmximoque
seesperarecibir.Lafuncinrecv()sebloqueahastaqueelservidorenvealgunainformacin.

Dichainformacinpuedesermenorqueeltamaomximosuministrado.Elvalorderetorno
delafuncinrecv()eselnumerodebytesrecibidos.
358 PROGRAMACIN C++ Y COMUNICACIONES.

//comunicacion
char cad[100];
int length=100; //read a maximum of 100 bytes
int r=recv(socket_conn,cad,length,0);
std::cout<<"Rec: "<<r<<" contenido: "<<cad<<std::endl;
Porultimosecierralacomunicacinysecierraelsocket.

shutdown(socket_conn, SHUT_RDWR);
close(socket_conn);
socket_conn=INVALID_SOCKET;

Servidor
El cdigo del programa servidor es algo ms Complejo, ya que debe realizar ms tareas. La
principalcaractersticaesqueseutilizandossocketsdiferentes,unoparalaconexinyotro
paralacomunicacin.ElservidorcomienzaenlazandoelsocketdeconexinaunadireccinIP
y un puerto (siendo la IP la de la mquina en la que corre el servidor), escuchando en ese
puertoyquedandoalaesperaAcceptdeunaconexin,enestadodebloqueo.Cuandoel
clienteseconecta,elAcceptsedesbloqueaydevuelveunnuevosocket,queesporelque
realmenteseenvanyrecibendatos.

#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <iostream>
#define INVALID_SOCKET -1

int main()
{
int socket_conn=INVALID_SOCKET;//used for communication
int socket_server=INVALID_SOCKET;//used for connection
struct sockaddr_in server_address;
struct sockaddr_in client_address;
// Configuracion de la direccion del servidor
char address[]="127.0.0.1";
int port=12000;
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = inet_addr(address);
server_address.sin_port = htons(port);
//creacion del socket servidor y escucha
socket_server = socket(AF_INET, SOCK_STREAM, 0);
int len = sizeof(server_address);
int on=1; //configuracion del socket para reusar direcciones
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
//escucha

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 11. COMUNICACIN POR SOCKETS 359

bind(socket_server,(struct sockaddr *) &server_address,len);


// Damos como maximo 5 clientes conectados simultneamente.
listen(socket_server,5);
//aceptacion de cliente (bloquea hasta la conexion)
unsigned int leng = sizeof(client_address);
socket_conn = accept(socket_server,
(struct sockaddr *)&client_address, &leng);
//notese que el envio se hace por el socket de communicacion
char cad[]="Hola Mundo";
int length=sizeof(cad);
send(socket_conn, cad, length,0);
//cierre de los dos sockets, el servidor y el de comunicacion
shutdown(socket_conn, SHUT_RDWR);
close(socket_conn);
socket_conn=INVALID_SOCKET;
shutdown(socket_server, SHUT_RDWR);
close(socket_server);
socket_server=INVALID_SOCKET;
return 1;
}
Hasta la creacin del socket del servidor, el programa es similar al cliente, quitando la
excepcindequesedeclaranlosdossockets,eldeconexinyeldecomunicacin.Laprimera
diferenciasonlaslneas:

//configuracion del socket para reusar direcciones


int on=1;
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
Estaslneasseutilizanparaqueelservidorseacapazdereusarladireccinyelpuertoque
hanquedadoabiertossinsercerradoscorrectamenteenunaejecucinanterior.Cuandoesto
sucede,elsistemaoperativodejaladireccindelsocketreservadayportantounintentode
utilizarlaparaunservidoracabaenfallo.Conestaslneaspodemosconfiguraryhabilitarque
sereusenlasdireccionesprevias.

Lasegundadiferenciaesqueenvezdeintentarlaconexinconconnect(),elservidordebe
establecerprimeroenquedireccinvaaestarescuchandosusocketdeconexin,loquese
establececonlaslneas:

int len = sizeof(server_address);


bind(socket_server,(struct sockaddr *) &server_address,len);
// Damos como maximo una cola de 5 conexiones.
listen(socket_server,5);
La funcin bind() enlaza el socket de conexin con la IP y el puerto establecidos
anteriormente.

Lallamadaabind()llevatresparmetros:

Handledelsocketquehemosabierto
360 PROGRAMACIN C++ Y COMUNICACIONES.

PunteroalaestructuraDireccion.Adiferenciadeloqueocurraconelcliente,enel
casodelservidorseespecificaladireccindelclientealquequeremosatender.En
este campo introducimos INADDR_ANY, si queremos atender a un cliente
cualquiera. La estructura admitida por este parmetro es general y valida para
cualquiertipodesocketyesdeltipostructsockaddr.Cadasocketconcretollevasu
propia estructura. LosAF_INETcomo este caso llevanstruct sockaddr_in,
losAF_UNIXllevan la estructurastruct sockaddr_un. Por eso, a la hora de pasar el
parmetro,debemoshacerun"cast"altipostructsockaddr.

LongituddelaestructuraDireccion.

Estafuncintambinessusceptibledefallo.Elfallomscomnescuandoseintentaenlazar
elsocketconunadireccinypuertoqueyaestnocupadosporotrosocket.Enestecasola
funcindevolver1,indicandoelerror.Avecesesposiblequesinosecierracorrectamente
unsocket(porejemplo,sielprogramafinalizabruscamente),elSOpiensequedichopuerto
estaocupado,yalvolveraejecutarelprograma,elbind()falle,noteniendosentidocontinuar
laejecucin.Lagestinbsicadeesteerrorpodraser:

if(0!=bind(socket_server,(struct sockaddr *)
&server_address,len))
{
std::cout<<Fallo en el Bind()<<std::endl;
return -1;
}

Lafuncinlisten()permitedefinircuantaspeticionesdeconexinalservidorsernencoladas
por el sistema. Ntese que esto no significa que realmente se atiendan las peticiones de
conexin.Eselusuarioatravsdelafuncinaccept()elqueaceptaunaconexin.Elnumero
deconexionesdependerdecuantasvecesejecuteelprogramadichoaccept().

//aceptacion de cliente (bloquea hasta la conexion)


unsigned int leng = sizeof(client_address);
socket_conn = accept(socket_server,
(struct sockaddr *)&client_address, &leng);

Lo ms importante del accept() es que en su modo normal bloquea el programa hasta que
realmenteserealizalaconexinporpartedelcliente.Aestafuncinselesuministraelsocket
de conexin, y devuelve el socket que realmente se utilizar para la comunicacin. Si algo
falla en la conexin, la funcin devolver 1, lo que corresponde a nuestra definicin de
socketinvalidoINVALID_SOCKET,loquepodemoscomprobar:

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 11. COMUNICACIN POR SOCKETS 361

if(socket_conn==INVALID_SOCKET)
{
std::cout<<Error en el accept<<std::endl;
return -1;
}
Una vez que se ha realizado la conexin, la comunicacin se hace por el nuevo socket,
utilizandolasmismasfuncionesdeenvoyrecepcinquesepodranusarenelcliente.Notese
que un modo de atender a varios clientes, es ir haciendo accepts consecutivos y creando
sockets de comunicacin hasta alcanzar un nmero determinado, momento en el que ya
trabajamosconlascomunicacionesalosdistintosclientes.

Enelejemploactual,realmentesloatendemosaunclientecadavezyporconveniohemos
establecidoqueserelservidorelqueenvaunprimermensajealcliente.Elcdigosiguiente
envaelmensajeHolaMundoporelsocket:

char cad[]="Hola Mundo";


int length=sizeof(cad);
//notese que el envio se hace por el socket de communicacion
send(socket_conn, cad, length,0);

Lafuncinsend()tambinpuedefallar,sielsocketnoestacorrectamenteconectado(seha
desconectado el cliente por ejemplo). La funcin devuelve el nmero de bytes enviados
correctamente o 1 en caso de error. Tpicamente, si la conexin es buena, la funcin
devolvercomoretornounvalorigualalength,aunquetambinesposiblequenoconsiga
enviartodoslosdatosqueselehasolicitado.Unasolucincompletadebecontemplaresta
posibilidad y reenviar los datos que no han sido enviados. No obstante y por simplicidad,
realizamosahoraunagestinsencilladeesteposibleerror:

if(lenght!=send(socket_conn, cad, length,0))


{
std::cout<<Fallo en el send()<<std::endl;
return -1;
}

Elcierredelossocketsserealizadelamismamaneraqueenelcliente,exceptuandoquese
deben cerrar correctamentelos dos sockets, el de conexin y el de comunicacin. La salida
por pantalla al ejecutar las aplicaciones (primero arrancar el servidor y luego el cliente)
deberaser(enelladodelcliente):

Rec: 11 contenido: Hola Mundo


362 PROGRAMACIN C++ Y COMUNICACIONES.

Ntese que los bytes recibidos son 11 porque incluyen el carcter nulo \0 de final de la
cadena.

11.3. Modelos de conexin Cliente-Servidor

Existen diversas formas de atender las conexiones de clientes en un servidor. Sin embargo
dado que la programacin concurrente no la trataremos en este curso, simplemente se
exponen a continuacin para entender la importancia de estas estructuras. La primera de
ellasrespondealmodovistoenelejemploanterios,lasegundarequieredeelusodethreads
(hilosdeejecucindeunproceso),ylaterceraeslaestructurahabitualconcomunicacinno
orientadaalaconexin.

Modelo Simple Cliente-Servidor: Conexin Stream

En el siguiente grfico se muestran los procesos que se ejecutan cuando se realiza una
conexinSimpleClienteServidor:

Enelservidor:

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 11. COMUNICACIN POR SOCKETS 363

Secreaunsocketdecomunicacinmediantelafuncinsocket().
Elsocketestformadoporunadireccinip+unpuertodeconexin,paraellohay
queasociaresainformacinalsocketmediantelafuncinbind().
Laparteservidordelaaplicacindebeestablecerunacoladeconexionesentrantes
para atender a los clientes segn el orden de llegada, esto se hace mediante la
funcinlisten().
Ahora el servidor deber atender las conexiones entrantes por el puerto que
establecimosmediantelafuncinaccept().
Tras establecer una comunicacin entre un cliente y un servidor se enviarn datos
mediantelafuncinsend()yserecibirnmediantelafuncinrecv().
Alfinalizarlacomunicacindeberemoscerrarelsocketdecomunicacin.

Enelcliente:

Secreaunsocketdecomunicacinmediantelafuncinsocket().
Elservidorestaceptandoconexionesentrantes,asquenosconectamosalservidor
mediantelafuncinconnect().
Recibimos y enviamos datos, pues ya estamos en contacto con el equipo remoto,
mediantelasfuncionesrecv()ysend().
Alfinalizarlacomunicacindeberemoscerrarelsocketdecomunicacin.

Modelo Concurrente Cliente-Servidor: Conexin Stream

Paraentenderelmodeloconcurrente,esprecisoalmenostenerunprimerconceptodeloque
esunhilodeejecucinothread:

Concepto de thread

UnthreadeslaunidadbsicadeejecucinenlamayoradelosS.O..Cualquierprogramaque
seejecuteconstade,almenos,unthread.

Un thread se puede considerar como la agrupacin de un trozo de programa junto con el


conjunto de registros del procesador que utiliza y una pila de mquina. El conjunto de los
registros y de la pila de cada thread se denominacontexto. Como sabemos, en un Sistema
Operativo multitarea, la CPU se reparte entre cada programa a ejecutar. Para ser ms
precisos,elS.O.repartelaCPUentretodoslosthreadsaejecutarencadamomento(puesun
programa puede contener varios threads), simplemente adueandose de esta y saltando al
364 PROGRAMACIN C++ Y COMUNICACIONES.

siguiente.Sinembargo,estaconmutacinnosepuedehacerdecualquiermanera.Cadavez
que el S.O. se aduea de la CPU para cedersela a otro thread, los registros y la pila (o sea,
elcontextodelhilo)contienenunosvaloresdeterminados.Poreso,elS.O.guardatodosesos
datosencadacambio,demodoquealvolveraconmutaralthreadinicial,puedarestaurarel
contextoinicial.LamayoradelosS.O.multitareasondetipopreemptivo,loquesignificaque
laCPUpuedeserarrebatadaencualquiermomento.Estosignificaqueunthreadnopuede
sabercuandoselevaaarrebatarlaCPU,porloquenopuedeguardarlosregistrosnilapila
deforma'voluntaria'.

Ladiferenciamsimportanteentrehiloyproceso,consisteenquedosprocesosdistintosen
unsistemamultitarea,nocompartenrecursosnisiquieraelmapadememoria,detalforma
quelacomunicacinentrelosmismosserealizapormediodemecanismosdecomunicacin
dados por el sistema operativo (memorias compartidas, pipes, mensajes). Son como dos
instanciasdiferentesdelmismotipo.Sinembargolosthreads,salvolapilayelcontextodela
CPU,compartenrecursos,memoriaymapadedireccinesyportantolaszonasdedatosson
comunes para todos los threads de un mismoproceso. Una de las ventajas que tienen por
tanto es que la conmutacin entre hilos de un mismo programa (proceso) es muy rpida,
frentealcambiodecontextoentredosprocesos.

Por otro lado, debemos recordar que cada thread se ejecuta de forma absolutamente
independiente.Dehecho,cadaunotrabajacomosituvieseunmicroprocesadorparaelsolo.
Estosignificaquesitenemosunazonadedatoscompartidaentrevariosthreadsdemodoque
puedan intercambiar informacin entre ellos, es necesario usar algn sistema de
sincronizacinparaevitarqueunodeellosaccedaaungrupodedatosquepuedenestara
medio actualizar por otro thread. Estos problemas clsicos en los sistemas concurrentes
quedanfueradelenfoquedelcurso,perobasteaquporlomenosmencionarlo.

Modelo concurrente cliente-servidor

En el siguiente grfico se muestran los procesos que se ejecutan cuando se realiza una
conexinConcurrenteClienteServidor:

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 11. COMUNICACIN POR SOCKETS 365

Enelservidor:

Secreaunsocketdecomunicacinmediantelafuncinsocket().
Elsocketestformadoporunadireccinip+unpuertodeconexin,paraellohay
queasociaresainformacinalsocketmediantelafuncinbind().
Laparteservidordelaaplicacindebeestablecerunacoladeconexionesentrantes
para atender a los clientes segn el orden de llegada, esto se hace mediante la
funcinlisten().
Ahora el servidor deber atender las conexiones entrantes por el puerto que
establecimosmediantelafuncinaccept().Lanicadiferenciaconelcasoanteriores
que una vez aceptada una conexin se crear un nuevo hilo de ejecucin (thread)
encargado de dicha comunicacin y en el cdigo principal se volvern a aceptar
conexiones entrantes. Esto quiere decir que por cada nueva conexin existir un
nuevothreadohilodeejecucin.
Tras establecer una comunicacin entre un cliente y un servidor se enviarn datos
mediantelafuncinsend()yserecibirnmediantelafuncinrecv().
Alfinalizarlacomunicacindeberemoscerrarelsocketdecomunicacinyfinalizar
suthreadcorrespondiente.

Enelcliente:
366 PROGRAMACIN C++ Y COMUNICACIONES.

Secreaunsocketdecomunicacinmediantelafuncinsocket().
Elservidorestaceptandoconexionesentrantes,asquenosconectamosalservidor
mediantelafuncinconnect().
Recibimos y enviamos datos, pues ya estamos en contacto con el equipo remoto,
mediantelasfuncionesrecv()ysend().
Alfinalizarlacomunicacindeberemoscerrarelsocketdecomunicacin.

Modelo Cliente-Servidor: Conexin Datagram

En el siguiente grfico se muestran los procesos que se ejecutan cuando se realiza una
conexinClienteServidormedianteDatagrams:

Enelservidor:

UPM-EUITI-2015. Miguel Hernando.


CAPTULO 11. COMUNICACIN POR SOCKETS 367

Secreaunsocketdecomunicacinmediantelafuncinsocket().
Elsocketestformadoporunadireccinip+unpuertodeconexin,paraellohay
queasociaresainformacinalsocketmediantelafuncinbind().
Trasestablecerunapuertodecomunicacinquedaalasesperadedatosentrantes
mediantelafuncinrecvfrom()oenvadatosaalgnclientemediantesendto().
Alfinalizarlacomunicacindeberemoscerrarelsocketdecomunicacinyfinalizar
suthreadcorrespondiente.

Enelcliente:

Secreaunsocketdecomunicacinmediantelafuncinsocket().
El servidor ya ha establecido un puerto de comunicacin por lo que podemos
enviarle datos mediante sendto() o esperar por algn dato que el servidor desee
enviarnosmedianterecvfrom().
Alfinalizarlacomunicacindeberemoscerrarelsocketdecomunicacin.
Anexo I. Soluciones a los ejercicios.

Captulo 2
EJERCICIO2.1

EJERCICIO2.2
#include <math.h>

float norma(float *v, int n=3, bool bnormaliza=false)


{
float modulo=0;
int i;
for(i=0;i<n;i++)modulo+=v[i]*v[i];
modulo=(float)sqrt((float)modulo);
if((bnormaliza)&&(modulo>0.0001F)){
for(i=0;i<n;i++)v[i]/=modulo;
}
return modulo;
}

Departamento de Electrnica Automtica e Informtica Industrial


370 PROGRAMACIN C++ Y COMUNICACIONES.

EJERCICIO2.3
a=3 b=5 c=6

EJERCICIO2.4
1 5 7 11 13 17 19 23 25 29

EJERCICIO2.5

OK nota1=bien;
MAL nota1=1;
OK nota1=(notas)1;
MAL nota1=suspenso+1;
MAL nota1=suspenso+aprobado;
OK var=5+bien;
OK var=bien+5;
OK var=notable+bien;
OK var=nota1+bien;
MAL nota1++;
OK for(var=suspenso;var<sobresaliente;var++)
printf(%d,var);
MAL for(nota2=suspenso;nota2<sobresaliente;nota2++)
printf(%d,(int)nota2);

EJERCICIO2.6
Valores: 18 14 17

UPM-EUITI-2015. Miguel Hernando.

Вам также может понравиться