Los contenedores de la STL

La STL (Standard Template Library), diseñada por Alex Stepanov, es parte de la ISO C++ Standard Library. Es una colección de estructuras de datos llamadas contenedores, funciones para su manejo y algoritmos.

La STL nos permite introducir muy brevemente en este curso dos de los paradigmas de programación de C++ de los que aún no hemos hablado:

  • La programación orientada a objetos

  • La programación genérica

La programación orientada a objetos

Es un paradigma de programación que representa entidades software de forma análoga a como se hace en el mundo real.

Cuando observamos el mundo real vemos objetos que son de distintas clases.

Diferenciamos un león (un objeto) de un avión (otro objeto) porque son objetos de clases distintas. También distinguimos un Renault de un BMW pues, aunque son de la misma clase (automóvil), son objetos distintos.

Concepto de clase en C++

Una clase es un tipo de dato definido por un programador, compuesto por:

  • Atributos, un conjunto de datos relacionados entre sí, que permiten caracterizar el estado de un objeto cualquiera de esa clase.

  • Métodos, un conjunto de funciones miembro, que permiten modificar los datos de la clase (cambiar su estado), obtener información acerca de ellos, etc.

Concepto de objeto en C++

Un objeto es un área de memoria que durante la ejecución de un programa está provista de un contenido semántico.

Las clases son los planos que permiten crear objetos. Un objeto es una instancia concreta en memoria de una clase.

Los planos de una vivienda de un edificio serían la clase. La vivienda sita en la calle San Eustaquio, nº3, 5D, construida según los planos, sería un objeto.

Concepto de variable en C++

Una variable es el nombre con el que en un programa nos referimos a un objeto.

Ejemplo: después de definir double x; podemos decir que x es un objeto de tipo double.

La programación genérica

La Programación Orientada a Objetos (POO) está centrada en cómo organizar los datos usando objetos.

La programación genérica se centra en la generalización de los algoritmos: el mismo código debe servir para la mayor variedad posible de tipos de datos u objetos.

Veamos un ejemplo de lo que pretende evitar la Programación Genérica. Para cada tipo de dato fundamental, debemos definir una función distinta, aunque el algoritmo es idéntico.

Versión para int

Versión para double

void invertir_vector(int v[], int num)
{
    for (int i = 0; i < num/2; ++i)
    {
        int aux = v[i];
        v[i] = v[num-1-i];
        v[num-1-i] = aux;
    }
}
void invertir_vector(double v[], int num)
{
    for (int i = 0; i < num/2; ++i)
    {
        double aux = v[i];
        v[i] = v[num-1-i];
        v[num-1-i] = aux;
    }
}

Con herramientas de programación genérica, en C++ podríamos hacerlo con una única definición. Tendría el siguiente aspecto:

template <typename T>
void invertir_vector(T v[], int num)
{
  for (int i = 0; i < num/2; ++i)
  {
    T aux = v[i];
    v[i] = v[num-1-i];
    v[num-1-i] = aux;
  }
}

El parámetro T es una plantilla (template) que sirve para cualquiera tipo de dato. Lo único que debe hacer el programador es informar antes de compilar del tipo real de esa plantilla.

Los contenedores de la STL

Un contenedor de la STL es un objeto que almacena una colección de otros objetos, sus elementos, normalmente del mismo tipo.

Para implementar un contenedor se usa una clase genérica o plantilla (template), lo que, como hemos visto, permite definir en un sólo bloque de código diferentes clases que comparten un diseño común.

Un contenedor de la STL:

  • gestiona sus necesidades de almacenamiento

  • permite acceder de forma controlada a sus elementos individuales

  • conoce el número de elementos del contenedor

  • permite añadir o borrar de forma controlada nuevos elementos

Por su extraordinario interés y uso en C++, nos centraremos en el contenedor de la STL vector.