Pensar en C++ V1_2

634
 Pensar en C++ (Volumen 1) Traducción (INACABADA) del libro Thinking in C++, Volumen 1 Bruce Eckel March 20, 2008 Puede encontrar la versión actualizada de este libro e información adicional sobre el proyecto de traducción en http://arco.inf-cr.uclm.es/~david.villa/pensarC++.html

Transcript of Pensar en C++ V1_2

Pensar en C++ (Volumen 1)Traduccin (INACABADA) del libro Thinking in C++, Volumen 1

Bruce Eckel

March 20, 2008

Puede encontrar la versin actualizada de este libro e informacin adicional sobre el proyecto de traduccin en http://arco.inf-cr.uclm.es/~david.villa/pensarC++.html

Pensar en C++ (Volumen 1) by Bruce Eckel Copyright 2000 Bruce Eckel

2

ndice de contenido1 Introduccin a los Objetos 1.1 1.2 1.3 1.4 1.5 El progreso de abstraccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Cada objeto tiene una interfaz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . La implementacin oculta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Reutilizar la implementacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Herencia: reutilizacin de interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.5.1 1.6 1.7 1.8 1.9 Relaciones es-un vs. es-como-un . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 31 32 34 34 35 37 38 41 41 42 43 43 44 46 47 48 48 48 49 49 50 50 51 51 52 52 52 53 53 53 53 53 3

Objetos intercambiables gracias al polimorsmo . . . . . . . . . . . . . . . . . . . . . . . . . . . Creacin y destruccin de objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Gestin de excepciones: tratamiento de errores . . . . . . . . . . . . . . . . . . . . . . . . . . . Anlisis y diseo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.9.1 Fase 0: Hacer un plan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.9.1.1 1.9.2 1.9.3 Declaracin de objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Fase 1: Qu estamos haciendo? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fase 2: Cmo podemos construirlo? . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.9.3.1 1.9.3.2 Las cinco etapas del diseo de objetos . . . . . . . . . . . . . . . . . . . . . . Directrices para desarrollo de objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.9.4 1.9.5 1.9.6 1.9.7

Fase 3: Construir el ncleo

Fase 4: Iterar los casos de uso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fase 5: Evolucin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Los planes valen la pena . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.10 Programacin Extrema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.10.1 Escriba primero las pruebas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.10.2 Programacin en parejas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.11 Porqu triunfa C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.11.1 Un C mejor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.11.2 Usted ya est en la curva de aprendizaje . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.11.3 Eciencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.11.4 Los sistemas son ms fciles de expresar y entender . . . . . . . . . . . . . . . . . . . . 1.11.5 Aprovechamiento mximo con libreras . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.11.6 Reutilizacin de cdigo fuente con plantillas . . . . . . . . . . . . . . . . . . . . . . . . 1.11.7 Manejo de errores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.11.8 Programar a lo grande . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

ndice de contenido 1.12 Estrategias de transicin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.12.1 Directrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.12.1.1 Entrenamiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.12.1.2 Proyectos de bajo riesgo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.12.1.3 Modelar desde el xito . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.12.1.4 Use libreras de clases existentes . . . . . . . . . . . . . . . . . . . . . . . . . 1.12.1.5 No reescriba en C++ cdigo que ya existe . . . . . . . . . . . . . . . . . . . . 1.12.2 Obstculos de la gestin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.12.2.1 Costes iniciales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.12.2.2 Cuestiones de rendimiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.12.2.3 Errores comunes de diseo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.13 Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Construir y usar objetos 2.1 El proceso de traduccin del lenguaje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.1 2.1.2 2.1.3 Intrpretes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Compiladores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . El proceso de compilacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.3.1 2.2 Comprobacin esttica de tipos . . . . . . . . . . . . . . . . . . . . . . . . . . 54 54 54 54 54 54 54 55 55 55 56 56 57 57 57 58 58 59 59 59 60 60 60 61 62 62 63 63 64 64 64 65 65 65 66 67 67 68 68 69 69 70

Herramientas para compilacin modular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.1 Declaraciones vs deniciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.1.1 2.2.1.2 2.2.1.3 2.2.1.4 2.2.1.5 2.2.1.6 2.2.2 2.2.3 Sintaxis de declaracin de funciones . . . . . . . . . . . . . . . . . . . . . . . Una puntualizacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Denicin de funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sintaxis de declaracin de variables . . . . . . . . . . . . . . . . . . . . . . . . Incluir cheros de cabecera . . . . . . . . . . . . . . . . . . . . . . . . . . . . Formato de inclusin del estndar C++ . . . . . . . . . . . . . . . . . . . . . .

Enlazado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Uso de libreras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.3.1 2.2.3.2 2.2.3.3 Cmo busca el enlazador una librera . . . . . . . . . . . . . . . . . . . . . . . Aadidos ocultos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Uso de libreras C plano . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.3

Su primer programa en C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3.1 2.3.2 2.3.3 2.3.4 2.3.5 Uso de las clases iostream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Espacios de nombres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fundamentos de la estructura de los programa . . . . . . . . . . . . . . . . . . . . . . . . Hello, World! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Utilizar el compilador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.4

Ms sobre iostreams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4.1 2.4.2 2.4.3 Concatenar vectores de caracteres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Leer de la entrada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Llamar a otros programas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.5 4

Introducin a las cadenas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

ndice de contenido 2.6 2.7 2.8 2.9 3 Lectura y escritura de cheros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduccin a los vectores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 72 75 76 77 77 78 79 79 80 80 80 81 82 82 83 84 85 86 87 87 87 88 88 89 90 91 93 95 96 97 98

C en C++ 3.1 Creacin de funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.1 3.1.2 3.1.3 3.2 Valores de retorno de las funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Uso de funciones de libreras C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creacin de libreras propias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Control de ujo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 3.2.9 Verdadero y falso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . if-else . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . do-while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Las pasabras reservadas break y continue . . . . . . . . . . . . . . . . . . . . . . . switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Uso y maluso de goto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Recursividad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3.3

Introduccin a los operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.1 3.3.2 Precedencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Auto incremento y decremento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3.4

Introduccin a los tipos de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6 3.4.7 Tipos predenidos bsicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . booleano, verdadero y falso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Especicadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduccin a punteros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Modicar objetos externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduccin a las referencias de C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . Punteros y Referencias como modicadores . . . . . . . . . . . . . . . . . . . . . . . .

3.5

Alcance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.5.1 Denicin de variables al vuelo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3.6

Especicar la ubicacin del espacio de almacenamiento . . . . . . . . . . . . . . . . . . . . . . 100 3.6.1 3.6.2 Variables globales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 Variables locales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 3.6.2.1 3.6.3 3.6.4 Variables registro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101

Static . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 extern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 3.6.4.1 Enlazado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103

3.6.5

Constantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 3.6.5.1 Valores constantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104

3.6.6

Volatile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 5

ndice de contenido 3.7 Los operadores y su uso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 3.7.1 3.7.2 Asignacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 Operadores matemticos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 3.7.2.1 3.7.3 3.7.4 3.7.5 3.7.6 3.7.7 3.7.8 3.7.9 Introduccin a las macros del preprocesador . . . . . . . . . . . . . . . . . . . 106

Operadores relacionales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 Operadores lgicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 Operadores para bits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 Operadores de desplazamiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 Operadores unarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 El operador ternario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 El operador coma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111

3.7.10 Trampas habituales cuando se usan operadores . . . . . . . . . . . . . . . . . . . . . . . 112 3.7.11 Operadores de moldeado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 3.7.12 Los moldes explcitos de C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 3.7.12.1 static_cast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 3.7.12.2 const_cast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 3.7.12.3 reinterpret_cast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 3.7.13 sizeof - un operador en si mismo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 3.7.14 La palabra reservada asm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 3.7.15 Operadores explcitos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 3.8 Creacin de tipos compuestos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 3.8.1 3.8.2 Creacin de alias usando typedef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 Usar struct para combinar variables . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 3.8.2.1 3.8.3 Punteros y estructuras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120

