¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
  1. Libros
  2. C++
  3. Programas C++ eficaces
Extrait - C++ De los fundamentos del lenguaje a las aplicaciones
Extractos del libro
C++ De los fundamentos del lenguaje a las aplicaciones Volver a la página de compra del libro

Programas C++ eficaces

Mejorar sus programas

1. Olvidar los actos reflejos del lenguaje C

Los programadores acostumbrados al lenguaje C, indudablemente han previsto muchas instrucciones macro procesadas por el preprocesador. Este es el caso especialmente de las constantes textuales y de las "funciones", que proporcionan muchos servicios.

Sin embargo, el lenguaje C++ ofrece alternativas que mejoran la seguridad del programa y su velocidad.

Las constantes definidas con la palabra clave const, en primer lugar, tienen la gran ventaja de ser verificadas por el compilador, no por el preprocesador. En caso de error (visibilidad, ortografía, etc.) el compilador puede darle al programador mucho más contexto.

Las funciones en línea (inline) permiten desarrollar instrucciones sin construir un marco de pila completo, con las consecuencias que esto puede tener en la transmisión de argumentos y en el rendimiento. Por supuesto, su implementación debe cumplir con algunas restricciones, pero sin duda usarlas tiene sus ventajas.

Consideremos el siguiente ejemplo, en el que se define una constante simbólica para el preprocesador. Si hay un error de escritura en el main, el compilador no tiene ninguna forma de precisar en qué archivo .h podría no coincidir. De manera similar, describimos en el capítulo De C a C++ una macro que compara dos enteros. Pero cuando se trata de una macro que repite uno de sus argumentos, notamos que aparecen efectos secundarios.

El siguiente ejemplo proporciona una alternativa a cada problema, basada en la sintaxis de C++, más segura y rápida:

#define TAMANIO 10 
#define COMP(a,b) (a-b>0?1:(a-b==0?0:-1)) 
 
const int tamanio = 10; 
inline int comp(int a,int b) 
{ 
    if(a-b>0) 
        return 1; 
    else 
    { 
        if(a==b) 
            return...

El diseño orientado a objetos (DOO)

1. Relación entre la POO y el DOO

El diseño de un programa orientado a objetos en C++ es una etapa que requiere cierta maduración. La esencia de tal programa no radica solo en la implementación de los algoritmos que contiene, sino también en la estructura de las clases y en las relaciones que las unen. En esta sección nos proponemos describir los enfoques de métodos relacionados con el diseño de programas C++.

a. El enfoque inicial de C++

En primer lugar, recordemos que C++ se creó para realizar aplicaciones destinadas al sector de las telecomunicaciones. Por tanto, este lenguaje no es solo un trabajo de investigación, sino que también es el resultado de un trabajo de ingeniería informática. Por supuesto, su diseñador Bjarne Stroustrup se aseguró de que fuera lo suficientemente general como para ser adaptado en otras situaciones. Para lograr este objetivo, diseñó tres elementos esenciales:

  • el propio lenguaje C ++;

  • la librería estándar STL;

  • un método de diseño orientado a objetos para C++.

Obviamente, el método propuesto por Bjarne Stroustrup se basa en su experiencia en el diseño de aplicaciones anterior a C++. Se basa en una serie de temas importantes, algunos de los cuales son clásicos de los métodos de diseño de software, orientados a objetos o no. Estos temas incluyen la delimitación del sistema, la complejidad de las aplicaciones respecto al grado de abstracción de las herramientas, o incluso los ciclos de diseño y programación percibidos como actividades iterativas.

El proceso de desarrollo mínimo consta de tres etapas:

  • análisis;

  • diseño;

  • implementación.

La etapa que nos ocupa es precisamente la del diseño. El autor del método organiza los subprocesos a partir del siguiente desglose:

  • identificación de clases, conceptos y sus relaciones más fundamentales;

  • especificación de operaciones, es decir, métodos;

  • especificación de las dependencias (cardinalidades como se diría en UML);

  • identificación de interfaces para las clases más importantes;

  • reorganización de la jerarquía de clases;

  • uso de modelos para perfeccionar el diagrama.

En conclusión, Bjarne Stroustrup...

Trabajos prácticos

Sin ser un fin en sí mismo, los designs patterns guían al desarrollador en el desarrollo de su programa, evitando que reinvente la rueda. El siguiente ejemplo ilustra el principio de separación de código por nivel de importancia (hablamos de "capas" de código) y se basa en el patrón de diseño Factory.

1. El objetivo del programa

Una clase de datos bastante simple, Libro contiene dos atributos autor y titulo.

El programa tiene una clase de service para listar libros de diferentes fuentes (llamadas DAO por data access object) como una base de datos, un archivo o una selección predefinida (en otras palabras, una lista codificada).

La función main() realiza dos llamadas a la clase de servicio, la primera para listar todos los libros del catálogo y la segunda para listar las obras filtradas por autor.

2. El diagrama de clases

Algunas clases se asocian con una clase de interfaz, que define el contrato funcional a través de una lista de métodos virtuales puros (también llamados métodos abstractos en C# o Java).

Esta construcción es bastante estándar respecto a la división de un programa en capas, y es aún más útil cuando entra en juego el patrón de diseño Factory.

images/cap6-pag16.png

Las clases de interfaces se representan como clases abstractas, ya que sus métodos no incluyen implementaciones (son métodos virtuales puros).

En C++, así es como se escribe esta asociación clase de interfaz - clase:

/* 
   clase de interfaz IlibroDAO 
   Solo contiene métodos virtuales puros (sin código) 
   No se puede instanciar tal cual sin implementación 
*/ 
class IlibroDAO 
{ 
public: 
   virtual vector<Libro>...