5. Capítulos

C++ es un lenguaje en el que se construyen características nuevas y diferentes sobre una sintaxis existente (por esta razón, nos referiremos a él como un lenguaje de programación orientado a objetos híbrido). 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 progresión 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 aprendía el lenguaje y también las que se les ocurrieron a la gente a la que 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 dí cuenta -mediante la presentación de material- de que si incluyes demasiadas características, tendrás que explicarlas todas, y es fácil que la confusión de los estudiantes se agrave. Como resultado, he tenido muchos problemas para introducir las características tan lentamente como ha sido posible; 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, en caso de que no haya más 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 más adelante de lo que me hubiese gustado. 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 asimile las características que dejo en sus manos.

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 mediante las ideas de 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 adaptar 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 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 (basta con que haya escrito algo de código en ese lenguaje, especialmente funciones). Si encuentra este capítulo demasiado difícil, debería mirar primero el seminario Pensar en 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 entorno 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 escribe. También aprenderá la mejor manera de organizar su código mediante archivos de cabecera y archivos 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éndolas privadas. Eso significa que se puede separar la implementación principal 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 clave 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 reciclado, usted puede garantizar que ese reciclado se realice siempre mediante el destructor C++.

Capítulo 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 múltiples 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 biblioteca. 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 dentro de clases en tiempo de compilación.

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 función de su creación, visibilidad, lugar de almacenamiento y enlazado. 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++ imita la referencia de Algol y Pascal, que permite al compilador manipular las direcciones, pero utilizando 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, devolviendo tipos, 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 de la programación genérica, 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 en el montón. También verá cómo new y delete se pueden sobrecargar de varias maneras, de forma que puedan controlar cómo se asigna y se recupera 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 puede 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 ejercicios 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 su 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 bibliotecas de clase contenedor, que son herramientas importantes para el desarrollo rápido y robusto de programas orientados a objetos (la Biblioteca Estándar de C++ incluye una biblioteca 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.