Programas ms claros gracias a enum . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 3.8.3.1 Comprobacin de tipos para enumerados . . . . . . . . . . . . . . . . . . . . . 121

3.8.4 3.8.5

Cmo ahorrar memoria con union . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 3.8.5.1 3.8.5.2 3.8.5.3 Punteros y arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 El formato de punto otante . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 Aritmtica de punteros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128

3.9

Consejos para depuracin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 3.9.1 Banderas para depuracin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 3.9.1.1 3.9.1.2 3.9.2 3.9.3 Banderas de depuracin para el preprocesador . . . . . . . . . . . . . . . . . . 131 Banderas para depuracin en tiempo de ejecucin . . . . . . . . . . . . . . . . 131

Convertir variables y expresiones en cadenas . . . . . . . . . . . . . . . . . . . . . . . . 132 La macro C assert() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133

3.10 Direcciones de funcin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 3.10.1 Denicin de un puntero a funcin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 3.10.2 Declaraciones y deniciones complicadas . . . . . . . . . . . . . . . . . . . . . . . . . . 134 3.10.3 Uso de un puntero a funcin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 3.10.4 Arrays de punteros a funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 6

ndice de contenido 3.11 Make: cmo hacer compilacin separada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 3.11.1 Las actividades de Make . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 3.11.1.1 Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 3.11.1.2 Reglas de sujo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 3.11.1.3 Objetivos predeterminados . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 3.11.2 Los Makeles de este libro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 3.11.3 Un ejemplo de Makele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 3.12 Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140 3.13 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140 4 Abstraccin de Datos 4.1 143

Una librera pequea al estilo C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 4.1.1 4.1.2 Asignacin dinmica de memoria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 Malas suposiciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149

4.2 4.3 4.4 4.5 4.6 4.7

Qu tiene de malo? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149 El objeto bsico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 Qu es un objeto? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 Tipos abstractos de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 Detalles del objeto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 Conveciones para los cheros de cabecera . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 4.7.1 4.7.2 4.7.3 4.7.4 4.7.5 4.7.6 Importancia de los cheros de cabecera . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 El problema de la declaracin mltiple . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 Las directivas del preprocesador #dene, #ifndef y #endif . . . . . . . . . . . . . . . . . 158 Un estndar para los cheros de cabecera . . . . . . . . . . . . . . . . . . . . . . . . . . 159 Espacios de nombres en los cheros de cabecera . . . . . . . . . . . . . . . . . . . . . . 160 Uso de los cheros de cabecera en proyectos . . . . . . . . . . . . . . . . . . . . . . . . 160

4.8

Estructuras anidadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 4.8.1 Resolucin de mbito global . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163

4.9

Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163

4.10 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 5 Ocultar la implementacin 5.1 5.2 167

Establecer los lmites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 Control de acceso en C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 5.2.1 protected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169

5.3

Friends . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 5.3.1 5.3.2 Amigas anidadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 Es eso puro? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173

5.4 5.5

Capa de objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 La clase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 5.5.1 5.5.2 Modicaciones en Stash para usar control de acceso . . . . . . . . . . . . . . . . . . . . 175 Modicar Stack para usar control de acceso . . . . . . . . . . . . . . . . . . . . . . . . . 176

5.6

Manejo de clases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 7

ndice de contenido 5.6.1 5.6.2 5.7 5.8 6 Ocultar la implementacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 Reducir la recompilacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177

Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 181

Inicializacin y limpieza 6.1 6.2 6.3

Inicializacin garantizada por el constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181 Limpieza garantizada por el destructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 Eliminacin del bloque de deniciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184 6.3.1 6.3.2 para bucles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185 Alojamiento de memoria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186

6.4 6.5 6.6 6.7 6.8 6.9 7

Stash con constructores y destructores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 Stack con constructores y destructores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 Inicializacin de tipos agregados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 Constructores por defecto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193 Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195 197

Sobrecarga de funciones y argumentos por defecto 7.1

Ms decoracin de nombres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 7.1.1 7.1.2 Sobrecarga en el valor de retorno . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 Enlace con tipos seguros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198

7.2 7.3 7.4

Ejemplo de sobrecarga . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 Uniones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 Argumentos por defecto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204 7.4.1 Argumentos de relleno . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205

7.5 7.6 7.7 8

Eleccin entre sobrecarga y argumentos por defecto . . . . . . . . . . . . . . . . . . . . . . . . . 206 Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 211

Constantes 8.1

Sustitucin de valores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 8.1.1 8.1.2 8.1.3 8.1.4 const en archivos de cabecera . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 constantes seguras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 Vectores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213 Diferencias con C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213

8.2

Punteros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215 8.2.1 8.2.2 Puntero a constante . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215 Puntero constante . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215 8.2.2.1 8.2.3 Formato . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216

Asignacin y comprobacin de tipos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 8.2.3.1 Literales de cadena . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217

8.3 8

Argumentos de funciones y valores de retorno . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217

ndice de contenido 8.3.1 8.3.2 Paso por valor constante . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217 Retorno por valor constante . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 8.3.2.1 8.3.3 Temporarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219

Paso y retorno de direcciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 8.3.3.1 Criterio de paso de argumentos . . . . . . . . . . . . . . . . . . . . . . . . . . 221

8.4

Clases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 8.4.1 const en las clases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 8.4.1.1 8.4.1.2 8.4.2 La lista de inicializacin del constructor. . . . . . . . . . . . . . . . . . . . . . 223 Constructores para los tipos del lenguaje . . . . . . . . . . . . . . . . . . . . . 223

Las constantes en tiempo de compilacin dentro de las clases. . . . . . . . . . . . . . . . 224 8.4.2.1 El enumerado en codigo antiguo . . . . . . . . . . . . . . . . . . . . . . . . . 226

8.4.3

Objetos y mtodos constantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227 8.4.3.1 FIXME mutable: bitwise vs. logical const . . . . . . . . . . . . . . . . . . . . 229

8.5 8.6 8.7 9

Volatile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230 Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232 235

Funciones inline 9.1

Los peligros del preprocesador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235 9.1.1 Macros y acceso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238

9.2

Funciones inline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238 9.2.1 9.2.2 inline dentro de clases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 Funciones de acceso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 9.2.2.1 Accesores y mutadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240

9.3 9.4

Stash y Stack con inlines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 Funciones inline y el compilador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247 9.4.1 9.4.2 9.4.3 Limitaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247 Referencias adelantadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248 Actividades ocultas en contructores y destructores . . . . . . . . . . . . . . . . . . . . . 248

9.5 9.6

Reducir el desorden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 Ms caractersticas del preprocesador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250 9.6.1 Encolado de smbolos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251

9.7 9.8 9.9

Comprobacin de errores mejorada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251 Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254 257

10 Control de nombres

10.1 Los elementos estticos de C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257 10.1.1 Variables estticas dentro de funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257 10.1.1.1 Objetos estticos dentro de funciones . . . . . . . . . . . . . . . . . . . . . . . 258 10.1.1.2 Destructores de objetos estticos . . . . . . . . . . . . . . . . . . . . . . . . . 259 10.1.2 Control del enlazado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 10.1.2.1 Confusin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261 9

ndice de contenido 10.1.3 Otros especicadores para almacenamiento de clases . . . . . . . . . . . . . . . . . . . . 262 10.2 Espacios de nombres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262 10.2.1 Crear un espacio de nombres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262 10.2.1.1 Espacios de nombres sin nombre . . . . . . . . . . . . . . . . . . . . . . . . . 263 10.2.1.2 Amigas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264 10.2.2 Cmo usar un espacio de nombres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264 10.2.2.1 Resolucin del mbito . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264 10.2.2.2 La directiva using . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265 10.2.2.3 La declaracin using . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267 10.2.3 El uso de los espacios de nombres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268 10.3 Miembros estticos en C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268 10.3.1 Denicin del almacenamiento para miembros de datos estticos . . . . . . . . . . . . . . 268 10.3.1.1 Inicializacin de vectores estticos . . . . . . . . . . . . . . . . . . . . . . . . 270 10.3.2 Clases anidadas y locales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271 10.3.3 Mtodos estticos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272 10.4 FIXME static initialization dependency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274 10.4.1 Qu hacer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276 10.5 Especicaciones de enlazado alternativo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 10.6 Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282 10.7 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282 11 Las referencias y el constructor de copia 285

