20/11/2023
La librería estándar de C++, en particular la clase vector, es una herramienta fundamental para el manejo de secuencias de datos. Comprender su funcionamiento interno es crucial para escribir código eficiente y evitar errores comunes. En este artículo, exploraremos a fondo la clase vector, sus miembros, y cómo optimizar su uso.

La Clase Vector: Un Contenedor de Secuencia
vectores una clase plantilla ( template class) que implementa un contenedor de secuencia dinámico. Esto significa que puede almacenar una colección de elementos del mismo tipo, y su tamaño se ajusta automáticamente a medida que se añaden o eliminan elementos. A diferencia de los arrays estáticos, los vectores no tienen un tamaño fijo en tiempo de compilación.
Sintaxis básica:
template <class Type, class Allocator = allocator<Type>> class vectorParámetros:
Type: El tipo de datos de los elementos que se almacenarán en el vector.Allocator(opcional): Un objeto que gestiona la asignación y liberación de memoria. Si se omite, se utiliza el asignador predeterminadoallocator<Type>.
Características Principales:
Una de las ventajas más significativas de vectores el acceso aleatorio a sus elementos en tiempo constante (O(1)). Esto significa que acceder a cualquier elemento del vector, independientemente de su posición, lleva el mismo tiempo. Sin embargo, las inserciones y eliminaciones en posiciones intermedias tienen un coste lineal (O(n)), ya que requieren desplazar los elementos subsiguientes.
Las inserciones y eliminaciones al final del vector son mucho más eficientes, con un coste constante (O(1)) en la mayoría de los casos. Sin embargo, cuando la capacidad del vector se llena, se produce una realocación, lo cual puede implicar copiar todos los elementos a un nuevo bloque de memoria de mayor tamaño, lo que resulta en un coste lineal.
Consideraciones de Rendimiento:
Es importante comprender que las operaciones de inserción y borrado en el medio de un vector pueden ser costosas, especialmente para vectores grandes. Si se realizan muchas inserciones o borrados en posiciones arbitrarias, se recomienda considerar el uso de otros contenedores como dequeo list, que ofrecen mayor eficiencia en estas situaciones.
Tabla comparativa de rendimiento:
| Operación | vector | deque | list |
|---|---|---|---|
| Acceso aleatorio | O(1) | O(1) | O(n) |
| Inserción al final | O(1) (amortiguado) | O(1) (amortiguado) | O(1) |
| Inserción al principio | O(n) | O(1) (amortiguado) | O(1) |
| Inserción en el medio | O(n) | O(n) | O(1) |
| Eliminación al final | O(1) | O(1) | O(1) |
| Eliminación al principio | O(n) | O(1) (amortiguado) | O(1) |
| Eliminación en el medio | O(n) | O(n) | O(1) |
Nota: O(1) amortiguado significa que la operación es constante en promedio, pero puede ser lineal en algunos casos debido a la reallocación.
Miembros de la Clase Vector
La clase vectorproporciona una amplia gama de miembros, incluyendo constructores, funciones miembro y operadores, para facilitar su manejo:
Constructores:
vectorofrece varios constructores para crear vectores con diferentes inicializaciones:
vector(): Crea un vector vacío.vector(size_type count): Crea un vector concountelementos con valores por defecto.vector(size_type count, const Type& value): Crea un vector concountelementos, todos inicializados con el valorvalue.vector(const vector& source): Crea una copia del vectorsource.vector(vector&& source): Mueve los datos del vectorsourceal nuevo vector.vector(initializer_list<Type> init_list): Crea un vector a partir de una lista de inicialización.
Funciones Miembro Importantes:
Algunas de las funciones miembro más utilizadas son:
push_back(value): Añade un elemento al final del vector.pop_back(): Elimina el último elemento del vector.insert(position, value): Inserta un elemento en una posición específica.erase(position): Borra un elemento en una posición específica.size(): Devuelve el número de elementos en el vector.empty(): Devuelvetruesi el vector está vacío,falseen caso contrario.at(index): Devuelve una referencia al elemento en la posiciónindex(lanza una excepción si el índice es inválido).operator[] (index): Devuelve una referencia al elemento en la posiciónindex(no realiza comprobaciones de límites).begin()yend(): Devuelven iteradores al principio y al final del vector respectivamente.reserve(count): Reserva espacio en memoria para al menoscountelementos.capacity(): Devuelve la cantidad de espacio en memoria actualmente reservado.resize(count): Cambia el tamaño del vector acountelementos.clear(): Elimina todos los elementos del vector.swap(other): Intercambia los contenidos de dos vectores.
Iteradores:
Los iteradores facilitan el recorrido de los elementos del vector. vectorproporciona iteradores de acceso aleatorio, lo que permite moverse eficientemente hacia adelante y hacia atrás en la secuencia.
Optimizando el Uso de Vectores
Para optimizar el rendimiento del código que utiliza vectores, se deben tener en cuenta las siguientes recomendaciones:
- Minimizar las inserciones y eliminaciones en el medio: Si es posible, realiza inserciones y eliminaciones al final del vector para mantener un rendimiento constante.
- Utilizar reserve(): Si se conoce de antemano el tamaño aproximado del vector, usar
reserve()puede evitar varias reallocaciones y mejorar el rendimiento. - Considerar otros contenedores: Para escenarios con muchas inserciones/eliminaciones en el medio,
dequeolistpueden ser más adecuados. - Evitar copias innecesarias: Utilizar referencias o punteros en lugar de copiar objetos grandes dentro del vector.
- Utilizar movimiento (move semantics): Cuando se pasan vectores a funciones, utilizar
std::movepara evitar copias innecesarias.
Ejemplos de Uso
A continuación, se muestran algunos ejemplos sencillos que ilustran el uso de la clase vector:
#include <iostream>#include <vector>int main() { std::vector<int> numeros; // Vector vacío numeros.push_back(10); numeros.push_back(20); numeros.push_back(30); std::cout << "Tamaño del vector: " << numeros.size() << std::endl; // Imprime 3 for (int i = 0; i < numeros.size(); ++i) { std::cout << numeros[i] << " "; // Imprime 10 20 30 } std::cout << std::endl; numeros.insert(numeros.begin() + 1, 15); // Inserta 15 en la posición 1 for (int numero : numeros) { std::cout << numero << " "; // Imprime 10 15 20 30 } std::cout << std::endl; numeros.erase(numeros.begin()); // Elimina el primer elemento for (int numero : numeros) { std::cout << numero << " "; // Imprime 15 20 30 } std::cout << std::endl; return 0;}Consultas habituales:
- ¿Cómo declarar un vector?
- ¿Cómo añadir elementos a un vector?
- ¿Cómo eliminar elementos de un vector?
- ¿Cómo acceder a un elemento de un vector?
- ¿Cuál es la diferencia entre
at()yoperator[]? - ¿Cómo optimizar el rendimiento de un vector?
- ¿Cuándo usar otros contenedores en lugar de un vector?
Este artículo proporciona una base sólida para comprender el funcionamiento de la librería vectoren C++. La práctica y la experiencia son clave para dominar su uso eficiente y aprovechar al máximo sus capacidades.
Si quieres conocer otros artículos parecidos a Cómo funciona la librería vector en c++ puedes visitar la categoría Libros y Librerías.
