C++ es un lenguaje en el que se construyen características nuevas y diferentes sobre una sintaxis existente (por esta razón, se dice que es un lenguaje de programación orientado a objetos híbrido). A medida que más gente supera la curva de aprendizaje, hemos empezado a hacernos una idea de la forma en que los programadores pasan por las etapas de las cualidades del lenguaje C++. Como parece ser la progresión natural de una mente formada en la programación procedural, he decidido comprender y seguir el mismo camino y acelerar el proceso proponiendo y resolviendo las preguntas que se me ocurrieron cuando yo aprendía el lenguaje y también las que me planteaba el público cuando lo enseñaba.
El curso fue diseñado con algo en mente: hacer más eficiente el proceso de aprender C++. La reacción de la audiencia me ayudó a comprender qué partes eran difíciles y necesitaban una aclaración extra. En las áreas en las que me volvía ambicioso e incluía demasiadas cosas de una vez, me di cuenta -mediante la presentación del material- de que si se incluyen muchas características nuevas, hay que explicarlas todas, y es fácil que la confusión de los estudiantes se agrave. Como resultado, me he esforzado mucho en introducir las características de pocas en pocas; idealmente, sólo un concepto importante a la vez por capítulo.
Así pues, el objetivo en cada capítulo es enseñar un concepto simple, o un pequeño grupo de conceptos asociados, de forma que no dependa de otras características adicionales. De esa forma puede digerir cada parte en el contexto de su conocimiento actual antes de continuar. Para llevarlo a cabo, mantengo algunas características de C durante más tiempo del que preferiría. La ventaja es que se evita la confusión al no ver todas las características de C++ antes de que éstas sean explicadas, así su introducción al lenguaje será tranquila y reflejará la forma en que asimilaría las características si lo hiciera por su cuenta.
He aquí una breve descripción de los capítulos que contiene este libro:
Capítulo 1: Introducción a los objetos. Cuando los proyectos se vuelven demasiado grandes y difíciles 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 capítulo junto con las ideas de la Programación Orientada a Objetos (POO) y cómo intenta ésta resolver la crisis del software. El capítulo le lleva a través de las características y conceptos básicos de la POO y también introduce los procesos de análisis y diseño. Además, aprenderá acerca de los beneficios y problemas de adoptar el lenguaje, y obtendrá sugerencias para adentrarse en el mundo de C++.
Capítulo 2: Crear y usar objetos. Este capítulo explica el proceso de construir programas usando compiladores y librerías. Presenta el primer programa C++ del libro y muestra cómo se construyen y compilan los programas. Después se presentan algunas de las librerías de objetos básicas disponibles en C++ Estándar. Para cuando acabe el capítulo, dominará lo que se refiere a escribir un programa C++ utilizando las librerías de objetos predefinidas.
Capítulo 3: El C de C++. Este capítulo es una densa vista general de las características de C que se utilizan en C++, así como gran número de características básicas que sólo están disponibles en C++. Además introduce la utilidad make, que es habitual en el desarrollo de software de todo el mundo y que se utiliza para construir todos los ejemplos de este libro (el código fuente de los listados de este libro, que está disponible en www.BruceEckel.com, contiene los makefiles correspondientes a cada capítulo). En el Capítulo 3 supongo que el lector tiene unos conocimientos básicos sólidos en algún lenguaje de programación procedural como Pascal, C, o incluso algún tipo de Basic (siempre que haya escrito mucho código en ese lenguaje, especialmente funciones). Si encuentra este capítulo demasiado difícil, debería mirar primero el seminario Thinking in C del CD que acompaña este libro (también disponible en www.BruceEckel.com).
Capítulo 4: Abstracción de datos. La mayor parte de las características de C++ giran en torno a la capacidad de crear nuevos tipos de datos. Esto no sólo ofrece una mayor organización del código, también es la base preliminar para las capacidades de POO más poderosas. Verá cómo esta idea es posible por el simple hecho de poner funciones dentro de las estructuras, los detalles de cómo hacerlo, y qué tipo de código se genera. También aprenderá la mejor manera de organizar su código mediante ficheros de cabecera y ficheros de implementación.
Capítulo 5: Ocultar la implementación. El programador puede decidir que algunos de los datos y funciones de su estructura no estén disponibles para el usuario del nuevo tipo haciéndolos privados. Eso significa que se puede separar la implementación subyacente de la interfaz que ve el programador cliente, y de este modo permitir que la implementación se pueda cambiar fácilmente sin afectar al código del cliente. La palabra reservada class también se presenta como una manera más elaborada de describir un tipo de datos nuevo, y se desmitifica el significado de la palabra «objeto» (es una variable elaborada).
Capítulo 6: Inicialización y limpieza. Uno de los errores más 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 inicializarán correctamente. Si sus objetos también requieren algún tipo de limpieza, usted puede garantizar que esa limpieza se realice siempre mediante el destructor de C++.
Capítulo 7: Sobrecarga de funciones y argumentos por defecto. C++ está pensado para ayudar a construir proyectos grandes y complejos. Al hacerlo, puede que tenga que incorporar varias librerías que utilicen el mismo nombre de función, y también puede decidir utilizar un mismo nombre con diferentes significados en la misma librería. Con C++ es sencillo gracias a la «sobrecarga de funciones», lo que le permite reutilizar el mismo nombre de función siempre que la lista de argumentos sea diferente. Los argumentos por defecto le permiten llamar a la misma función de diferentes maneras proporcionando, automáticamente, valores por defecto para algunos de sus argumentos.
Capítulo 8: Constantes. Este capítulo cubre las palabras reservadas const y volatile, que en C++ tienen un significado adicional, especialmente dentro de las clases. Aprenderá lo que significa aplicar const a una definición de puntero. El capítulo también muestra cómo varía el significado de const según se utilice dentro o fuera de las clases y cómo crear constantes en tiempo de compilación dentro de clases.
Capítulo 9: Funciones inline. Las macros del preprocesador eliminan la sobrecarga de llamada a función, pero el preprocesador también elimina la valiosa comprobación de tipos de C++. La función inline le ofrece todos los beneficios de una macro de preprocesador además de los beneficios de una verdadera llamada a función. Este capítulo explora minuciosamente la implementación y uso de las funciones inline.
Capítulo 10: Control de nombres. La elección de nombres es una actividad fundamental en la programación y, cuando un proyecto se vuelve grande, el número de nombres puede ser arrollador. C++ le permite un gran control de los nombres en cuanto a su creación, visibilidad, lugar de almacenamiento y enlazado[11]. Este capítulo muestra cómo se controlan los nombres en C++ utilizando dos técnicas. Primero, la palabra reservada static se utiliza para controlar la visibilidad y enlazado, y se explora su significado especial para clases. Una técnica mucho más ú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.
Capítulo 11: Las referencias y el constructor de copia. Los punteros de C++ trabajan como los punteros de C con el beneficio adicional de la comprobación de tipos más fuerte de C++. C++ también proporciona un método adicional para manejar direcciones: C++ toma prestada la referencia de Algol y Pascal, que permite al compilador manipular las direcciones, mientras usted utiliza la notación ordinaria. También 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++.
Capítulo 12: Sobrecarga de operadores. Esta característica se llama algunas veces «azúcar sintáctico»; permite dulcificar la sintaxis de uso de su tipo permitiendo operadores así como llamadas a funciones. En este capítulo aprenderá que la sobrecarga de operadores sólo es un tipo de llamada a función diferente y aprenderá cómo escribir sus propios operadores, manejando el -a veces confuso- uso de los argumentos, los tipos de retorno, y la decisión de si implementar el operador como método o función amiga.
Capítulo 13: Creación dinámica de
objetos. ¿Cuántos aviones necesitará manejar un sistema de tráfico aéreo? ¿Cuántas figuras requerirá un sistema CAD? En el problema general de la programación, no se puede saber la cantidad, tiempo de vida o el tipo de los objetos que necesitará el programa una vez lanzado. En este capítulo aprenderá cómo new y delete solventan de modo elegante este problema en C++ creando objetos de forma segura en el montículo. También verá cómo new y delete se pueden sobrecargar de varias maneras, de forma que pueda controlar cómo se asigna y se libera el espacio de almacenamiento.
Capítulo 14: Herencia y composición. La abstracción de datos le permite crear tipos nuevos de la nada, pero con composición y herencia, se pueden crear tipos nuevos a partir de los ya existentes. Con la composición, se puede ensamblar un tipo nuevo utilizando otros tipos como piezas y, con la herencia, puede crear una versión más específica de un tipo existente. En este capítulo aprenderá la sintaxis, cómo redefinir funciones y la importancia de la construcción y destrucción para la herencia y la composición.
Capítulo 15: Polimorfismo y
funciones virtuales. Por su cuenta, podría llevarle nueve meses descubrir y comprender esta piedra angular de la POO. A través de ejemplos pequeños y simples, verá cómo crear una familia de tipos con herencia y manipular objetos de esa familia mediante su clase base común. La palabra reservada virtual le permite tratar todos los objetos de esta familia de forma genérica, lo que significa que el grueso del código no depende de información de tipo específica. Esto hace extensibles sus programas, de manera que construir programas y mantener el código sea más sencillo y más barato.
Capítulo 16: Introducción a las plantillas. La herencia y la composición permiten reutilizar el código objeto, pero eso no resuelve todas las necesidades de reutilización. Las plantillas permiten reutilizar el código fuente proporcionando al compilador un medio para sustituir el nombre de tipo en el cuerpo de una clase o función. Esto da soporte al uso de librerías de clase contenedor, que son herramientas importantes para el desarrollo rápido y robusto de programas orientados a objetos (la Librería Estándar de C++ incluye una librería significativa de clases contenedor). Este capítulo ofrece una profunda base en este tema esencial.
Temas adicionales (y materias más avanzadas) están disponibles en el Volumen 2 del libro, que se puede descargar del sitio web www.BruceEckel.com.
[11] (N. del T.) En inglés, linkage: la propiedad de un nombre que determina si el enlazador lo comparte entre unidades de traducción (enlazado externo) o si sólo es visible en la suya (enlazado interno). En castellano coincide con la traducción de linking, el proceso que realiza el enlazador; el contexto permite distinguirlos. Se explica en el Capítulo 3.