11.1 Punteros en C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285 11.2 Referencias en C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285 11.2.1 Referencias en las funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286 11.2.1.1 Referencias constantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287 11.2.1.2 Referencias a puntero . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288 11.2.2 Consejos para el paso de argumentos . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288 11.3 El constructor de copia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288 11.3.1 Paso y retorno por valor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289 11.3.1.1 Paso y retorno de objetos grandes . . . . . . . . . . . . . . . . . . . . . . . . . 289 11.3.1.2 mbito de la pila para una llamada a una funcin . . . . . . . . . . . . . . . . 290 11.3.1.3 Re-entrada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290 11.3.1.4 Copia bit a bit vs. inicializacin . . . . . . . . . . . . . . . . . . . . . . . . . . 291 11.3.2 Construccin por copia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292 11.3.2.1 Objetos temporales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295 11.3.3 Constructor copia por defecto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296 11.3.4 Alternativas a la construccin por copia . . . . . . . . . . . . . . . . . . . . . . . . . . . 297 11.3.4.1 Prevencin del paso por valor . . . . . . . . . . . . . . . . . . . . . . . . . . . 298 11.3.4.2 Funciones que modican objetos externos . . . . . . . . . . . . . . . . . . . . 298 11.4 Punteros a miembros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299 11.4.1 Funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300 11.4.1.1 Un ejemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301 10

ndice de contenido 11.5 Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302 11.6 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303 12 Sobrecarga de operadores 12.1 Precaucin y tranquilidad 305 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305

12.2 Sintaxis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305 12.3 Operadores sobrecargables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307 12.3.1 Operadores unarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307 12.3.1.1 Incremento y decremento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310 12.3.2 Operadores binarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310 12.3.3 Argumentos y valores de retorno . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 12.3.3.1 Retorno por valor como constante . . . . . . . . . . . . . . . . . . . . . . . . . 319 12.3.3.2 Optimizacin del retorno . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319 12.3.4 Operadores poco usuales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320 12.3.4.1 El operador coma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320 12.3.4.2 El operador -> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321 12.3.4.3 Un operador anidado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322 12.3.4.4 Operador ->* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324 12.3.5 Operadores que no puede sobrecargar . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325 12.4 Operadores no miembros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326 12.4.1 Directrices bsicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327 12.5 Sobrecargar la asignacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327 12.5.1 Comportamiento del operador = . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328 12.5.1.1 Punteros en clases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329 12.5.1.2 Contabilidad de referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331 12.5.1.3 Creacin automtica del operador = . . . . . . . . . . . . . . . . . . . . . . . . 335 12.6 Conversin automtica de tipos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336 12.6.1 Conversin por constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336 12.6.1.1 Prevenir la conversin por constructor . . . . . . . . . . . . . . . . . . . . . . 336 12.6.2 Conversin por operador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337 12.6.2.1 Reexividad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338 12.6.3 Ejemplo de conversin de tipos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339 12.6.4 Las trampas de la conversin automtica de tipos . . . . . . . . . . . . . . . . . . . . . . 340 12.6.4.1 Actividades ocultas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341 12.7 Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342 12.8 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342 13 Creacin dinmica de objetos 345

13.1 Creacin de objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345 13.1.1 Asignacin dinmica en C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346 13.1.2 Operador new . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347 13.1.3 Operador delete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348 13.1.4 Un ejemplo sencillo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348 11

ndice de contenido 13.1.5 Trabajo extra para el gestor de memoria . . . . . . . . . . . . . . . . . . . . . . . . . . . 349 13.2 Rediseo de los ejemplos anteriores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349 13.2.1 delete void* probablemente es un error . . . . . . . . . . . . . . . . . . . . . . . . . . 349 13.2.2 Responsabilidad de la limpieza cuando se usan punteros . . . . . . . . . . . . . . . . . . 350 13.2.3 Stash para punteros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351 13.2.3.1 Una prueba . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353 13.3 new y delete para vectores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354 13.3.1 Cmo hacer que un puntero sea ms parecido a un vector . . . . . . . . . . . . . . . . . . 355 13.3.2 Cuando se supera el espacio de almacenamiento . . . . . . . . . . . . . . . . . . . . . . 355 13.3.3 Sobrecarga de los operadores new y delete . . . . . . . . . . . . . . . . . . . . . . . 356 13.3.3.1 Sobrecarga global de new y delete . . . . . . . . . . . . . . . . . . . . . . . 357 13.3.3.2 13.3.3.3 Sobrecarga de new y delete especca para una clase . . . . . . . . . . . . 358 Sobrecarga de new y delete para vectores . . . . . . . . . . . . . . . . . . 360

13.3.3.4 Llamadas al constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362 13.3.3.5 Operadores new y delete de [FIXME emplazamiento (situacin)] . . . . . . 363

13.4 Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364 13.5 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364 14 Herencia y Composicin 367

14.1 Sintaxis de la composicin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367 14.2 Sintaxis de la herencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369 14.3 Lista de inicializadores de un constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370 14.3.1 Inicializacin de objetos miembros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370 14.3.2 Tipos predenidos en la lista de inicializadores . . . . . . . . . . . . . . . . . . . . . . . 370 14.3.3 Combinacin de composicin y herencia . . . . . . . . . . . . . . . . . . . . . . . . . . 371 14.3.3.1 Llamadas automticas al destructor . . . . . . . . . . . . . . . . . . . . . . . . 372 14.3.4 Orden de llamada de constructores y destructores . . . . . . . . . . . . . . . . . . . . . . 372 14.4 Ocultacin de nombres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374 14.5 Funciones que no heredan automticamente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377 14.5.1 Herencia y mtodos estticos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379 14.5.2 Composicin vs. herencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379 14.5.2.1 Subtipado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380 14.5.2.2 Herencia privada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 382 14.5.2.2.1 Publicar los miembros heredados de forma privada . . . . . . . . . . 382

14.6 Protected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383 14.6.1 Herencia protegida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384 14.7 Herencia y sobrecarga de operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384 14.8 Herencia mltiple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385 14.9 Desarrollo incremental . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386 14.10FIXME Upcasting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386 14.10.1 Por qu FIXME "upcasting"? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387 14.10.2 FIXME Upcasting y el constructor de copia . . . . . . . . . . . . . . . . . . . . . . . . . 387 14.10.3 Composicin vs. herencia FIXME (revisited) . . . . . . . . . . . . . . . . . . . . . . . . 389 12

ndice de contenido 14.10.4 FIXME Upcasting de punteros y referencias . . . . . . . . . . . . . . . . . . . . . . . . . 390 14.10.5 Una crisis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390 14.11Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391 14.12Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391 15 Polimorsmo y Funciones virtuales 395

15.1 Evolucin de los programadores de C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395 15.2 Upcasting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 396 15.3 El problema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397 15.3.1 Ligadura de las llamadas a funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397 15.4 Funciones virtuales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397 15.4.1 Extensibilidad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398 15.5 Cmo implementa C++ la ligadura dinmica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400 15.5.1 Almacenando informacin de tipo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400 15.5.2 Pintar funciones virtuales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402 15.5.3 Detrs del teln . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402 15.5.4 Instalar el vpointer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403 15.5.5 Los objetos son diferentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403 15.6 Por qu funciones virtuales? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404 15.7 Clases base abstractas y funciones virtuales puras . . . . . . . . . . . . . . . . . . . . . . . . . . 405 15.7.1 Deniciones virtuales puras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407 15.8 Herencia y la VTABLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408 15.8.1 FIXME: Object slicing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410 15.9 Sobrecargar y redenir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411 15.9.1 Tipo de retorno variante . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413 15.10funciones virtuales y constructores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414 15.10.1 Orden de las llamadas a los constructores . . . . . . . . . . . . . . . . . . . . . . . . . . 414 15.10.2 Comportamiento de las funciones virtuales dentro de los constructores . . . . . . . . . . . 415 15.10.3 Destructores y destructores virtuales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415 15.10.4 Destructores virtuales puros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417 15.10.5 Mecanismo virtual en los destructores . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418 15.10.6 Creacin una jerarqua basada en objetos . . . . . . . . . . . . . . . . . . . . . . . . . . 419 15.11Sobrecarga de operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421 15.12Downcasting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423 15.13Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425 15.14Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426 16 Introduccin a las Plantillas 429

16.1 Contenedores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429 16.1.1 La necesidad de los contenedores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431 16.2 Un vistazo a las plantillas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431 16.2.1 La solucin de la plantilla . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 432 16.3 Sintaxis del Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433 13

ndice de contenido 16.3.1 Deniciones de funcin no inline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434 16.3.1.1 Archivos cabecera . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434 16.3.2 IntStack como plantilla . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435 16.3.3 Constantes en los Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436 16.4 Stack y Stash como Plantillas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437 16.4.1 Cola de punteros mediante plantillas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439 16.5 Activando y desactivando la propiedad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443 16.6 Manejando objetos por valor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445 16.7 Introduccin a los iteradores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447 16.7.1 Stack con iteradores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453 16.7.2 PStash con iteradores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456 16.8 Por qu usar iteradores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 460 16.8.1 Plantillas Funcin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462 16.9 Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463 16.10Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463 A Estilo de codicacin 465

A.1 General . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465 A.2 Nombres de chero . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466 A.3 Marcas comentadas de inicio y n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466 A.4 Parntesis, llaves e indentacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466 A.5 Nombres para identicadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469 A.6 Orden de los #includes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469 A.7 Guardas de inclusin en cheros de cabecera . . . . . . . . . . . . . . . . . . . . . . . . . . . . 470 A.8 Uso de los espacios de nombres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 470 A.9 Utilizacin de require() y assure() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 470 471 479

B Directrices de Programacin C Lecturas recomendadas

C.1 Sobre C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479 C.2 Sobre C++ en general . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479 C.2.1 Mi propia lista de libros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479

C.3 Los rincones oscuros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 480 C.4 Sobre Anlisis y Diseo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 480

14

ndice de tablas3 C en C++ 3.1 3.2 3.3 Expresiones que utilizan booleanos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89

Moldes explcitos de C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 Nuevas palabras reservadas para operadores booleanos . . . . . . . . . . . . . . . . . . . . . . . 117

12 Sobrecarga de operadores 12.1 Directrices para elegir entre miembro y no-miembro . . . . . . . . . . . . . . . . . . . . . . . . . 327

15

Prlogo a la traduccinEste trabajo de traduccin ha sido realizado ntegramente por voluntarios. Le agradecemos que nos comunique cualquier error de traduccin o transcripcin en el texto. Tambin ser bienvenido si desea colaborar ms activamente en la traduccin. Puede encontrar informacin para ello en nuestra pgina web 1 . Aydenos a hacer de esta traduccin un trabajo de calidad. Tenga presente que el trabajo de traduccin no ha terminado. Si utiliza el libro en el estado actual es probable que encuentre innumerables errores. Por favor, no nos los notique por ahora. Le agradeceremos su colaboracin para corregir posibles erratas cuando el trabajo se d por terminado, pero ese momento an no ha llegado (falta poco). Ello no implica que el libro no pueda serle til en su estado actual. Este captulo se actualiza frecuentemente y no lo dar por terminado hasta que concluya el proceso de traduccin y revisin de este volumen al menos. La traduccin del Volumen 2 acaba de comenzar.

Licencia y normas de distribucinEl equipo de traduccin ha seguido al pi de la letra las directrices marcadas por Bruce Eckel (autor del libro original) para la realizacin de traducciones y distribucin de stas. Si utiliza o distribuye este texto debe cumplirlas y advertir de su existencia a los posibles lectores. El equipo de traduccin elude toda responsabilidad por la violacin -por parte de terceros- de las citadas directrices2 . Se incluyen a continuacin respetando el idioma original (para evitar eventuales interpretaciones incorrectas): In my contract with the publisher, I maintain all electronic publishing rights to the book, including translation into foreign languages. This means that the publisher still handles negotiations for translations that are printed (and I have nothing directly to do with that) but I may grant translation rights for electronic versions of the book. I have been granting such rights for open-source style translation projects. (Note that I still maintain the copyright on my material.) That is: You must provide a web site or other medium whereby people may participate in the project (two easy possibilities are http://www.egroups.com or http://www.topica.com). You must maintain a downloadable version of the partially or fully translated version of the book. Someone must be responsible for the organization of the translation (I cannot be actively involved - I dont have the time). There should only be one language translation project for each book. We dont have the resources for a fork. As in an open-source project, there must be a way to pass responsibility to someone else if the rst person becomes too busy. The book must be freely distributable. The book may be mirrored on other sites. Names of the translators should be included in the translated book.1 http://arco.esi.uclm.es/~david.villa/pensarC++.html 2

El texto original de estas directrices est accesible en la pgina web del autor.

17

ndice de tablas

El proyecto de traduccinSi desea saber ms sobre este proyecto visite http://arco.inf-cr.uclm.es/~david.villa/pensarC++.html.

TecnicismosSe han traducido la mayor parte de los trminos especcos tanto de orientacin a objetos como de programacin en general. Para evitar confusiones o ambigedades a los lectores que manejen literatura en ingls hemos incluido entre parntesis el trmino original la primera vez que aparece traducido. Para traducir tecnicismos especialmente complicados hemos utilizado como referencia la segunda edicin de El lenguaje de Programacin C++ (en castellano) as como la Wikipedia. En contadas ocasiones se ha mantenido el trmino original en ingls. En benecio de la legibilidad, hemos preferido no hacer traducciones demasiado forzadas ni utilizar expresiones que pudieran resultar desconocidas en el argot o en los libros especializados disponibles en castellano. Nuestro propsito es tener un libro que pueda ser comprendido por hispano-hablantes. Es a todas luces imposible realizar una traduccin rigurosa acorde con las normas lingsticas de la RAE, puesto que, en algunos casos, el autor incluso utiliza palabras de su propia invencin.

Cdigo fuentePor hacer

ProduccinEl texto ha sido escrito en el lenguaje de marcado DocBook versin 4.3 en su variante XML. Cada captulo est contenido en un chero independiente y todos ellos se incluyen en un chero maestro utilizando XInclude. Debido a que muchos procesadores de DocBook no soportan adecuadamente la caracterstica XInclude, se usa la herramienta xsltproc para generar un nico chero XML que contiene el texto de todo el libro.

Cdigo fuenteTambin se utiliza XInclude para aadir en su lugar el contenido de los cheros de cdigo fuente escritos en C++. De ese modo, el texto de los listados que aparecen en el libro es idntico a los cheros C++ que distribuye el autor. De ese modo, la edicin es mucha ms limpia y sobretodo se evitan posibles errores de transcripcin de los listados. Utilizando un pequeo programa escrito en lenguaje Python3 , se substituyen los nombres etiquetados de los cheros por la sentencia XInclude correscpondiente://: V1C02:Hello.cpp

pasa a ser:

Una ver realizada esta substitucin, se utiliza de nuevo xsltproc para montar tanto el texto como los listados en un nico chero XML.

3

./utils/x_includes.py

18

ndice de tablas

Esquemas y diagramas Generacin de productosA partir del documento completo se generan dos resultados distintos; Una pgina web en XHTML utilizando un chero diferente para cada seccin de cada captulo. Automticamente se generan enlaces para navegar el documento y tablas de contenidos. Para ello se utiliza tambin la herramienta xsltproc aplicando las hojas de estilo XSLT del proyecto de documentacin del programa The Gimp, que tienen licencia GPL. Para el coloreado de los listados de cdigo fuente se ha utilizado el programa highlight. Para ello, un pequeo programa Python marca los listados para su extracin, a continuacin se colorean y por ltimo se vuelven a insertar en la pgina HTML. Un documento en formato PDF utilizando la aplicacin dblatex, Ha sido necesario crear una hoja de estilo especcamente para manipular el formato de pgina, ttulos e indices. Para el resalte de sintxis de los listados se ha utilizado el paquete LaTeX listings.

El equipoLas siguientes personas han colaborado en mayor o menor medida en algn momento desde el comienzo del proyecto de traduccin de Pensar en C++: David Villa Alises (coordinador) dvilla#gmx.net Mguel ngel Garca miguelangel.garcia#gmail.com Javier Corrales Garca jcg#damir.iem.csic.es Brbara Teruggi bwire.red#gmail.com Sebastin Gurin Gloria Barbern Gonzlez globargon#gmail.com Fernando Perfumo Velzquez nperfumo#telefonica.net Jos Mara Gmez josemaria.gomez#gmail.com David Martnez Moreno ender#debian.org Cristbal Tello ctg#tinet.org Jess Lpez Mollo (pre-Lucas) Jos Mara Requena Lpez (pre-Lucas) Javier Fenoll Rejas (pre-Lucas)

AgradecimientosPor hacer

19

PrefacioComo cualquier lenguaje humano, C++ proporciona mtodos para expresar conceptos. Si se utiliza de forma correcta, este medio de expresin ser signicativamente ms sencillo y exible que otras alternativas cuando los problemas aumentan en tamao y complejidad.

No se puede ver C++ slo como un conjunto de caractersticas, ya que algunas de esas caractersticas no tienen sentido por separado. Slo se puede utilizar la suma de las partes si se est pensando en el diseo, no slo en el cdigo. Y para entender C++ de esta forma, se deben comprender los problemas existentes con C y con la programacin en general. Este libro trata los problemas de programacin, porque son problemas, y el enfoque que tiene C++ para solucionarlos. Adems, el conjunto de caractersticas que explico en cada captulo se basar en la forma en que yo veo un tipo de problema en particular y cmo resolverlo con el lenguaje. De esta forma espero llevar al lector, poco a poco, de entender C al punto en el que C++ se convierta en su propia lengua. Durante todo el libro, mi actitud ser pensar que el lector desea construir en su cabeza un modelo que le permita comprender el lenguaje bajando hasta sus races; si se tropieza con un rompecabezas, ser capaz de compararlo con su modelo mental y deducir la respuesta. Tratar de comunicarle las percepciones que han reorientado mi cerebro para Pensar en C++.

Material nuevo en la segunda edicinEste libro es una minuciosa reescritura de la primera edicin para reejar todos los cambios que han aparecido en C++ tras la nalizacin del estndar que lo rige, y tambin para reejar lo que he aprendido desde que escrib la primera edicin. He examinado y reescrito el texto completo, en ocasiones quitando viejos ejemplos, a veces cambindolos, y tambin aadiendo muchos ejercicios nuevos. La reorganizacin y reordenacin del material tuvo lugar para reejar la disponibilidad de mejores herramientas, as como mi mejor comprensin de cmo la gente aprende C++. He aadido un nuevo captulo, como introduccin al resto del libro, una introduccin rpida a los conceptos de C y a las caractersticas bsicas de C++ para aquellos que no tienen experiencia en C. El CD-ROM incluido al nal del libro en la edicin en papel contiene un seminario: una introduccin an ms ligera a los conceptos de C necesarios para comprender C++ (o Java). Chuck Allison lo escribi para mi empresa (MindView, Inc.), y se llama Pensar en C: conceptos bsicos de Java y C++. Presenta los aspectos de C que necesita conocer para poder cambiar a C++ o Java, abandonando los desagradables bits de bajo nivel con los que los programadores de C tratan a diario, pero que lenguajes como C++ y Java mantienen lejos (o incluso eliminan, en el caso de Java). As que la respuesta corta a la pregunta Qu es diferente en la segunda edicin? sera que aquello que no es completamente nuevo se ha reescrito, a veces hasta el punto en el que no podra reconocer los ejemplos y el material original de la primera edicin.

Qu contiene el volumen 2 de este libro?Con la conclusin del estndar de C++ tambin se aadieron algunas importantes bibliotecas nuevas, tales como string y los contenedores, y algoritmos de la Librera Estndar C++, y tambin se ha aadido complejidad a las plantillas. stos y otros temas ms avanzados se han relegado al volumen 2 de este libro, incluyendo asuntos como la herencia mltiple, el manejo de excepciones, patrones de diseo, y material sobre la creacin y depuracin de sistemas estables. 21

ndice de tablas

Cmo obtener el volumen 2Del mismo modo que el libro que lee en estos momentos, Pensar en C++, Volumen 2 se puede descargar desde mi sitio web www.BruceEckel.com. Puede encontrar informacin en el sitio web sobre la fecha prevista para la impresin del Volumen 2. El sitio web tambin contiene el cdigo fuente de los listados para ambos libros, junto con actualizaciones e informacin sobre otros seminarios en CD-ROM que ofrece MidView Inc., seminarios pblicos y formacin interna, consultas, soporte y asistentes paso a paso.

RequisitosEn la primera edicin de este libro, decid suponer que otra persona ya le haba enseado C y que el lector tena, al menos, un nivel aceptable de lectura del mismo. Mi primera intencin fue hablar de lo que me result difcil: el lenguaje C++. En esta edicin he aadido un captulo como introduccin rpida a C, acompaada del seminario en-CD Thinking in C, pero sigo asumiendo que el lector tiene algn tipo de experiencia en programacin. Adems, del mismo modo que se aprenden muchas palabras nuevas intuitivamente, vindolas en el contexto de una novela, es posible aprender mucho sobre C por el contexto en el que se utiliza en el resto del libro.

Aprender C++Yo me adentr en C++ exactamente desde la misma posicin en la que espero que se encuentren muchos de los lectores de este libro: como un programador con una actitud muy sensata y con muchos vicios de programacin. Peor an, mi experiencia era sobre porgramacin de sistemas empotrados a nivel hardware, en la que a veces se considera a C como un lenguaje de alto nivel y excesivamente ineciente para ahorrar bits. Descubr ms tarde que nunca haba sido un buen programador en C, camuando as mi ignorancia sobre estructuras, malloc() y free(), setjmp() y longimp(), y otros conceptos sosticados, y murindome de vergenza cuando estos trminos entraban en una conversacin, en lugar de investigar su utilidad. Cuando comenc mi lucha por aprender C++, el nico libro decente era la auto-proclamada Gua de expertos de Bjarne Stroustrup 4 as que simpliqu los conceptos bsicos por m mismo. Esto se acab convirtiendo en mi primer libro de C++ 5 , que es esencialmente un reejo de mi experiencia. Fue descrita como una gua de lectura para atraer a los programadores a C y C++ al mismo tiempo. Ambas ediciones 6 del libro consiguieron una respuesta entusiasta. Ms o menos al mismo tiempo que apareca Using C++, comenc a ensear el lenguaje en seminarios y presentaciones. Ensear C++ (y ms tarde, Java) se convirti en mi profesin; llevo viendo cabezas asintiendo, caras plidas, y expresiones de perplejidad en audiencias por todo el mundo desde 1989. Cuando comenc a dar formacin interna a grupos ms pequeos, descubr algo durante los ejercicios. Incluso aquella gente que estaba sonriendo y asintiendo se encontraba equivocada en muchos aspectos. Creando y dirigiendo las pruebas de C++ y Java durante muchos aos en la Conferencia de Desarrollo de Software, descubr que tanto otros oradores como yo tendamos a tocar demasiados temas, y todo demasiado rpido. As que, de vez en cuando, a pesar de la variedad del nivel de la audiencia e independientemente de la forma en que se presentara el material, terminara perdiendo alguna parte de mi pblico. Quiz sea pedir demasiado, pero como soy una de esas personas que se resisten a una conferencia tradicional (y para la mayora de las personas, creo, esta resistencia est causada por el aburrimiento), quise intentar mantener a cada uno a su velocidad. Durante un tiempo, estuve haciendo presentaciones en orden secuencial. De ese modo, termin por aprender experimentando e iterando (una tcnica que tambin funciona bien en el diseo de programas en C++). Al nal, desarroll un curso usando todo lo que haba aprendido de mi experiencia en la enseanza. As, el aprendizaje se realiza en pequeos pasos, fciles de digerir, y de cara a un seminario prctico (la situacin ideal para el aprendizaje) hay ejercicios al nal de cada presentacin. Puede encontrar mis seminarios pblicos en www.BruceEckel.com, y tambin puede aprender de los seminarios que he pasado a CD-ROM. La primera edicin de este libro se gest a lo largo de dos aos, y el material de este libro se ha usado de muchas4 5 6

Bjarne Stroustrup, The C++ Programming Language, Addison-Wesley, 1986 (rst edition). Using C++, Osborne/McGraw-Hill 1989. Using C++ and C++ Inside & Out, Osborne/McGraw-Hill 1993.

22

ndice de tablas formas y en muchos seminarios diferentes. Las reacciones que he percibido de cada seminario me han ayudado a cambiar y reorientar el material hasta que he comprobado que funciona bien como un medio de enseanza. Pero no es slo un manual para dar seminarios; he tratado de recopilar tanta informacin como he podido en estas pginas, intentando estructurarlas para atraer al lector hasta la siguiente materia. Ms que nada, el libro est diseado para servir al lector solitario que lucha con un lenguaje de programacin nuevo.

ObjetivosMis objetivos en este libro son: 1. Presentar el material paso a paso, de manera que el lector pueda digerir cada concepto fcilmente antes de continuar. 2. Usar ejemplos tan simples y cortos como sea posible. Esto a veces me impide manejar problemas del mundo real, pero he descubierto que los principiantes normalmente quedan ms contentos cuando pueden comprender cada detalle de un ejemplo que siendo impresionados por el mbito del problema que soluciona. Adems, hay un lmite en la cantidad de cdigo que se puede asimilar en una clase. Por ello, a veces recibo crticas por usar ejemplos de juguete, pero tengo la buena voluntad de aceptarlas en favor de producir algo pedaggicamente til. 3. La cuidadosa presentacin secuencial de capacidades para que no se vea algo que no ha sido explicado. De acuerdo, esto no siempre es posible; en esos casos, se ofrece una breve descripcin introductoria. 4. Indicarle lo que creo que es importante para que se comprenda el lenguaje, ms que todo lo que s. Creo que hay una "jerarqua de la importancia de la informacin", y hay algunos hechos que el 95 por ciento de los programadores nunca necesitar saber y que slo podran confundirles y aanzar su percepcin de la complejidad del lenguaje. Tomando un ejemplo de C, si memoriza la tabla de precedencia de los operadores (yo nunca lo hice), puede escribir cdigo ms corto. Pero si lo piensa, esto confundir al lector/mantenedor de ese cdigo. As que olvide la precedencia, y utilice parntesis cuando las cosas no estn claras. Esta misma actitud la utilizar con alguna otra informacin del lenguaje C++, que creo que es ms importante para escritores de compiladores que para programadores. 5. Mantener cada seccin sucientemente enfocada como para que el tiempo de lectura -y el tiempo entre bloques de ejercicios- sea razonable. Eso mantiene las mentes de la audiencia ms activas e involucradas durante un seminario prctico, y adems le da al lector una mayor sensacin de avance. 6. Ofrecer a los lectores una base slida de manera que puedan comprender las cuestiones lo sucientemente bien como para pasar a otros cursos y libros ms difciles (en concreto, el Volumen 2 de este libro). 7. He tratado de no utilizar ninguna versin de C++ de ningn proveedor en particular porque, para aprender el lenguaje, no creo que los detalles de una implementacin concreta sean tan importantes como el lenguaje mismo. La documentacin sobre las especicaciones de implementacin propia de cada proveedor suele ser adecuada.

CaptulosC++ es un lenguaje en el que se construyen caractersticas nuevas y diferentes sobre una sintaxis existente (por esta razn, nos referiremos a l como un lenguaje de programacin orientado a objetos hbrido). Como mucha gente pasa por una curva de aprendizaje, hemos comenzado por adaptarnos a la forma en que los programadores pasan por las etapas de las cualidades del lenguaje C++. Como parece que la progresin natural es la de una mente entrenada de forma procedural, he decidido comprender y seguir el mismo camino y acelerar el proceso proponiendo y resolviendo las preguntas que se me ocurrieron cuando yo aprenda el lenguaje y tambin las que se les ocurrieron a la gente a la que lo enseaba. El curso fue diseado con algo en mente: hacer ms eciente el proceso de aprender C++. La reaccin de la audiencia me ayud a comprender qu partes eran difciles y necesitaban una aclaracin extra. En las reas en las que me volva ambicioso e inclua demasiadas cosas de una vez, me d cuenta -mediante la presentacin de material- de que si incluyes demasiadas caractersticas, tendrs que explicarlas todas, y es fcil que la confusin de los estudiantes se agrave. Como resultado, he tenido muchos problemas para introducir las caractersticas tan lentamente como ha sido posible; idealmente, slo un concepto importante a la vez por captulo. 23

ndice de tablas As pues, el objetivo en cada captulo es ensear un concepto simple, o un pequeo grupo de conceptos asociados, en caso de que no haya ms conceptos adicionales. De esa forma puede digerir cada parte en el contexto de su conocimiento actual antes de continuar. Para llevarlo a cabo, dej algunas partes de C para ms adelante de lo que me hubiese gustado. La ventaja es que se evita la confusin al no ver todas las caractersticas de C++ antes de que stas sean explicadas, as su introduccin al lenguaje ser tranquila y reejar la forma en que asimile las caractersticas que dejo en sus manos. He aqu una breve descripcin de los captulos que contiene este libro: Captulo 1: Introduccin a los objetos. Cuando los proyectos se vuelven demasiado grandes y difciles de mantener, nace la crisis del software, que es cuando los programadores dicen: No podemos terminar los proyectos, y cuando podemos, son demasiado caros!. Eso provoc gran cantidad de reacciones, que se discuten en este captulo mediante las ideas de Programacin Orientada a Objetos (POO) y cmo intenta sta resolver la crisis del software. El captulo le lleva a travs de las caractersticas y conceptos bsicos de la POO y tambin introduce los procesos de anlisis y diseo. Adems, aprender acerca de los benecios y problemas de adaptar el lenguaje, y obtendr sugerencias para adentrarse en el mundo de C++. Captulo 2: Crear y usar objetos. Este captulo explica el proceso de construir programas usando compiladores y libreras. Presenta el primer programa C++ del libro y muestra cmo se construyen y compilan los programas. Despus se presentan algunas de las libreras de objetos bsicas disponibles en C++ Estndar. Para cuando acabe el captulo, dominar lo que se reere a escribir un programa C++ utilizando las libreras de objetos predenidas. Captulo 3: El C de C++. Este captulo es una densa vista general de las caractersticas de C que se utilizan en C++, as como gran nmero de caractersticas bsicas que slo estn disponibles en C++. Adems introduce la utilidad make, que es habitual en el desarrollo software de todo el mundo y que se utiliza para construir todos los ejemplos de este libro (el cdigo fuente de los listados de este libro, que est disponible en www.BruceEckel.com, contiene los makefiles correspondientes a cada captulo). En el captulo 3 supongo que el lector tiene unos conocimientos bsicos slidos en algn lenguaje de programacin procedural como Pascal, C, o incluso algn tipo de Basic (basta con que haya escrito algo de cdigo en ese lenguaje, especialmente funciones). Si encuentra este captulo demasiado difcil, debera mirar primero el seminario Pensar en C del CD que acompaa este libro (tambin disponible en www.BruceEckel.com). Captulo 4: Abstraccin de datos. La mayor parte de las caractersticas de C++ giran entorno a la capacidad de crear nuevos tipos de datos. Esto no slo ofrece una mayor organizacin del cdigo, tambin es la base preliminar para las capacidades de POO ms poderosas. Ver cmo esta idea es posible por el simple hecho de poner funciones dentro de las estructuras, los detalles de cmo hacerlo, y qu tipo de cdigo se escribe. Tambin aprender la mejor manera de organizar su cdigo mediante archivos de cabecera y archivos de implementacin. Captulo 5: Ocultar la implementacin. El programador puede decidir que algunos de los datos y funciones de su estructura no estn disponibles para el usuario del nuevo tipo hacindolas privadas. Eso signica que se puede separar la implementacin principal de la interfaz que ve el programador cliente, y de este modo permitir que la implementacin se pueda cambiar fcilmente sin afectar al cdigo del cliente. La palabra clave class tambin se presenta como una manera ms elaborada de describir un tipo de datos nuevo, y se desmitica el signicado de la palabra objeto (es una variable elaborada). Captulo 6: Inicializacin y limpieza. Uno de los errores ms comunes en C se debe a las variables no inicializadas. El constructor de C++ permite garantizar que las variables de su nuevo tipo de datos (objetos de su clase) siempre se inicializarn correctamente. Si sus objetos tambin requieren algn tipo de reciclado, usted puede garantizar que ese reciclado se realice siempre mediante el destructor C++. Captulo 7: Sobrecarga de funciones y argumentos por defecto. C++ est pensado para ayudar a construir proyectos grandes y complejos. Mientras lo hace, puede dar lugar a mltiples libreras que utilicen el mismo nombre de funcin, y tambin puede decidir utilizar un mismo nombre con diferentes signicados en la misma biblioteca. Con C++ es sencillo gracias a la sobrecarga de funciones, lo que le permite reutilizar el mismo nombre de funcin siempre que la lista de argumentos sea diferente. Los argumentos por defecto le permiten llamar a la misma funcin de diferentes maneras proporcionando, automticamente, valores por defecto para algunos de sus argumentos. Captulo 8: Constantes. Este captulo cubre las palabras reservadas const y volatile, que en C++ tienen un signicado adicional, especialmente dentro de las clases. Aprender lo que signica aplicar const a una denicin de puntero. El captulo tambin muestra cmo vara el signicado de const segn se utilice dentro o fuera de las clases y cmo crear constantes dentro de clases en tiempo de compilacin. Captulo 9: Funciones inline. Las macros del preprocesador eliminan la sobrecarga de llamada a funcin, pero el preprocesador tambin elimina la valiosa comprobacin de tipos de C++. La funcin inline le ofrece todos

24

ndice de tablas los benecios de una macro de preprocesador adems de los benecios de una verdadera llamada a funcin. Este captulo explora minuciosamente la implementacin y uso de las funciones inline. Captulo 10: Control de nombres. La eleccin de nombres es una actividad fundamental en la programacin y, cuando un proyecto se vuelve grande, el nmero de nombres puede ser arrollador. C++ le permite un gran control de los nombres en funcin de su creacin, visibilidad, lugar de almacenamiento y enlazado. Este captulo muestra cmo se controlan los nombres en C++ utilizando dos tcnicas. Primero, la palabra reservada static se utiliza para controlar la visibilidad y enlazado, y se explora su signicado especial para clases. Una tcnica mucho ms til para controlar los nombres a nivel global es el namespace de C++, que le permite dividir el espacio de nombres global en distintas regiones. Captulo 11: Las referencias y el constructor de copia. Los punteros de C++ trabajan como los punteros de C con el benecio adicional de la comprobacin de tipos ms fuerte de C++. C++ tambin proporciona un mtodo adicional para manejar direcciones: C++ imita la referencia de Algol y Pascal, que permite al compilador manipular las direcciones, pero utilizando la notacin ordinaria. Tambin encontrar el constructor-de-copia, que controla la manera en que los objetos se pasan por valor hacia o desde las funciones. Finalmente, se explica el puntero-a-miembro de C++. Captulo 12: Sobrecarga de operadores. Esta caracterstica se llama algunas veces azcar sintctico; permite dulcicar la sintaxis de uso de su tipo permitiendo operadores as como llamadas a funciones. En este captulo aprender que la sobrecarga de operadores slo es un tipo de llamada a funcin diferente y aprender cmo escribir sus propios operadores, manejando el -a veces confuso- uso de los argumentos, devolviendo tipos, y la decisin de si implementar el operador como mtodo o funcin amiga. Captulo 13: Creacin dinmica de objetos. Cuntos aviones necesitar manejar un sistema de trco areo? Cuntas guras requerir un sistema CAD? En el problema de la programacin genrica, no se puede saber la cantidad, tiempo de vida o el tipo de los objetos que necesitar el programa una vez lanzado. En este captulo aprender cmo new y delete solventan de modo elegante este problema en C++ creando objetos en el montn. Tambin ver cmo new y delete se pueden sobrecargar de varias maneras, de forma que puedan controlar cmo se asigna y se recupera el espacio de almacenamiento. Captulo 14: Herencia y composicin. La abstraccin de datos le permite crear tipos nuevos de la nada, pero con composicin y herencia, se puede crear tipos nuevos a partir de los ya existentes. Con la composicin, se puede ensamblar un tipo nuevo utilizando otros tipos como piezas y, con la herencia, puede crear una versin ms especca de un tipo existente. En este captulo aprender la sintaxis, cmo redenir funciones y la importancia de la construccin y destruccin para la herencia y la composicin. Captulo 15: Polimorsmo y funciones virtuales. Por su cuenta, podra llevarle nueve meses descubrir y comprender esta piedra angular de la POO. A travs de ejercicios pequeos y simples, ver cmo crear una familia de tipos con herencia y manipular objetos de esa familia mediante su clase base comn. La palabra reservada virtual le permite tratar todos los objetos de su familia de forma genrica, lo que signica que el grueso del cdigo no depende de informacin de tipo especca. Esto hace extensibles sus programas, de manera que construir programas y mantener el cdigo sea ms sencillo y ms barato. Captulo 16: Introduccin a las plantillas. La herencia y la composicin permiten reutilizar el cdigo objeto, pero eso no resuelve todas las necesidades de reutilizacin. Las plantillas permiten reutilizar el cdigo fuente proporcionando al compilador un medio para sustituir el nombre de tipo en el cuerpo de una clase o funcin. Esto da soporte al uso de bibliotecas de clase contenedor, que son herramientas importantes para el desarrollo rpido y robusto de programas orientados a objetos (la Biblioteca Estndar de C++ incluye una biblioteca signicativa de clases contenedor). Este captulo ofrece una profunda base en este tema esencial. Temas adicionales (y materias ms avanzadas) estn disponibles en el Volumen 2 del libro, que se puede descargar del sitio web www.BruceEckel.com.

EjerciciosHe descubierto que los ejercicios son excepcionalmente tiles durante un seminario para completar la comprensin de los estudiantes, as que encontrar algunos al nal de cada captulo. El nmero de ejercicios ha aumentado enormemente respecto a la primera edicin. Muchos de los ejercicios son sucientemente sencillos como para que puedan terminarse en una cantidad de tiempo razonable en una clase o apartado de laboratorio mientras el profesor observa, asegurndose de que todos los estudiantes asimilan el material. Algunos ejercicios son un poco ms complejos para mantener entretenidos a los estudiantes avanzados. El grueso de los ejercicios estn orientados para ser resueltos en poco tiempo y se 25

ndice de tablas intenta slo probar y pulir sus conocimientos ms que presentar retos importantes (seguramente ya los encontrar por su cuenta -o mejor dicho-, ellos lo encontrarn a usted).

Soluciones a los ejerciciosLas soluciones a los ejercicios seleccionados pueden encontrarse en el documento electrnico El Solucionario de Pensar en C++, disponible por una pequea cantidad en www.BruceEckel.com.

Cdigo fuenteEl cdigo fuente de los listados de este libro est registrado como freeware, distribuido mediante el sitio Web www.BruceEckel.com. El copyright le impide publicar el cdigo en un medio impreso sin permiso, pero se le otorga el derecho de usarlo de muchas otras maneras (ver ms abajo). El cdigo est disponible en un chero comprimido, destinado a extraerse desde cualquier plataforma que tenga una utilidad zip (puede buscar en Internet para encontrar una versin para su platarforma si an no tiene una instalada). En el directorio inicial donde desempaquete el cdigo encontrar la siguiente nota de registro:Copyright (c) 2000, Bruce Eckel Source code file from the book "Thinking in C++" All rights reserved EXCEPT as allowed by the following statements: You can freely use this file for your own work (personal or commercial), including modifications and distribution in executable form only. Permission is granted to use this file in classroom situations, including its use in presentation materials, as long as the book "Thinking in C++" is cited as the source. Except in classroom situations, you cannot copy and distribute this code; instead, the sole distribution point is http://www.BruceEckel.com (and official mirror sites) where it is available for free. You cannot remove this copyright and notice. You cannot distribute modified versions of the source code in this package. You cannot use this file in printed media without the express permission of the author. Bruce Eckel makes no representation about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty of any kind, including any implied warranty of merchantability, fitness for a particular purpose, or non-infringement. The entire risk as to the quality and performance of the software is with you. Bruce Eckel and the publisher shall not be liable for any damages suffered by you or any third party as a result of using or distributing this software. In no event will Bruce Eckel or the publisher be liable for any lost revenue, profit, or data, or for direct, indirect, special, consequential, incidental, or punitive damages, however caused and regardless of the theory of liability, arising out of the use of or inability to use software, even if Bruce Eckel and the publisher have been advised of the possibility of such damages. Should the software prove defective, you assume the cost of all necessary servicing, repair, or correction. If you think youve found an error, please submit the correction using the form you will find at www.BruceEckel.com. (Please use the same form for non-code errors found in the book.)

26

ndice de tablas

Se puede usar el cdigo en proyectos y clases siempre y cuando se mantenga la nota de copyright.

Estndares del lenguajeDurante todo el libro, cuando se haga referencia al estndar de C ISO, generalmente se dir C. Slo si se necesita distinguir entre C estndar y otros ms viejos, versiones previas al estndar de C, se har una distincin. Cuando se escribi este libro, el Comit de Estndares de C++ ya haba terminado de trabajar en el lenguaje. Por eso, se usar el trmino C++ Estndar para referirse al lenguaje estandarizado. Si se hace referencia simplemente a C++, debera asumir que se quiere decir C++ Estndar. Hay alguna confusin sobre el nombre real del Comit de Estndares de C++ y el nombre del estndar mismo. Steve Clamage, el presidente del comit, claric esto: Hay dos comits de estandarizacin de C++: El comit NCITS (antiguamente X3) J16 y el comit ISO JTC1/SC22/WG14. ANSI alquila NCITS para crear comits tcnicos para desarrollar estndares nacionales americanos. J16 fue alquilado en 1989 para crear un estndar americano para C++. Por el ao 1991 se alquil WG14 para crear un estndar internacional. El proyecto J16 se convirti en un proyecto Tipo I (Internacional) y se subordin al esfuerzo de estandarizacin de ISO. Los dos comits se encontraban al mismo tiempo en el mismo sitio, y el voto de J16 constituye el voto americano con WG14. WG14 delega el trabajo tcnico a J16. WG14 vota por el trabajo tcnico de J16. El estndar de C++ fue creado originalmente como un estndar ISO. ANSI vot ms tarde (como recomendaba J16) para adoptar el estndar de C++ ISO como el estndar americano para C++. Por eso, ISO es la forma correcta de referirse al Estndar C++.

Soporte del lenguajePuede que su compilador no disponga de todas las caractersticas discutidas en este libro, especialmente si no tiene la versin ms recente del compilador. Implementar un lenguaje como C++ es una tarea herclea, y puede esperar que las caractersticas aparecern poco a poco en lugar de todas a la vez. Pero si prueba uno de los ejemplos del libro y obtiene un montn de errores del compilador, no es necesariamente un error en el cdigo o en el compilador; simplemente puede no estar implementado an en su compilador particular.

El CD-ROM del libroEl contenido principal del CD-ROM empaquetado al nal de este libro es un seminario en CD-ROM titulado Pensar en C: Fundamentos para Java y C++ obra de Chuck Allison (publicado por MindView, Inc., y tambin disponible en www.BruceEckel.com). Contiene muchas horas de grabaciones y transparencias, que pueden mostrarse en la mayora de las computadoras que dispongan de lector de CD-ROM y sistema de sonido. El objetivo de Pensar en C es llevarle cuidadosamente a travs de los fundamentos del lenguaje C. Se centra en el conocimiento que necesita para poder pasarse a C++ o Java en lugar de intentar hacerle un experto en todos los recovecos de C (una de las razones de utilizar un lenguaje de alto nivel como C++ o Java es, precisamente, que se pueden evitar muchos de esos recovecos). Tambin contiene ejercicios y soluciones guiadas. Tngalo en cuenta porque el Captulo 3 de este libro va ms all del CD de Pensar en C, el CD no es una alternativa a este captulo, sino que debera utilizarse como preparacin para este libro. Por favor, tenga en cuenta que el CD-ROM est basado en navegador, por lo que debera tener un navegador Web instalado en su mquina antes de utilizarlo. 27

ndice de tablas

CD-ROMs, seminarios, y consultoraHay seminarios en CD-ROM planeados para cubrir el Volumen 1 y el Volumen 2 de este libro. Comprenden muchas horas de grabaciones mas que acompaan las transparencias que cubren el material seleccionado de cada captulo del libro. Se pueden ver en la mayora de las computadoras que disponen de lector de CDROM y sistema de sonido. Estos CDs pueden comprarse en www.BruceEckel.com, donde encontrar ms informacin y lecturas de ejemplo. Mi compaa, MindView, Inc., proporciona seminarios pblicos de preparacin prctica basados en el material de este libro y tambin en temas avanzados. El material seleccionado de cada captulo representa una leccin, que se contina con un periodo de ejercicios monitorizados para que cada estudiante reciba atencin personal. Tambin proporcionamos preparacin in situ, consultora, tutorizacin, diseo y asistentes de cdigo. Puede encontrar la informacin y los formularios para los prximos seminarios, as como otra informacin de contacto, en www.BruceEckel.com. A veces me encuentro disponible para consultas de diseo, evaluacin de procesos y asistencia. Cuando comenc a escribir sobre computadoras, mi motivacin principal fue incrementar mis actividades de consultora, porque encontraba que la consultora era competitiva, educacional, y una de mis experiencias profesionales ms valiosas. As que har todo lo que pueda para incluirle a usted en mi agenda, o para ofrecerle uno de mis socios (que son gente que conozco bien y con la que he tratado, y a menudo co-desarrollan e imparten seminarios conmigo).

ErroresNo importa cuntos trucos emplee un escritor para detectar los errores, algunos siempre se escapan y saltan del papel al lector atento. Si encuentra algo que crea que es un error, por favor, utilice el formulario de correcciones que encontrar en www.BruceEckel.com. Se agradece su ayuda.

Sobre la portadaLa primera edicin de este libro tena mi cara en la portada, pero para la segunda edicin yo quera desde el principio una portada que se pareciera ms una obra de arte, como la portada de Pensar en Java. Por alguna razn, C++ parece sugerirme Art Dec con sus curvas simples y pinceladas cromadas. Tena en mente algo como esos carteles de barcos y aviones con cuerpos largos. Mi amigo Daniel Will-Harris, (www.Will-Harris.com) a quien conoc en las clases del coro del instituto, iba a llegar a ser un diseador y escritor de talla mundial. l ha hecho prcticamente todos mis diseos, includa la portada para la primera edicin de este libro. Durante el proceso de diseo de la portada, Daniel, insatisfecho con el progreso que realizbamos, siempre preguntaba: Qu relacin hay entre las personas y las computadoras?. Estbamos atascados. Como capricho, sin nada en mente, me pidi que pusiera mi cara en el escner. Daniel tena uno de sus programas grcos (Corel Xara, su favorito) que autotraz mi cara escaneada. l lo describe de la siguente manera: El autotrazado es la forma en la que la computadora transforma un dibujo en los tipos de lneas y curvas que realmente le gustan. Entonces jug con ello hasta que obtuvo algo que pareca un map