<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="es">
	<id>https://www.ecured.cu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Majibacoa2+jc</id>
	<title>EcuRed - Contribuciones del colaborador [es]</title>
	<link rel="self" type="application/atom+xml" href="https://www.ecured.cu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Majibacoa2+jc"/>
	<link rel="alternate" type="text/html" href="https://www.ecured.cu/Especial:Contribuciones/Majibacoa2_jc"/>
	<updated>2026-06-06T13:21:08Z</updated>
	<subtitle>Contribuciones del colaborador</subtitle>
	<generator>MediaWiki 1.31.16</generator>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234392</id>
		<title>Contenedores C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234392"/>
		<updated>2018-11-29T19:22:27Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Contenedores C++ |imagen=  |concepto= En sentido [[C++|C++]] estricto, un contenedor de la STL es una clase genérica que puede instanciarse para representar diversos tipos de objetos. Esta clase incluye ciertas operaciones  sobre los objetos de su tipo; estas operaciones están representadas por [[Función (programación)|funciones]]-miembro, incluyendo [[Constructores (Programación)|constructores]] y funciones-[[Operadores|operador]], que son a su vez funciones genéricas}}''' Contenedores [[C++|C++]] '''. Al mismo tiempo, desde el punto de vista de las teorías de la información, podemos considerarlos estructuras de datos más o menos adecuadas (según el caso) para aplicarles ciertos algoritmos.&lt;br /&gt;
De su propio nombre (&amp;quot;Containers&amp;quot;) podemos deducir que su misión principal, y razón de su existencia, es su función como estructuras de datos, y en este sentido podemos adelantar que entre sus funcionalidades más destacadas se encuentran la gestión del espacio de almacenamiento necesario.&lt;br /&gt;
Una de las primerísimas ventajas de la utilización de contenedores es que el programador no tiene que enredarse con las cuestiones siempre espinosas de asignar o liberar memoria para los objetos creados, de forma que queda liberado de los [[Operadores|operadores]] [[Operador new|new]] y [[Operador delete|delete]].&lt;br /&gt;
== Filosofía de uso ==&lt;br /&gt;
Una primera pincelada sobre la [[Filosofía|filosofía]] de uso de los contenedores mediante un sencillo ejemplo: si tenemos que manejar un conjunto de enteros, puede utilizarse una [[Matriz|matriz]] de enteros, pero ya hemos señalado  que esta estructura nos obliga a conocer de antemano la cantidad de datos a almacenar (el tamaño de la matriz). En consecuencia, si el número de datos puede variar, esta opción no es muy adecuada. Además, si es importante mantener los datos ordenados, la utilización de una matriz nos obligaría a ingeniar por nuestra cuenta la forma de hacerlo; seguramente mediante complicadas rutinas de &amp;quot;sort&amp;quot; hechas manualmente.&lt;br /&gt;
&lt;br /&gt;
Una alternativa es utilizar como &amp;quot;contenedor&amp;quot; para nuestros enteros una clase genérica de la STL denominada [[Vector|vector]]. En este caso, serían posibles expresiones como las siguientes:&lt;br /&gt;
&lt;br /&gt;
  vector&amp;lt;int&amp;gt; v(3);         // L1:&lt;br /&gt;
  v[0] = 7;                 // L2:&lt;br /&gt;
  v[1] = v[0] + 1;          // L3:&lt;br /&gt;
  v[2] = v[0] + v[1];       // L4:&lt;br /&gt;
&lt;br /&gt;
Al encontrar la primera sentencia, el [[Compilador|compilador]] crea una instancia (especialidad) anónima de la plantilla vector para alojar enteros; a continuación una instancia de ella para alojar tres enteros, a la que denominamos v.&lt;br /&gt;
&lt;br /&gt;
Una primera inspección de las sentencias L2 a L3, nos muestra que la clase ofrece la posibilidad de utilizar con sus miembros el [[Operadores|operador]] subíndice de matriz [ ]. Deducimos por tanto, que dispone de una versión sobrecargada de este operador para los miembros de la clase, lo que nos permite utilizar el objeto v como una matriz, aunque con algunas funcionalidades no incluidas en aquellas.&lt;br /&gt;
&lt;br /&gt;
Después de L4 los valores finales para los miembros de nuestra &amp;quot;matriz&amp;quot; serian:&lt;br /&gt;
 v[0] == 7, v[1] == 8, v[2] == 15&lt;br /&gt;
&lt;br /&gt;
Si deseamos invertir el orden de los elementos de nuestra matriz. Para ello utilizamos una [[Función (programación)|función]] especial:&lt;br /&gt;
&lt;br /&gt;
 reverse(v.begin(), v.end());&lt;br /&gt;
&lt;br /&gt;
después de lo cual, el orden de miembros sería:&lt;br /&gt;
&lt;br /&gt;
 v[0] == 15, v[1] == 8, v[2] == 7&lt;br /&gt;
&lt;br /&gt;
La primera observación es que la función reverse utiliza dos argumentos, que son a su vez el valor devuelto por sendos métodos de clase (los aplicamos sobre nuestro objeto v).  El valor devuelto por estos métodos es lo que se conoce como un [[Iteradores (Programación)|iterador]]; una especie de puntero que señalan al interior de la estructura de datos representada por el contenedor v. En este caso, el primer iterador señala al primer miembro y el segundo a una posición después del último; de esta forma se indican los miembros inicial y final entre los que se realizará la operación de inversión efectuada por reverse.&lt;br /&gt;
&lt;br /&gt;
La segunda observación es que la función reverse no es un método de clase, sino una función global; es lo que denominamos un [[Algoritmo|algoritmo]]. Esta función tiene la peculiaridad de que puede ser aplicado sobre el contenedor vector (y algún otro); que opera sobre un rango de los elementos del contenedor, en nuestro caso sobre la totalidad (esta capacidad de operar sobre una parte de un contenedor es característica de los algoritmos). También que pueden operar sobre otros contenedores produciendo un efecto similar. Por ejemplo, el algoritmo reverse puede operar incluso sobre una simple matriz:&lt;br /&gt;
 char Ch[5] = { 'A', 'E', 'I', 'O', 'U' };&lt;br /&gt;
 reverse(Ch, Ch + 5);&lt;br /&gt;
 for (int i = 0; i &amp;lt; 5; ++i) cout &amp;lt;&amp;lt; &amp;quot;Ch[&amp;quot; &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &amp;quot;] = &amp;quot; &amp;lt;&amp;lt; Ch[i];&lt;br /&gt;
 Salida:&lt;br /&gt;
 Ch[0] = U Ch[1] = O Ch[2] = I Ch[3] = E Ch[4] = A&lt;br /&gt;
&lt;br /&gt;
Es significativo que el objeto v es una estructura de datos que permite acceder individualmente a sus miembros &amp;quot;como si&amp;quot; fuesen elementos de una matriz. También que se pueden aplicar ciertas operaciones sobre la totalidad, o parte, de esta estructura considerada como una unidad.&lt;br /&gt;
== Clasificación ==&lt;br /&gt;
Existen dos tipos de contenedores: secuencias y asociativos; a su vez se subdividen según el tipo de [[Iteradores (Programación)|iterador]] que soportan.&lt;br /&gt;
&lt;br /&gt;
Las secuencias almacenan los elementos en orden secuencial (de ahí su nombre). El contenedor agrupa a todos sus miembros como una sucesión lineal, y en consecuencia son adecuadas para accesos directos y secuenciales. Un ejemplo de secuencia es una matriz. De hecho, los algoritmos que pueden aplicarse a las secuencias pueden aplicarse también a las matrices.&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, por lo que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.  La STL proporciona cinco tipos distintos.&lt;br /&gt;
&lt;br /&gt;
La existencia de índices supone una ordenación según los valores de un conjunto de elementos (denominado &amp;quot;de claves&amp;quot;) para el que debe existir un criterio de ordenación. Dicho en otras palabras, los objetos &amp;quot;de clave&amp;quot; deben ser de un tipo para el que estén definidos los operadores relacionales. El árbol es mantenido ordenado de forma automática por los algoritmos de inserción y borrado del contenedor.&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave y para recorrer el conjunto (ordenado) de los elementos.&lt;br /&gt;
&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] contiene diez formas de contenedores y tres adaptadores de contenedor (denominados simplemente [[Adapter|adaptadores]]). En esta sección se expondrán brevemente cuales son estas formas; sus características, y cuál es la más adecuada para cada tipo de problema específico. En secciones sucesivas se comentarán individualmente con mayor detalle.&lt;br /&gt;
Relación siguiendo la clasificación utilizada en el Estándar:&lt;br /&gt;
  • Secuencias&lt;br /&gt;
      o	deque&lt;br /&gt;
      o	list&lt;br /&gt;
      o	stack&lt;br /&gt;
      o	vector&lt;br /&gt;
      o	vector &amp;lt;bool&amp;gt;&lt;br /&gt;
  • adaptadores&lt;br /&gt;
      o	queue&lt;br /&gt;
      o	priority_queue&lt;br /&gt;
  • Contenedores asociativos&lt;br /&gt;
      o	map&lt;br /&gt;
      o	multimap&lt;br /&gt;
      o	set&lt;br /&gt;
      o	multiset&lt;br /&gt;
      o	bitset&lt;br /&gt;
== Características ==&lt;br /&gt;
Las características más significativas de las diversas formas de contenedor son:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Contenedor&lt;br /&gt;
! Características&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;big&amp;gt;Secuencias&amp;lt;/big&amp;gt;&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| vector&lt;br /&gt;
| Este contenedor es una estructura de datos de tamaño fijo preferentemente. Aunque la STL proporciona herramientas para cambiar el tamaño de un vector de forma dinámica, esta operación es costosa y debe ser evitada dentro de lo posible (en este sentido el vector se comporta como una matriz ordinaria).&lt;br /&gt;
&lt;br /&gt;
Disponen de un buén mecanismo de acceso aleatorio a elementos y de un mecanismo de inserción al final muy eficiente.&lt;br /&gt;
&lt;br /&gt;
Generalmente es preferible utilizar un vector que un deque o un list, a menos que sea frecuentemente necesario insertar datos al comienzo o al final, en cuyo caso es mejor utilizar un deque.  Si por el contrario es frecuente la inserción de elementos en el centro, entonces es preferible un list.&lt;br /&gt;
|-&lt;br /&gt;
| vector&amp;lt;bool&amp;gt;&lt;br /&gt;
| Es una versión de la anterior especial para valores binarios (bits).&lt;br /&gt;
|-&lt;br /&gt;
| list&lt;br /&gt;
| Este contenedor responde a la idéa intuitiva de &amp;quot;lista&amp;quot;, el almacenamiento de objetos en una secuencia lineal que no está necesariamente ordenada (aunque sus miembros pueden ser ordenados fácilmente mediante la función-miembro sort() ). Estos contenedores suelen ser implementados como listas doblemente enlazadas. &lt;br /&gt;
&lt;br /&gt;
Dispone de mecanismos eficientes para insertar elementos al principio, al final o en cualquier posición (utilizando iteradores que denoten posición). Estas operaciones consumen un tiempo constante con independencia del número de elmentos albergados en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Dado que son estructuras lineales, en general los elementos no pueden ser accedidos por subíndices como en un vector.  Es necesario realizar un recorrido lineal por todos los valores, por lo que en las operaciones de acceso se utilizan tiempos proporcionales al número de elementos.&lt;br /&gt;
|-&lt;br /&gt;
| stack&lt;br /&gt;
| Contenedor de elementos tipo pila LIFO que permite inserciones y eliminaciones solo en la parte superior.&lt;br /&gt;
|-&lt;br /&gt;
| deque&lt;br /&gt;
| Los deques o colas de doble terminación (&amp;quot;Double-ended queue&amp;quot;) son un tipo de estructura de datos que comparte las características de las colas (&amp;quot;Queues&amp;quot;) y las pilas (&amp;quot;Stacks&amp;quot;). Como en las colas , los elementos pueden ser empujados por un extremo al interior del contenedor, y el primer elemento introducido puede ser extraído por el extremo opuesto. Al mismo tiempo, el último elemento introducido por el principio puede ser extraído en ese mismo extremo como si fuese una pila.&lt;br /&gt;
 &lt;br /&gt;
Estos contenedores suelen ser implementados bajo la forma de matrices bidimensionales.&lt;br /&gt;
&lt;br /&gt;
Las características de los deques implementados en la STL pueden resumirse en: Acceso aleatorio; mecanismo eficiente de inserción al principio o al final.&lt;br /&gt;
|-&lt;br /&gt;
| string&lt;br /&gt;
| Contenedor de caracteres adaptado a operaciones con cadenas de caracteres.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;big&amp;gt;Asociaciones&amp;lt;/big&amp;gt;&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| set&lt;br /&gt;
| Como el resto de contenedores asociativos, esta forma de contenedor mantiene los elementos en orden. Dispone de mecanismos eficientes para inclusión, inserción y eliminación de elementos, y soporta claves únicas (solo puede existir un miembro con una clave determinada).&lt;br /&gt;
|-&lt;br /&gt;
| multiset&lt;br /&gt;
| Versión del anterior que permite la existencia de claves duplicadas. Es decir, distintos elementos dentro del conjunto pueden responder a la misma clave.&lt;br /&gt;
|-&lt;br /&gt;
| bitset&lt;br /&gt;
| Contenedor de bit más orientado al tamaño que hacia el tipo de contenido. Permite almacenar secuencias de bits de tamaño fijo. No existen iteradores para reccorrerlas, y sus elementos se acceden utilizando el operador subíndice.&lt;br /&gt;
 &lt;br /&gt;
Se dispone de varias funciones para realizar con ellos operaciones de bits &lt;br /&gt;
|-&lt;br /&gt;
| map&lt;br /&gt;
| Como el resto de estructuras asociativas, el map mantiene sus elementos ordenados. Se caracteriza porque sus miembros son pares de valores que pueden ser de tipos distintos. Uno de ellos, el que actúa como clave para el índice (&amp;quot;Key-value&amp;quot;), puede ser de cualquier tipo, a condición de que sus elementos puedan ser ordenados según un criterio (por defecto se utiliza el operador &amp;lt;).&lt;br /&gt;
 &lt;br /&gt;
Permite claves únicas. Es decir, que solo puede existir un miembro para cada clave. Dispone de mecanismos de inserción y borrado muy eficientes y no existe límite de tamaño. La estructura se encarga de crecer y disminuir en concordancia con las necesidades de sus miembros. Permite el operador [ ] subíndice para los elementos de la clave así como otras técnicas de acceso.&lt;br /&gt;
&lt;br /&gt;
Estas estructuras de datos recibe también los nombres de diccionarios, tablas y matrices asociativas, en referencia a que pueden considerarse como dos matrices del mismo número de elementos, en las que existe una relación entre cada miembro de una con otro miembro de la otra.  Una de las matrices (que actúa de índice) estaría ordenada según su contenido&lt;br /&gt;
|-&lt;br /&gt;
| multimap&lt;br /&gt;
| En todo igual que el anterior pero permitiendo además claves duplicadas. Es decir, que una misma clave pueda estar asociada a dos &amp;quot;valores&amp;quot; distintos.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Adaptador&lt;br /&gt;
! Características&lt;br /&gt;
|-&lt;br /&gt;
| queue&lt;br /&gt;
| Contenedor tipo cola FIFO que permite inserciones al final y eliminaciones al principio.&lt;br /&gt;
|-&lt;br /&gt;
| priority queue&lt;br /&gt;
| Este contenedor dispone de mecanismos eficientes para acceso y eliminación de grandes valores.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Seleccionar un contenedor ==&lt;br /&gt;
El binomio contendor-iterador conforma una herramienta que se adapta a circunstancias muy variadas. Es posible que un determinado problema pueda ser abordado de varias formas, en estos casos la selección de la forma de contenedor más adecuado depende de las circunstancias. En ciertas ocasiones puede resultar bastante obvia; en otras puede no estar tan claro cuál es la mejor opción, pues &amp;quot;a priori&amp;quot;, pueden adaptarse varias formas al caso concreto. Puede utilizarse el sistema de prueba y comparación. Por ejemplo, cronometrando los resultados obtenidos en un modo u otro. También será de gran ayuda la experiencia, pero como una guía o criterio general puede utilizarse el principio de selección que se indica a continuación.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Como se accederá a los datos?.&lt;br /&gt;
| Si es importante un acceso aleatorio, pueden utilizarse un vector o un deque. Si basta con un acceso secuencial cualquiera de los dos puede ser el elegido.&lt;br /&gt;
|-&lt;br /&gt;
| Es importante el orden en que serán mantenidos los valores dentro de la colección de datos?&lt;br /&gt;
| Existen muchas formas de secuenciar los valores. Si es importante un orden estricto a lo largo de toda la vida del contenedor, la elección obvia es un set, dado que las inserciones en una de estas estructuras se realizan automáticamente en orden.&lt;br /&gt;
 &lt;br /&gt;
Si este orden es importante solo en algún momento, por ejemplo al final de una serie de inserciones, puede ser más sencillo colocar los valores en un list o vector para ordenar más tarde el resultado en el momento necesario.&lt;br /&gt;
&lt;br /&gt;
Si el orden en que se almacenan los valores en la estructura está relacionado con el orden de su inserción, entonces un stack, un queue o un list pueden ser la mejor elección.&lt;br /&gt;
|-&lt;br /&gt;
| Puede variar mucho el tamaño de la estructura de datos durante el curso de la ejecución del programa?&lt;br /&gt;
| Si es así, entonces puede ser que la mejor opción sean un list o un set. Un vector o un deque pueden conducir a mantener un gran almacenamiento intermedio (buffer); incluso después que los elementos hayan sido eliminados de la colección de datos. Estos dos contenedores no son adecuados para cambios de tamaño, aunque vector dispone de un mecanismo de inserción al final eficiente.&lt;br /&gt;
 &lt;br /&gt;
Recíprocamente: si el tamaño de la colección se mantiene relativamente estable, entonces un vector o un deque pueden utilizar menos memoria que un list o un set que almacenen el mismo número de elementos.&lt;br /&gt;
|-&lt;br /&gt;
| Es posible determinar el tamaño de la colección?&lt;br /&gt;
| La estructura de datos vector proporciona un medio para pre-seleccionar un bloque de memoria de un tamaño específico con la función miembro reserve, posibilidad que no existe en otros contenedores.&lt;br /&gt;
|-&lt;br /&gt;
| Es frecuente tener que comprobar si un valor cualquiera está incluido en la colección?&lt;br /&gt;
| En este caso, un contenedor set o map pueden ser buena elección. En estos casos comprobar si un determinado valor está incluido puede ser realizado con un pequeño número de pasos (logarítmicos con el tamaño del contenedor). Mientras que la misma verificación en cualquiera de los otros tipos puede requerir comparar el valor con cada elemento almacenado en el contenedor.&lt;br /&gt;
|-&lt;br /&gt;
| Está indexada la colección de datos? &lt;br /&gt;
| Si las claves son enteros entre 0 y un límite superior, pueden utilizarse un vector o un deque. &lt;br /&gt;
|-&lt;br /&gt;
| Si es así, puede ser vista la colección como una serie de pares clave/valor?&lt;br /&gt;
| Si la clave es algún otro valor, como cadenas de caracteres o tipos definidos por el usuario, puede utilizarse un contenedor map.&lt;br /&gt;
|-&lt;br /&gt;
| Pueden los valores estar relacionados unos con otros?&lt;br /&gt;
| Todos los valores almacenados en cualquier contenedor de la STL debe ser capaz de comprobar la igualdad con cualquier otro valor similar, pero recuerde que no todos son capaces de reconocer el operador de relación menor-que; sin embargo, si los valores no pueden ser ordenados utilizando el operador menor-que, no pueden ser almacenados en un set o en un map.&lt;br /&gt;
|-&lt;br /&gt;
| Es una operación frecuente tener que encontrar y eliminar el valor mayor de la colección?&lt;br /&gt;
| En caso afirmativo, la estructura de datos más idónea es el priority queue.&lt;br /&gt;
|-&lt;br /&gt;
| En que posiciones son insertados o eliminados los elementos de la estructura?&lt;br /&gt;
| Si los valores son añadidos o eliminados en la zona interior, entonces la mejor opción es un list.&lt;br /&gt;
 &lt;br /&gt;
Si los valores son insertados solo al comienzo, un deque o un list pueden ser lo más adecuado.&lt;br /&gt;
&lt;br /&gt;
Si los valores son insertados y eliminados solo al final, un stack o un queue pueden ser elecciones lógicas.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| Es frecuente tener que refundir dos o más secuencias en una sola?&lt;br /&gt;
| En caso afirmativo, puede considerarse que las mejores opciones son un set o un list, dependiendo que la colección deba o no ser mantenida en orden.&lt;br /&gt;
 &lt;br /&gt;
Refundir dos set es una operación muy eficiente.  Si la colección de datos no está ordenada, pero puede utilizarse la función miembro splice() de las list (que es muy eficiente), entonces es preferible este último tipo de contenedor, dado que esta operación no está contemplada en las demás formas.&lt;br /&gt;
|}&lt;br /&gt;
=== Tipos no incluidos ===&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] incluye contenedores adecuados para la mayoría de los casos prácticos, aunque quizás existen una serie de estructuras de datos clásicas que no han sido incluidas. En la mayoría de los casos, la causa es que los contenedores proporcionados pueden ser fácilmente adaptados para suplir los usos facilitados por los tipos omitidos.&lt;br /&gt;
&lt;br /&gt;
Tipos clásicos no incluidos y la sustitución más fácil.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Contenedor omitido&lt;br /&gt;
! Sustitución utilizando elementos de STL&lt;br /&gt;
|-&lt;br /&gt;
| tree&lt;br /&gt;
| El modo set está implementado internamente como un árbol de búsqueda binaria. &lt;br /&gt;
&lt;br /&gt;
Para la mayoría de los casos prácticos que pueden ser resueltos utilizando árboles este modo es un sustituto adecuado.&lt;br /&gt;
|-&lt;br /&gt;
| matrices multidimensionales&lt;br /&gt;
| Puesto que los vectores pueden almacenar elementos que sean otros vectores, estas estructuras pueden ser construidas fácilmente.&lt;br /&gt;
|-&lt;br /&gt;
| graph&lt;br /&gt;
| La representación de un gráfico puede ser fácilmente construida como un map que contiene otros map. Un map cuyos elementos son a su vez maps, es la representación natural de un gráfico directo. &lt;br /&gt;
|-&lt;br /&gt;
| sparse array&lt;br /&gt;
| Una novedosa sustitución es la representación de un gráfico&lt;br /&gt;
|-&lt;br /&gt;
| hash table&lt;br /&gt;
| Las tablas hash proporcionan un tiempo de acceso constante, así como inserción y borrado de elementos, convirtiendo estas operaciones en operaciones de índice.&lt;br /&gt;
 &lt;br /&gt;
Una tabla hash puede ser construida fácilmente como un vector (o deque) cuyos elementos son lists (o incluso sets).  En el ejemplo de la ordenación raíz (  xxx) se describe una de estas estructuras (un vector de deques), aunque en este ejemplo no incluye invocación la función hash para convertir un valor en un índice.&lt;br /&gt;
|-&lt;br /&gt;
| Funcionalidad set&lt;br /&gt;
| En la STL, los tipos set están específicamente ordenados, y sus operaciones (como la unión intersección, etc.) no pueden ser realizadas sobre colecciones de valores no ordenados (por ejemplo un conjunto de números complejos).&lt;br /&gt;
 &lt;br /&gt;
Una list puede ser utilizada como sustituto, aunque es necesario escribir funciones de operación especiales, dado que los algoritmos genéricos no pueden ser utilizados con listas.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Gestión de memoria ==&lt;br /&gt;
La gestión de memoria realizada por los contenedores comprende tanto la asignación y liberación de espacio para sus miembros, como para las claves que constituyen el sistema de índice de algunos tipos de contenedor. En general los algoritmos de la STL están muy optimizados y el sistema de asignación de memoria intenta compaginar rapidez y eficacia. La primera exige asignar y desasignar espacio cada vez que se introduce o elimina un miembro del contenedor. La eficacia, e incluso la disminución de la fragmentación inherentes al manejo del montón, exige asignar y rehusar trozos de memoria lo más grandes posible cada vez. El abordaje a este problema se ha realizado de dos formas básicas: (a) Contenedores que no pueden alterar su tamaño, de forma que la asignación de espacio para sus elementos debe realizarse en el momento de su declaración. (b) Contenedores que pueden crecer y/o disminuir en consonancia con los elementos a albergar.&lt;br /&gt;
&lt;br /&gt;
Refiriéndonos al caso (b), para balancear estas exigencias contrapuestas, algunas implementaciones utilizan el siguiente esquema de trabajo: inicialmente el sistema asigna al contenedor un trozo de memoria de tamaño adecuado para contener cierto número de elementos; espacio que es utilizando hasta que se agota. A partir de aquí, cada nueva demanda origina la asignación una zona de doble tamaño que la anterior. Por ejemplo, supongamos que para gestionar un vector de enteros, el compilador asigna inicialmente espacio para un máximo de 16 miembros.  Cuando se agotara, se realizaría una nueva asignación de espacio para 32 miembros, e inmediatamente se efectuaría una recolocación del contenido actual en el nuevo espacio y la liberación del primitivo. Si el nuevo contenedor quedara lleno de nuevo, la siguiente asignación sería capaz de 64 miembros y así sucesivamente.&lt;br /&gt;
&lt;br /&gt;
El factor de aumento de tamaño puede ser cualquiera. Muchos compiladores utilizan un factor 1.5 cada vez que deben ampliar el espacio necesario.&lt;br /&gt;
&lt;br /&gt;
Cada nueva recolocación implica varios pasos:&lt;br /&gt;
  •	Asignación de memoria al estilo malloc() de la librería clásica en cantidad suficiente para el nuevo tamaño.&lt;br /&gt;
  •	Copia de los elementos actuales en la nueva localización. Los elementos son colocados en la nueva situación utilizando el constructor copia.&lt;br /&gt;
  •	Actualización de las estructuras internas del nuevo contenedor (sistema de índices).&lt;br /&gt;
  •	Eliminación de los elementos originales mediante invocación sucesiva de sus correspondientes destructores.&lt;br /&gt;
  •	Liberación de la memoria utilizada por las estructuras internas.&lt;br /&gt;
  •	Liberación de la zona original mediante una invocación al estilo free de la librería clásica.&lt;br /&gt;
&lt;br /&gt;
En general, al referirse al tamaño de un contenedor existen tres magnitudes distintas aunque relacionadas, cuyos valores pueden obtenerse mediante tres métodos:&lt;br /&gt;
&lt;br /&gt;
  •	El número de elementos contenidos actualmente. size()&lt;br /&gt;
  •	El máximo número de elementos que pueden alcanzarse actualmente sin necesidad de una nueva recolocación. capacity()&lt;br /&gt;
  •	El máximo número de elementos que pueden alcanzarse en cualquier caso. max_size().&lt;br /&gt;
&lt;br /&gt;
 Ejemplo:&lt;br /&gt;
   #include &amp;lt;iostream&amp;gt;&lt;br /&gt;
   using namespace std;&lt;br /&gt;
   #include &amp;lt;vector&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   int main() {         // ================&lt;br /&gt;
   vector&amp;lt;int&amp;gt; vInt;&lt;br /&gt;
   for (int i=0; i &amp;lt; 100; i++) vInt.push_back(i);&lt;br /&gt;
&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Tamaño actual:   &amp;quot; &amp;lt;&amp;lt; vInt.size()     &amp;lt;&amp;lt; endl;&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Capacidad actual: &amp;quot; &amp;lt;&amp;lt; vInt.capacity() &amp;lt;&amp;lt; endl;&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Tamano maximo:   &amp;quot; &amp;lt;&amp;lt; vInt.max_size() &amp;lt;&amp;lt; endl;&lt;br /&gt;
   return 0;&lt;br /&gt;
   }&lt;br /&gt;
   Salida:&lt;br /&gt;
   Tamaño actual: 100&lt;br /&gt;
   Capacidad actual: 256&lt;br /&gt;
   Tamano maximo: 1073741823&lt;br /&gt;
&lt;br /&gt;
En todos los casos: size() &amp;lt;= capacity()&lt;br /&gt;
&lt;br /&gt;
Es posible comprobar si un contenedor está vacío, comparando su tamaño actual size() con cero, aunque es más rápido utilizar el método empty(), que devuelve true si realmente size() == 0.&lt;br /&gt;
&lt;br /&gt;
=== Reserva de espacio ===&lt;br /&gt;
Como puede suponer, cada recolocación supone un proceso considerable, sobre todo en contenedores muy grandes. Para evitar sus inconvenientes si se conoce de antemano el tamaño máximo a utilizar, la STL ofrece la posibilidad de preasignar un espacio arbitrario. Para esto se dispone del método reserve(n), que garantiza la asignación de espacio inicial suficiente para alojar n miembros en el contenedor. Si el argumento n es mayor que la capacidad actual, se produce una recolocación y el nuevo argumento determina la nueva capacidad. Si es menor no se produce ninguna acción.&lt;br /&gt;
&lt;br /&gt;
Ejemplo, para crear un vector de enteros capaz para al menos 1000 miembros:&lt;br /&gt;
  vector &amp;lt;int&amp;gt; v;&lt;br /&gt;
  v.reserve(1000);&lt;br /&gt;
&lt;br /&gt;
En el siguiente ejemplo se muestran los resultados compilado con Borland C++ 5.5 para Win32; con MS Visual C++ 6.0 y con GNU gcc 2.95.3 para Linux:&lt;br /&gt;
  // resultados con:         BC++   VC++   GNU   &lt;br /&gt;
  vector&amp;lt;int&amp;gt; v;&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 0      0      0   &lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 0      0      0&lt;br /&gt;
  v.push_back(3);&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    1      1&lt;br /&gt;
  v.reserve(100);&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    100    100&lt;br /&gt;
&lt;br /&gt;
=== Operaciones sobre contenedores ===&lt;br /&gt;
Los elementos de un contenedor son colocados en él utilizando el constructor copia, aunque algunas operaciones requieren la existencia de un constructor por defecto. A su vez, los algoritmos genéricos, como copy(), que copian a un contenedor, utilizan el operador de asignación.&lt;br /&gt;
&lt;br /&gt;
Cuando se duplica todo un contenedor de tipos T por invocación del [[Constructor (C++)|constructor]] copia o por asignación, cada miembro es copiado en la nueva estructura utilizando el constructor copia o el operador de asignación. Tanto si una copia profunda o una copia somera, el resultado es controlado por el programador, que puede proporcionar el operador de asignación para el tipo T con cualquier significado que desee. Si se ha definido un destructor para el tipo T, este destructor es invocado cada vez que deba ser eliminado un elemento del contenedor. Cuando se destruye toda la colección, el destructor es invocado por cada elemento que permaneciera almacenado.&lt;br /&gt;
&lt;br /&gt;
En estos casos, el contenedor es solamente responsable de mantener los propios punteros, siendo responsabilidad del programador manejar la memoria de los valores referenciados por estos, lo que supone que los espacios de memoria son asignados correctamente; por lo general mediante el operador new; que no son desasignados mientras el contenedor albergue referencias a ellos, y que sean adecuadamente desasignados una vez que han sido eliminados del contenedor.&lt;br /&gt;
&lt;br /&gt;
===  Secuencias ===&lt;br /&gt;
Las secuencias son estructuras de datos de tipo lineal, con posibilidad de que su tamaño puede ser alterado insertando elementos al principio, al final o en cualquier posición, si bien la idoneidad en este sentido es distinta entre los diversos tipos.&lt;br /&gt;
&lt;br /&gt;
La STL ofrece los siguientes:&lt;br /&gt;
  • deque&lt;br /&gt;
  • list&lt;br /&gt;
  • stack&lt;br /&gt;
  • vector&lt;br /&gt;
  • vector&amp;lt;bool&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La estructura lineal implica que sus datos son lógicamente contiguos, aunque su disposición física puede que no lo sea. Los elementos pueden ser accedidos por un índice numérico, aunque en algunos tipos de secuencia el acceso a un elemento implica un recorrido por la lista.&lt;br /&gt;
&lt;br /&gt;
== Contenedores asociativos ==&lt;br /&gt;
Los contenedores asociativos son una extensión de las secuencias. Mientras que en estas para acceder a los elementos solo pueden utilizarse claves numéricas, que señalan el número de orden del elemento dentro de la secuencia (al estilo de los índices en las matrices). Los contenedores asociativos admiten cualquier tipo de clave de acceso. Las más frecuentes son las cadenas alfanuméricas (stings).&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, razón por la que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.&lt;br /&gt;
&lt;br /&gt;
La ordenación se realiza según los valores de ciertos miembros del contenedor. Estos elementos son denominados &amp;quot;de claves&amp;quot; (&amp;quot;Key values&amp;quot;). Lo que exige que los objetos &amp;quot;de clave&amp;quot; sean de un tipo para el que estén definidos los operadores relacionales. El contenedor es mantenido ordenado de forma automática por los algoritmos de inserción y borrado.&lt;br /&gt;
&lt;br /&gt;
La STL proporciona cinco tipo distintos, aunque en realidad son tres clases; dos de ellas en dos variedades (permitiendo o no claves duplicadas). Uno de los tipos (bitset) sirve para almacenar campos de bits de longitud constante. Los otros dos permiten elementos ordenados de cualquier tipo (set y multiset), mientras que map y multimap permiten alojar pares de elementos. Uno que actúa como &amp;quot;Key value&amp;quot; y otro que puede ser un tipo cualquiera al que llamaremos valor-dato.&lt;br /&gt;
&lt;br /&gt;
  • bitset&lt;br /&gt;
  • set&lt;br /&gt;
  • multiset&lt;br /&gt;
  • map&lt;br /&gt;
  • multimap&lt;br /&gt;
&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave, y para recorrer el conjunto (ordenado) de las claves.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Facetas C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http://www.zator.com/Cpp/E5_1_1.htm Contenerores C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Contenedores en C.conclase.net]&lt;br /&gt;
* [https://docs.microsoft.com/es-es/cpp/standard-library/stl-containers?view=vs-2017  Contenedores de la biblioteca estándar de C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234274</id>
		<title>Contenedores C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234274"/>
		<updated>2018-11-29T18:38:52Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Contenedores C++ |imagen=  |concepto= En sentido [[C++|C++]] estricto, un contenedor de la STL es una clase genérica que puede instanciarse para representar diversos tipos de objetos. Esta clase incluye ciertas operaciones  sobre los objetos de su tipo; estas operaciones están representadas por [[Función (programación)|funciones]]-miembro, incluyendo [[Constructores (Programación)|constructores]] y funciones-[[Operadores|operador]], que son a su vez funciones genéricas}}''' Contenedores [[C++|C++]] '''. Al mismo tiempo, desde el punto de vista de las teorías de la información, podemos considerarlos estructuras de datos más o menos adecuadas (según el caso) para aplicarles ciertos algoritmos.&lt;br /&gt;
De su propio nombre (&amp;quot;Containers&amp;quot;) podemos deducir que su misión principal, y razón de su existencia, es su función como estructuras de datos, y en este sentido podemos adelantar que entre sus funcionalidades más destacadas se encuentran la gestión del espacio de almacenamiento necesario.&lt;br /&gt;
Una de las primerísimas ventajas de la utilización de contenedores es que el programador no tiene que enredarse con las cuestiones siempre espinosas de asignar o liberar memoria para los objetos creados, de forma que queda liberado de los [[Operadores|operadores]] [[Operador new|new]] y [[Operador delete|delete]].&lt;br /&gt;
== Filosofía de uso ==&lt;br /&gt;
Una primera pincelada sobre la [[Filosofía|filosofía]] de uso de los contenedores mediante un sencillo ejemplo: si tenemos que manejar un conjunto de enteros, puede utilizarse una [[Matriz|matriz]] de enteros, pero ya hemos señalado  que esta estructura nos obliga a conocer de antemano la cantidad de datos a almacenar (el tamaño de la matriz). En consecuencia, si el número de datos puede variar, esta opción no es muy adecuada. Además, si es importante mantener los datos ordenados, la utilización de una matriz nos obligaría a ingeniar por nuestra cuenta la forma de hacerlo; seguramente mediante complicadas rutinas de &amp;quot;sort&amp;quot; hechas manualmente.&lt;br /&gt;
&lt;br /&gt;
Una alternativa es utilizar como &amp;quot;contenedor&amp;quot; para nuestros enteros una clase genérica de la STL denominada [[Vector|vector]]. En este caso, serían posibles expresiones como las siguientes:&lt;br /&gt;
&lt;br /&gt;
  vector&amp;lt;int&amp;gt; v(3);         // L1:&lt;br /&gt;
  v[0] = 7;                 // L2:&lt;br /&gt;
  v[1] = v[0] + 1;          // L3:&lt;br /&gt;
  v[2] = v[0] + v[1];       // L4:&lt;br /&gt;
&lt;br /&gt;
Al encontrar la primera sentencia, el [[Compilador|compilador]] crea una instancia (especialidad) anónima de la plantilla vector para alojar enteros; a continuación una instancia de ella para alojar tres enteros, a la que denominamos v.&lt;br /&gt;
&lt;br /&gt;
Una primera inspección de las sentencias L2 a L3, nos muestra que la clase ofrece la posibilidad de utilizar con sus miembros el [[Operadores|operador]] subíndice de matriz [ ]. Deducimos por tanto, que dispone de una versión sobrecargada de este operador para los miembros de la clase, lo que nos permite utilizar el objeto v como una matriz, aunque con algunas funcionalidades no incluidas en aquellas.&lt;br /&gt;
&lt;br /&gt;
Después de L4 los valores finales para los miembros de nuestra &amp;quot;matriz&amp;quot; serian:&lt;br /&gt;
 v[0] == 7, v[1] == 8, v[2] == 15&lt;br /&gt;
&lt;br /&gt;
Si deseamos invertir el orden de los elementos de nuestra matriz. Para ello utilizamos una [[Función (programación)|función]] especial:&lt;br /&gt;
&lt;br /&gt;
 reverse(v.begin(), v.end());&lt;br /&gt;
&lt;br /&gt;
después de lo cual, el orden de miembros sería:&lt;br /&gt;
&lt;br /&gt;
 v[0] == 15, v[1] == 8, v[2] == 7&lt;br /&gt;
&lt;br /&gt;
La primera observación es que la función reverse utiliza dos argumentos, que son a su vez el valor devuelto por sendos métodos de clase (los aplicamos sobre nuestro objeto v).  El valor devuelto por estos métodos es lo que se conoce como un [[Iteradores (Programación)|iterador]]; una especie de puntero que señalan al interior de la estructura de datos representada por el contenedor v. En este caso, el primer iterador señala al primer miembro y el segundo a una posición después del último; de esta forma se indican los miembros inicial y final entre los que se realizará la operación de inversión efectuada por reverse.&lt;br /&gt;
&lt;br /&gt;
La segunda observación es que la función reverse no es un método de clase, sino una función global; es lo que denominamos un [[Algoritmo|algoritmo]]. Esta función tiene la peculiaridad de que puede ser aplicado sobre el contenedor vector (y algún otro); que opera sobre un rango de los elementos del contenedor, en nuestro caso sobre la totalidad (esta capacidad de operar sobre una parte de un contenedor es característica de los algoritmos). También que pueden operar sobre otros contenedores produciendo un efecto similar. Por ejemplo, el algoritmo reverse puede operar incluso sobre una simple matriz:&lt;br /&gt;
 char Ch[5] = { 'A', 'E', 'I', 'O', 'U' };&lt;br /&gt;
 reverse(Ch, Ch + 5);&lt;br /&gt;
 for (int i = 0; i &amp;lt; 5; ++i) cout &amp;lt;&amp;lt; &amp;quot;Ch[&amp;quot; &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &amp;quot;] = &amp;quot; &amp;lt;&amp;lt; Ch[i];&lt;br /&gt;
 Salida:&lt;br /&gt;
 Ch[0] = U Ch[1] = O Ch[2] = I Ch[3] = E Ch[4] = A&lt;br /&gt;
&lt;br /&gt;
Es significativo que el objeto v es una estructura de datos que permite acceder individualmente a sus miembros &amp;quot;como si&amp;quot; fuesen elementos de una matriz. También que se pueden aplicar ciertas operaciones sobre la totalidad, o parte, de esta estructura considerada como una unidad.&lt;br /&gt;
== Clasificación ==&lt;br /&gt;
Existen dos tipos de contenedores: secuencias y asociativos; a su vez se subdividen según el tipo de [[Iteradores (Programación)|iterador]] que soportan.&lt;br /&gt;
&lt;br /&gt;
Las secuencias almacenan los elementos en orden secuencial (de ahí su nombre). El contenedor agrupa a todos sus miembros como una sucesión lineal, y en consecuencia son adecuadas para accesos directos y secuenciales. Un ejemplo de secuencia es una matriz. De hecho, los algoritmos que pueden aplicarse a las secuencias pueden aplicarse también a las matrices.&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, por lo que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.  La STL proporciona cinco tipos distintos.&lt;br /&gt;
&lt;br /&gt;
La existencia de índices supone una ordenación según los valores de un conjunto de elementos (denominado &amp;quot;de claves&amp;quot;) para el que debe existir un criterio de ordenación. Dicho en otras palabras, los objetos &amp;quot;de clave&amp;quot; deben ser de un tipo para el que estén definidos los operadores relacionales. El árbol es mantenido ordenado de forma automática por los algoritmos de inserción y borrado del contenedor.&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave y para recorrer el conjunto (ordenado) de los elementos.&lt;br /&gt;
&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] contiene diez formas de contenedores y tres adaptadores de contenedor (denominados simplemente [[Adapter|adaptadores]]). En esta sección se expondrán brevemente cuales son estas formas; sus características, y cuál es la más adecuada para cada tipo de problema específico. En secciones sucesivas se comentarán individualmente con mayor detalle.&lt;br /&gt;
Relación siguiendo la clasificación utilizada en el Estándar:&lt;br /&gt;
  • Secuencias&lt;br /&gt;
      o	deque&lt;br /&gt;
      o	list&lt;br /&gt;
      o	stack&lt;br /&gt;
      o	vector&lt;br /&gt;
      o	vector &amp;lt;bool&amp;gt;&lt;br /&gt;
  • adaptadores&lt;br /&gt;
      o	queue&lt;br /&gt;
      o	priority_queue&lt;br /&gt;
  • Contenedores asociativos&lt;br /&gt;
      o	map&lt;br /&gt;
      o	multimap&lt;br /&gt;
      o	set&lt;br /&gt;
      o	multiset&lt;br /&gt;
      o	bitset&lt;br /&gt;
== Características ==&lt;br /&gt;
Las características más significativas de las diversas formas de contenedor son:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Contenedor&lt;br /&gt;
! Características&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;big&amp;gt;Secuencias&amp;lt;/big&amp;gt;&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| vector&lt;br /&gt;
| Este contenedor es una estructura de datos de tamaño fijo preferentemente. Aunque la STL proporciona herramientas para cambiar el tamaño de un vector de forma dinámica, esta operación es costosa y debe ser evitada dentro de lo posible (en este sentido el vector se comporta como una matriz ordinaria).&lt;br /&gt;
&lt;br /&gt;
Disponen de un buén mecanismo de acceso aleatorio a elementos y de un mecanismo de inserción al final muy eficiente.&lt;br /&gt;
&lt;br /&gt;
Generalmente es preferible utilizar un vector que un deque o un list, a menos que sea frecuentemente necesario insertar datos al comienzo o al final, en cuyo caso es mejor utilizar un deque.  Si por el contrario es frecuente la inserción de elementos en el centro, entonces es preferible un list.&lt;br /&gt;
|-&lt;br /&gt;
| vector&amp;lt;bool&amp;gt;&lt;br /&gt;
| Es una versión de la anterior especial para valores binarios (bits).&lt;br /&gt;
|-&lt;br /&gt;
| list&lt;br /&gt;
| Este contenedor responde a la idéa intuitiva de &amp;quot;lista&amp;quot;, el almacenamiento de objetos en una secuencia lineal que no está necesariamente ordenada (aunque sus miembros pueden ser ordenados fácilmente mediante la función-miembro sort() ). Estos contenedores suelen ser implementados como listas doblemente enlazadas. &lt;br /&gt;
&lt;br /&gt;
Dispone de mecanismos eficientes para insertar elementos al principio, al final o en cualquier posición (utilizando iteradores que denoten posición). Estas operaciones consumen un tiempo constante con independencia del número de elmentos albergados en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Dado que son estructuras lineales, en general los elementos no pueden ser accedidos por subíndices como en un vector.  Es necesario realizar un recorrido lineal por todos los valores, por lo que en las operaciones de acceso se utilizan tiempos proporcionales al número de elementos.&lt;br /&gt;
|-&lt;br /&gt;
| stack&lt;br /&gt;
| Contenedor de elementos tipo pila LIFO que permite inserciones y eliminaciones solo en la parte superior.&lt;br /&gt;
|-&lt;br /&gt;
| deque&lt;br /&gt;
| Los deques o colas de doble terminación (&amp;quot;Double-ended queue&amp;quot;) son un tipo de estructura de datos que comparte las características de las colas (&amp;quot;Queues&amp;quot;) y las pilas (&amp;quot;Stacks&amp;quot;). Como en las colas , los elementos pueden ser empujados por un extremo al interior del contenedor, y el primer elemento introducido puede ser extraído por el extremo opuesto. Al mismo tiempo, el último elemento introducido por el principio puede ser extraído en ese mismo extremo como si fuese una pila.&lt;br /&gt;
 &lt;br /&gt;
Estos contenedores suelen ser implementados bajo la forma de matrices bidimensionales.&lt;br /&gt;
&lt;br /&gt;
Las características de los deques implementados en la STL pueden resumirse en: Acceso aleatorio; mecanismo eficiente de inserción al principio o al final.&lt;br /&gt;
|-&lt;br /&gt;
| string&lt;br /&gt;
| Contenedor de caracteres adaptado a operaciones con cadenas de caracteres.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;big&amp;gt;Asociaciones&amp;lt;/big&amp;gt;&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| set&lt;br /&gt;
| Como el resto de contenedores asociativos, esta forma de contenedor mantiene los elementos en orden. Dispone de mecanismos eficientes para inclusión, inserción y eliminación de elementos, y soporta claves únicas (solo puede existir un miembro con una clave determinada).&lt;br /&gt;
|-&lt;br /&gt;
| multiset&lt;br /&gt;
| Versión del anterior que permite la existencia de claves duplicadas. Es decir, distintos elementos dentro del conjunto pueden responder a la misma clave.&lt;br /&gt;
|-&lt;br /&gt;
| bitset&lt;br /&gt;
| Contenedor de bit más orientado al tamaño que hacia el tipo de contenido. Permite almacenar secuencias de bits de tamaño fijo. No existen iteradores para reccorrerlas, y sus elementos se acceden utilizando el operador subíndice.&lt;br /&gt;
 &lt;br /&gt;
Se dispone de varias funciones para realizar con ellos operaciones de bits &lt;br /&gt;
|-&lt;br /&gt;
| map&lt;br /&gt;
| Como el resto de estructuras asociativas, el map mantiene sus elementos ordenados. Se caracteriza porque sus miembros son pares de valores que pueden ser de tipos distintos. Uno de ellos, el que actúa como clave para el índice (&amp;quot;Key-value&amp;quot;), puede ser de cualquier tipo, a condición de que sus elementos puedan ser ordenados según un criterio (por defecto se utiliza el operador &amp;lt;).&lt;br /&gt;
 &lt;br /&gt;
Permite claves únicas. Es decir, que solo puede existir un miembro para cada clave. Dispone de mecanismos de inserción y borrado muy eficientes y no existe límite de tamaño. La estructura se encarga de crecer y disminuir en concordancia con las necesidades de sus miembros. Permite el operador [ ] subíndice para los elementos de la clave así como otras técnicas de acceso.&lt;br /&gt;
&lt;br /&gt;
Estas estructuras de datos recibe también los nombres de diccionarios, tablas y matrices asociativas, en referencia a que pueden considerarse como dos matrices del mismo número de elementos, en las que existe una relación entre cada miembro de una con otro miembro de la otra.  Una de las matrices (que actúa de índice) estaría ordenada según su contenido&lt;br /&gt;
|-&lt;br /&gt;
| multimap&lt;br /&gt;
| En todo igual que el anterior pero permitiendo además claves duplicadas. Es decir, que una misma clave pueda estar asociada a dos &amp;quot;valores&amp;quot; distintos.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Adaptador&lt;br /&gt;
! Características&lt;br /&gt;
|-&lt;br /&gt;
| queue&lt;br /&gt;
| Contenedor tipo cola FIFO que permite inserciones al final y eliminaciones al principio.&lt;br /&gt;
|-&lt;br /&gt;
| priority queue&lt;br /&gt;
| Este contenedor dispone de mecanismos eficientes para acceso y eliminación de grandes valores.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Seleccionar un contenedor ==&lt;br /&gt;
El binomio contendor-iterador conforma una herramienta que se adapta a circunstancias muy variadas. Es posible que un determinado problema pueda ser abordado de varias formas, en estos casos la selección de la forma de contenedor más adecuado depende de las circunstancias. En ciertas ocasiones puede resultar bastante obvia; en otras puede no estar tan claro cuál es la mejor opción, pues &amp;quot;a priori&amp;quot;, pueden adaptarse varias formas al caso concreto. Puede utilizarse el sistema de prueba y comparación. Por ejemplo, cronometrando los resultados obtenidos en un modo u otro. También será de gran ayuda la experiencia, pero como una guía o criterio general puede utilizarse el principio de selección que se indica a continuación.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Como se accederá a los datos?.&lt;br /&gt;
| Si es importante un acceso aleatorio, pueden utilizarse un vector o un deque. Si basta con un acceso secuencial cualquiera de los dos puede ser el elegido.&lt;br /&gt;
|-&lt;br /&gt;
| Es importante el orden en que serán mantenidos los valores dentro de la colección de datos?&lt;br /&gt;
| Existen muchas formas de secuenciar los valores. Si es importante un orden estricto a lo largo de toda la vida del contenedor, la elección obvia es un set, dado que las inserciones en una de estas estructuras se realizan automáticamente en orden.&lt;br /&gt;
 &lt;br /&gt;
Si este orden es importante solo en algún momento, por ejemplo al final de una serie de inserciones, puede ser más sencillo colocar los valores en un list o vector para ordenar más tarde el resultado en el momento necesario.&lt;br /&gt;
&lt;br /&gt;
Si el orden en que se almacenan los valores en la estructura está relacionado con el orden de su inserción, entonces un stack, un queue o un list pueden ser la mejor elección.&lt;br /&gt;
|-&lt;br /&gt;
| Puede variar mucho el tamaño de la estructura de datos durante el curso de la ejecución del programa?&lt;br /&gt;
| Si es así, entonces puede ser que la mejor opción sean un list o un set. Un vector o un deque pueden conducir a mantener un gran almacenamiento intermedio (buffer); incluso después que los elementos hayan sido eliminados de la colección de datos. Estos dos contenedores no son adecuados para cambios de tamaño, aunque vector dispone de un mecanismo de inserción al final eficiente.&lt;br /&gt;
 &lt;br /&gt;
Recíprocamente: si el tamaño de la colección se mantiene relativamente estable, entonces un vector o un deque pueden utilizar menos memoria que un list o un set que almacenen el mismo número de elementos.&lt;br /&gt;
|-&lt;br /&gt;
| Es posible determinar el tamaño de la colección?&lt;br /&gt;
| La estructura de datos vector proporciona un medio para pre-seleccionar un bloque de memoria de un tamaño específico con la función miembro reserve, posibilidad que no existe en otros contenedores.&lt;br /&gt;
|-&lt;br /&gt;
| Es frecuente tener que comprobar si un valor cualquiera está incluido en la colección?&lt;br /&gt;
| En este caso, un contenedor set o map pueden ser buena elección. En estos casos comprobar si un determinado valor está incluido puede ser realizado con un pequeño número de pasos (logarítmicos con el tamaño del contenedor). Mientras que la misma verificación en cualquiera de los otros tipos puede requerir comparar el valor con cada elemento almacenado en el contenedor.&lt;br /&gt;
|-&lt;br /&gt;
| Está indexada la colección de datos? &lt;br /&gt;
| Si las claves son enteros entre 0 y un límite superior, pueden utilizarse un vector o un deque. &lt;br /&gt;
|-&lt;br /&gt;
| Si es así, puede ser vista la colección como una serie de pares clave/valor?&lt;br /&gt;
| Si la clave es algún otro valor, como cadenas de caracteres o tipos definidos por el usuario, puede utilizarse un contenedor map.&lt;br /&gt;
|-&lt;br /&gt;
| Pueden los valores estar relacionados unos con otros?&lt;br /&gt;
| Todos los valores almacenados en cualquier contenedor de la STL debe ser capaz de comprobar la igualdad con cualquier otro valor similar, pero recuerde que no todos son capaces de reconocer el operador de relación menor-que; sin embargo, si los valores no pueden ser ordenados utilizando el operador menor-que, no pueden ser almacenados en un set o en un map.&lt;br /&gt;
|-&lt;br /&gt;
| Es una operación frecuente tener que encontrar y eliminar el valor mayor de la colección?&lt;br /&gt;
| En caso afirmativo, la estructura de datos más idónea es el priority queue.&lt;br /&gt;
|-&lt;br /&gt;
| En que posiciones son insertados o eliminados los elementos de la estructura?&lt;br /&gt;
| Si los valores son añadidos o eliminados en la zona interior, entonces la mejor opción es un list.&lt;br /&gt;
 &lt;br /&gt;
Si los valores son insertados solo al comienzo, un deque o un list pueden ser lo más adecuado.&lt;br /&gt;
&lt;br /&gt;
Si los valores son insertados y eliminados solo al final, un stack o un queue pueden ser elecciones lógicas.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| Es frecuente tener que refundir dos o más secuencias en una sola?&lt;br /&gt;
| En caso afirmativo, puede considerarse que las mejores opciones son un set o un list, dependiendo que la colección deba o no ser mantenida en orden.&lt;br /&gt;
 &lt;br /&gt;
Refundir dos set es una operación muy eficiente.  Si la colección de datos no está ordenada, pero puede utilizarse la función miembro splice() de las list (que es muy eficiente), entonces es preferible este último tipo de contenedor, dado que esta operación no está contemplada en las demás formas.&lt;br /&gt;
|}&lt;br /&gt;
=== Tipos no incluidos ===&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] incluye contenedores adecuados para la mayoría de los casos prácticos, aunque quizás existen una serie de estructuras de datos clásicas que no han sido incluidas. En la mayoría de los casos, la causa es que los contenedores proporcionados pueden ser fácilmente adaptados para suplir los usos facilitados por los tipos omitidos.&lt;br /&gt;
&lt;br /&gt;
Tipos clásicos no incluidos y la sustitución más fácil.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Contenedor omitido&lt;br /&gt;
! Sustitución utilizando elementos de STL&lt;br /&gt;
|-&lt;br /&gt;
| tree&lt;br /&gt;
| El modo set está implementado internamente como un árbol de búsqueda binaria. &lt;br /&gt;
&lt;br /&gt;
Para la mayoría de los casos prácticos que pueden ser resueltos utilizando árboles este modo es un sustituto adecuado.&lt;br /&gt;
|-&lt;br /&gt;
| matrices multidimensionales&lt;br /&gt;
| Puesto que los vectores pueden almacenar elementos que sean otros vectores, estas estructuras pueden ser construidas fácilmente.&lt;br /&gt;
|-&lt;br /&gt;
| graph&lt;br /&gt;
| La representación de un gráfico puede ser fácilmente construida como un map que contiene otros map. Un map cuyos elementos son a su vez maps, es la representación natural de un gráfico directo. &lt;br /&gt;
|-&lt;br /&gt;
| sparse array&lt;br /&gt;
| Una novedosa sustitución es la representación de un gráfico&lt;br /&gt;
|-&lt;br /&gt;
| hash table&lt;br /&gt;
| Las tablas hash proporcionan un tiempo de acceso constante, así como inserción y borrado de elementos, convirtiendo estas operaciones en operaciones de índice.&lt;br /&gt;
 &lt;br /&gt;
Una tabla hash puede ser construida fácilmente como un vector (o deque) cuyos elementos son lists (o incluso sets).  En el ejemplo de la ordenación raíz (  xxx) se describe una de estas estructuras (un vector de deques), aunque en este ejemplo no incluye invocación la función hash para convertir un valor en un índice.&lt;br /&gt;
|-&lt;br /&gt;
| Funcionalidad set&lt;br /&gt;
| En la STL, los tipos set están específicamente ordenados, y sus operaciones (como la unión intersección, etc.) no pueden ser realizadas sobre colecciones de valores no ordenados (por ejemplo un conjunto de números complejos).&lt;br /&gt;
 &lt;br /&gt;
Una list puede ser utilizada como sustituto, aunque es necesario escribir funciones de operación especiales, dado que los algoritmos genéricos no pueden ser utilizados con listas.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Gestión de memoria ==&lt;br /&gt;
La gestión de memoria realizada por los contenedores comprende tanto la asignación y liberación de espacio para sus miembros, como para las claves que constituyen el sistema de índice de algunos tipos de contenedor. En general los algoritmos de la STL están muy optimizados y el sistema de asignación de memoria intenta compaginar rapidez y eficacia. La primera exige asignar y desasignar espacio cada vez que se introduce o elimina un miembro del contenedor. La eficacia, e incluso la disminución de la fragmentación inherentes al manejo del montón, exige asignar y rehusar trozos de memoria lo más grandes posible cada vez. El abordaje a este problema se ha realizado de dos formas básicas: (a) Contenedores que no pueden alterar su tamaño, de forma que la asignación de espacio para sus elementos debe realizarse en el momento de su declaración. (b) Contenedores que pueden crecer y/o disminuir en consonancia con los elementos a albergar.&lt;br /&gt;
&lt;br /&gt;
Refiriéndonos al caso (b), para balancear estas exigencias contrapuestas, algunas implementaciones utilizan el siguiente esquema de trabajo: inicialmente el sistema asigna al contenedor un trozo de memoria de tamaño adecuado para contener cierto número de elementos; espacio que es utilizando hasta que se agota. A partir de aquí, cada nueva demanda origina la asignación una zona de doble tamaño que la anterior. Por ejemplo, supongamos que para gestionar un vector de enteros, el compilador asigna inicialmente espacio para un máximo de 16 miembros.  Cuando se agotara, se realizaría una nueva asignación de espacio para 32 miembros, e inmediatamente se efectuaría una recolocación del contenido actual en el nuevo espacio y la liberación del primitivo. Si el nuevo contenedor quedara lleno de nuevo, la siguiente asignación sería capaz de 64 miembros y así sucesivamente.&lt;br /&gt;
&lt;br /&gt;
El factor de aumento de tamaño puede ser cualquiera. Muchos compiladores utilizan un factor 1.5 cada vez que deben ampliar el espacio necesario.&lt;br /&gt;
&lt;br /&gt;
Cada nueva recolocación implica varios pasos:&lt;br /&gt;
  •	Asignación de memoria al estilo malloc() de la librería clásica en cantidad suficiente para el nuevo tamaño.&lt;br /&gt;
  •	Copia de los elementos actuales en la nueva localización. Los elementos son colocados en la nueva situación utilizando el constructor copia.&lt;br /&gt;
  •	Actualización de las estructuras internas del nuevo contenedor (sistema de índices).&lt;br /&gt;
  •	Eliminación de los elementos originales mediante invocación sucesiva de sus correspondientes destructores.&lt;br /&gt;
  •	Liberación de la memoria utilizada por las estructuras internas.&lt;br /&gt;
  •	Liberación de la zona original mediante una invocación al estilo free de la librería clásica.&lt;br /&gt;
&lt;br /&gt;
En general, al referirse al tamaño de un contenedor existen tres magnitudes distintas aunque relacionadas, cuyos valores pueden obtenerse mediante tres métodos:&lt;br /&gt;
&lt;br /&gt;
  •	El número de elementos contenidos actualmente. size()&lt;br /&gt;
  •	El máximo número de elementos que pueden alcanzarse actualmente sin necesidad de una nueva recolocación. capacity()&lt;br /&gt;
  •	El máximo número de elementos que pueden alcanzarse en cualquier caso. max_size().&lt;br /&gt;
&lt;br /&gt;
 Ejemplo:&lt;br /&gt;
   #include &amp;lt;iostream&amp;gt;&lt;br /&gt;
   using namespace std;&lt;br /&gt;
   #include &amp;lt;vector&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   int main() {         // ================&lt;br /&gt;
   vector&amp;lt;int&amp;gt; vInt;&lt;br /&gt;
   for (int i=0; i &amp;lt; 100; i++) vInt.push_back(i);&lt;br /&gt;
&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Tamaño actual:   &amp;quot; &amp;lt;&amp;lt; vInt.size()     &amp;lt;&amp;lt; endl;&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Capacidad actual: &amp;quot; &amp;lt;&amp;lt; vInt.capacity() &amp;lt;&amp;lt; endl;&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Tamano maximo:   &amp;quot; &amp;lt;&amp;lt; vInt.max_size() &amp;lt;&amp;lt; endl;&lt;br /&gt;
   return 0;&lt;br /&gt;
   }&lt;br /&gt;
   Salida:&lt;br /&gt;
   Tamaño actual: 100&lt;br /&gt;
   Capacidad actual: 256&lt;br /&gt;
   Tamano maximo: 1073741823&lt;br /&gt;
&lt;br /&gt;
En todos los casos: size() &amp;lt;= capacity()&lt;br /&gt;
&lt;br /&gt;
Es posible comprobar si un contenedor está vacío, comparando su tamaño actual size() con cero, aunque es más rápido utilizar el método empty(), que devuelve true si realmente size() == 0.&lt;br /&gt;
&lt;br /&gt;
=== Reserva de espacio ===&lt;br /&gt;
Como puede suponer, cada recolocación supone un proceso considerable, sobre todo en contenedores muy grandes. Para evitar sus inconvenientes si se conoce de antemano el tamaño máximo a utilizar, la STL ofrece la posibilidad de preasignar un espacio arbitrario. Para esto se dispone del método reserve(n), que garantiza la asignación de espacio inicial suficiente para alojar n miembros en el contenedor. Si el argumento n es mayor que la capacidad actual, se produce una recolocación y el nuevo argumento determina la nueva capacidad. Si es menor no se produce ninguna acción.&lt;br /&gt;
&lt;br /&gt;
Ejemplo, para crear un vector de enteros capaz para al menos 1000 miembros:&lt;br /&gt;
  vector &amp;lt;int&amp;gt; v;&lt;br /&gt;
  v.reserve(1000);&lt;br /&gt;
&lt;br /&gt;
En el siguiente ejemplo se muestran los resultados compilado con Borland C++ 5.5 para Win32; con MS Visual C++ 6.0 y con GNU gcc 2.95.3 para Linux:&lt;br /&gt;
  // resultados con:         BC++   VC++   GNU   &lt;br /&gt;
  vector&amp;lt;int&amp;gt; v;&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 0      0      0   &lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 0      0      0&lt;br /&gt;
  v.push_back(3);&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    1      1&lt;br /&gt;
  v.reserve(100);&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    100    100&lt;br /&gt;
&lt;br /&gt;
=== Operaciones sobre contenedores ===&lt;br /&gt;
Los elementos de un contenedor son colocados en él utilizando el constructor copia, aunque algunas operaciones requieren la existencia de un constructor por defecto. A su vez, los algoritmos genéricos, como copy(), que copian a un contenedor, utilizan el operador de asignación.&lt;br /&gt;
&lt;br /&gt;
Cuando se duplica todo un contenedor de tipos T por invocación del [[Constructor (C++)|constructor]] copia o por asignación, cada miembro es copiado en la nueva estructura utilizando el constructor copia o el operador de asignación. Tanto si una copia profunda o una copia somera, el resultado es controlado por el programador, que puede proporcionar el operador de asignación para el tipo T con cualquier significado que desee. Si se ha definido un destructor para el tipo T, este destructor es invocado cada vez que deba ser eliminado un elemento del contenedor. Cuando se destruye toda la colección, el destructor es invocado por cada elemento que permaneciera almacenado.&lt;br /&gt;
&lt;br /&gt;
En estos casos, el contenedor es solamente responsable de mantener los propios punteros, siendo responsabilidad del programador manejar la memoria de los valores referenciados por estos, lo que supone que los espacios de memoria son asignados correctamente; por lo general mediante el operador new; que no son desasignados mientras el contenedor albergue referencias a ellos, y que sean adecuadamente desasignados una vez que han sido eliminados del contenedor.&lt;br /&gt;
&lt;br /&gt;
===  Secuencias ===&lt;br /&gt;
Las secuencias son estructuras de datos de tipo lineal, con posibilidad de que su tamaño puede ser alterado insertando elementos al principio, al final o en cualquier posición, si bien la idoneidad en este sentido es distinta entre los diversos tipos.&lt;br /&gt;
&lt;br /&gt;
La STL ofrece los siguientes:&lt;br /&gt;
  • deque&lt;br /&gt;
  • list&lt;br /&gt;
  • stack&lt;br /&gt;
  • vector&lt;br /&gt;
  • vector&amp;lt;bool&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La estructura lineal implica que sus datos son lógicamente contiguos, aunque su disposición física puede que no lo sea. Los elementos pueden ser accedidos por un índice numérico, aunque en algunos tipos de secuencia el acceso a un elemento implica un recorrido por la lista.&lt;br /&gt;
&lt;br /&gt;
== Contenedores asociativos ==&lt;br /&gt;
Los contenedores asociativos son una extensión de las secuencias. Mientras que en estas para acceder a los elementos solo pueden utilizarse claves numéricas, que señalan el número de orden del elemento dentro de la secuencia (al estilo de los índices en las matrices). Los contenedores asociativos admiten cualquier tipo de clave de acceso. Las más frecuentes son las cadenas alfanuméricas (stings).&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, razón por la que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.&lt;br /&gt;
&lt;br /&gt;
La ordenación se realiza según los valores de ciertos miembros del contenedor. Estos elementos son denominados &amp;quot;de claves&amp;quot; (&amp;quot;Key values&amp;quot;). Lo que exige que los objetos &amp;quot;de clave&amp;quot; sean de un tipo para el que estén definidos los operadores relacionales. El contenedor es mantenido ordenado de forma automática por los algoritmos de inserción y borrado.&lt;br /&gt;
&lt;br /&gt;
La STL proporciona cinco tipo distintos, aunque en realidad son tres clases; dos de ellas en dos variedades (permitiendo o no claves duplicadas). Uno de los tipos (bitset) sirve para almacenar campos de bits de longitud constante. Los otros dos permiten elementos ordenados de cualquier tipo (set y multiset), mientras que map y multimap permiten alojar pares de elementos. Uno que actúa como &amp;quot;Key value&amp;quot; y otro que puede ser un tipo cualquiera al que llamaremos valor-dato.&lt;br /&gt;
&lt;br /&gt;
  • bitset&lt;br /&gt;
  • set&lt;br /&gt;
  • multiset&lt;br /&gt;
  • map&lt;br /&gt;
  • multimap&lt;br /&gt;
&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave, y para recorrer el conjunto (ordenado) de las claves.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http://www.zator.com/Cpp/E5_1_1.htm Contenerores C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Contenedores en C.conclase.net]&lt;br /&gt;
* [https://docs.microsoft.com/es-es/cpp/standard-library/stl-containers?view=vs-2017  Contenedores de la biblioteca estándar de C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234267</id>
		<title>Contenedores C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234267"/>
		<updated>2018-11-29T18:34:09Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Contenedores C++ |imagen=  |concepto= En sentido [[C++|C++]] estricto, un contenedor de la STL es una clase genérica que puede instanciarse para representar diversos tipos de objetos. Esta clase incluye ciertas operaciones  sobre los objetos de su tipo; estas operaciones están representadas por [[Función (programación)|funciones]]-miembro, incluyendo [[Constructores (Programación)|constructores]] y funciones-[[Operadores|operador]], que son a su vez funciones genéricas}}''' Contenedores [[C++|C++]] '''. Al mismo tiempo, desde el punto de vista de las teorías de la información, podemos considerarlos estructuras de datos más o menos adecuadas (según el caso) para aplicarles ciertos algoritmos.&lt;br /&gt;
De su propio nombre (&amp;quot;Containers&amp;quot;) podemos deducir que su misión principal, y razón de su existencia, es su función como estructuras de datos, y en este sentido podemos adelantar que entre sus funcionalidades más destacadas se encuentran la gestión del espacio de almacenamiento necesario.&lt;br /&gt;
Una de las primerísimas ventajas de la utilización de contenedores es que el programador no tiene que enredarse con las cuestiones siempre espinosas de asignar o liberar memoria para los objetos creados, de forma que queda liberado de los [[Operadores|operadores]] [[Operador new|new]] y [[Operador delete|delete]].&lt;br /&gt;
== Filosofía de uso ==&lt;br /&gt;
Una primera pincelada sobre la filosofía de uso de los contenedores mediante un sencillo ejemplo: si tenemos que manejar un conjunto de enteros, puede utilizarse una matriz de enteros, pero ya hemos señalado  que esta estructura nos obliga a conocer de antemano la cantidad de datos a almacenar (el tamaño de la matriz). En consecuencia, si el número de datos puede variar, esta opción no es muy adecuada. Además, si es importante mantener los datos ordenados, la utilización de una matriz nos obligaría a ingeniar por nuestra cuenta la forma de hacerlo; seguramente mediante complicadas rutinas de &amp;quot;sort&amp;quot; hechas manualmente.&lt;br /&gt;
&lt;br /&gt;
Una alternativa es utilizar como &amp;quot;contenedor&amp;quot; para nuestros enteros una clase genérica de la STL denominada vector. En este caso, serían posibles expresiones como las siguientes:&lt;br /&gt;
&lt;br /&gt;
  vector&amp;lt;int&amp;gt; v(3);         // L1:&lt;br /&gt;
  v[0] = 7;                 // L2:&lt;br /&gt;
  v[1] = v[0] + 1;          // L3:&lt;br /&gt;
  v[2] = v[0] + v[1];       // L4:&lt;br /&gt;
&lt;br /&gt;
Al encontrar la primera sentencia, el compilador crea una instancia (especialidad) anónima de la plantilla vector para alojar enteros; a continuación una instancia de ella para alojar tres enteros, a la que denominamos v.&lt;br /&gt;
&lt;br /&gt;
Una primera inspección de las sentencias L2 a L3, nos muestra que la clase ofrece la posibilidad de utilizar con sus miembros el operador subíndice de matriz [ ]. Deducimos por tanto, que dispone de una versión sobrecargada de este operador para los miembros de la clase, lo que nos permite utilizar el objeto v como una matriz, aunque con algunas funcionalidades no incluidas en aquellas.&lt;br /&gt;
&lt;br /&gt;
Después de L4 los valores finales para los miembros de nuestra &amp;quot;matriz&amp;quot; serian:&lt;br /&gt;
 v[0] == 7, v[1] == 8, v[2] == 15&lt;br /&gt;
&lt;br /&gt;
Si deseamos invertir el orden de los elementos de nuestra matriz. Para ello utilizamos una [[Función (programación)|función]] especial:&lt;br /&gt;
&lt;br /&gt;
 reverse(v.begin(), v.end());&lt;br /&gt;
&lt;br /&gt;
después de lo cual, el orden de miembros sería:&lt;br /&gt;
&lt;br /&gt;
 v[0] == 15, v[1] == 8, v[2] == 7&lt;br /&gt;
&lt;br /&gt;
La primera observación es que la función reverse utiliza dos argumentos, que son a su vez el valor devuelto por sendos métodos de clase (los aplicamos sobre nuestro objeto v).  El valor devuelto por estos métodos es lo que se conoce como un [[Iteradores (Programación)|iterador]]; una especie de puntero que señalan al interior de la estructura de datos representada por el contenedor v. En este caso, el primer iterador señala al primer miembro y el segundo a una posición después del último; de esta forma se indican los miembros inicial y final entre los que se realizará la operación de inversión efectuada por reverse.&lt;br /&gt;
&lt;br /&gt;
La segunda observación es que la función reverse no es un método de clase, sino una función global; es lo que denominamos un [[Algoritmo|algoritmo]]. Esta función tiene la peculiaridad de que puede ser aplicado sobre el contenedor vector (y algún otro); que opera sobre un rango de los elementos del contenedor, en nuestro caso sobre la totalidad (esta capacidad de operar sobre una parte de un contenedor es característica de los algoritmos). También que pueden operar sobre otros contenedores produciendo un efecto similar. Por ejemplo, el algoritmo reverse puede operar incluso sobre una simple matriz:&lt;br /&gt;
 char Ch[5] = { 'A', 'E', 'I', 'O', 'U' };&lt;br /&gt;
 reverse(Ch, Ch + 5);&lt;br /&gt;
 for (int i = 0; i &amp;lt; 5; ++i) cout &amp;lt;&amp;lt; &amp;quot;Ch[&amp;quot; &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &amp;quot;] = &amp;quot; &amp;lt;&amp;lt; Ch[i];&lt;br /&gt;
 Salida:&lt;br /&gt;
 Ch[0] = U Ch[1] = O Ch[2] = I Ch[3] = E Ch[4] = A&lt;br /&gt;
&lt;br /&gt;
Es significativo que el objeto v es una estructura de datos que permite acceder individualmente a sus miembros &amp;quot;como si&amp;quot; fuesen elementos de una matriz. También que se pueden aplicar ciertas operaciones sobre la totalidad, o parte, de esta estructura considerada como una unidad.&lt;br /&gt;
== Clasificación ==&lt;br /&gt;
Existen dos tipos de contenedores: secuencias y asociativos; a su vez se subdividen según el tipo de [[Iteradores (Programación)|iterador]] que soportan.&lt;br /&gt;
&lt;br /&gt;
Las secuencias almacenan los elementos en orden secuencial (de ahí su nombre). El contenedor agrupa a todos sus miembros como una sucesión lineal, y en consecuencia son adecuadas para accesos directos y secuenciales. Un ejemplo de secuencia es una matriz. De hecho, los algoritmos que pueden aplicarse a las secuencias pueden aplicarse también a las matrices.&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, por lo que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.  La STL proporciona cinco tipos distintos.&lt;br /&gt;
&lt;br /&gt;
La existencia de índices supone una ordenación según los valores de un conjunto de elementos (denominado &amp;quot;de claves&amp;quot;) para el que debe existir un criterio de ordenación. Dicho en otras palabras, los objetos &amp;quot;de clave&amp;quot; deben ser de un tipo para el que estén definidos los operadores relacionales. El árbol es mantenido ordenado de forma automática por los algoritmos de inserción y borrado del contenedor.&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave y para recorrer el conjunto (ordenado) de los elementos.&lt;br /&gt;
&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] contiene diez formas de contenedores y tres adaptadores de contenedor (denominados simplemente [[Adapter|adaptadores]]). En esta sección se expondrán brevemente cuales son estas formas; sus características, y cuál es la más adecuada para cada tipo de problema específico. En secciones sucesivas se comentarán individualmente con mayor detalle.&lt;br /&gt;
Relación siguiendo la clasificación utilizada en el Estándar:&lt;br /&gt;
  • Secuencias&lt;br /&gt;
      o	deque&lt;br /&gt;
      o	list&lt;br /&gt;
      o	stack&lt;br /&gt;
      o	vector&lt;br /&gt;
      o	vector &amp;lt;bool&amp;gt;&lt;br /&gt;
  • adaptadores&lt;br /&gt;
      o	queue&lt;br /&gt;
      o	priority_queue&lt;br /&gt;
  • Contenedores asociativos&lt;br /&gt;
      o	map&lt;br /&gt;
      o	multimap&lt;br /&gt;
      o	set&lt;br /&gt;
      o	multiset&lt;br /&gt;
      o	bitset&lt;br /&gt;
== Características ==&lt;br /&gt;
Las características más significativas de las diversas formas de contenedor son:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Contenedor&lt;br /&gt;
! Características&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;big&amp;gt;Secuencias&amp;lt;/big&amp;gt;&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| vector&lt;br /&gt;
| Este contenedor es una estructura de datos de tamaño fijo preferentemente. Aunque la STL proporciona herramientas para cambiar el tamaño de un vector de forma dinámica, esta operación es costosa y debe ser evitada dentro de lo posible (en este sentido el vector se comporta como una matriz ordinaria).&lt;br /&gt;
&lt;br /&gt;
Disponen de un buén mecanismo de acceso aleatorio a elementos y de un mecanismo de inserción al final muy eficiente.&lt;br /&gt;
&lt;br /&gt;
Generalmente es preferible utilizar un vector que un deque o un list, a menos que sea frecuentemente necesario insertar datos al comienzo o al final, en cuyo caso es mejor utilizar un deque.  Si por el contrario es frecuente la inserción de elementos en el centro, entonces es preferible un list.&lt;br /&gt;
|-&lt;br /&gt;
| vector&amp;lt;bool&amp;gt;&lt;br /&gt;
| Es una versión de la anterior especial para valores binarios (bits).&lt;br /&gt;
|-&lt;br /&gt;
| list&lt;br /&gt;
| Este contenedor responde a la idéa intuitiva de &amp;quot;lista&amp;quot;, el almacenamiento de objetos en una secuencia lineal que no está necesariamente ordenada (aunque sus miembros pueden ser ordenados fácilmente mediante la función-miembro sort() ). Estos contenedores suelen ser implementados como listas doblemente enlazadas. &lt;br /&gt;
&lt;br /&gt;
Dispone de mecanismos eficientes para insertar elementos al principio, al final o en cualquier posición (utilizando iteradores que denoten posición). Estas operaciones consumen un tiempo constante con independencia del número de elmentos albergados en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Dado que son estructuras lineales, en general los elementos no pueden ser accedidos por subíndices como en un vector.  Es necesario realizar un recorrido lineal por todos los valores, por lo que en las operaciones de acceso se utilizan tiempos proporcionales al número de elementos.&lt;br /&gt;
|-&lt;br /&gt;
| stack&lt;br /&gt;
| Contenedor de elementos tipo pila LIFO que permite inserciones y eliminaciones solo en la parte superior.&lt;br /&gt;
|-&lt;br /&gt;
| deque&lt;br /&gt;
| Los deques o colas de doble terminación (&amp;quot;Double-ended queue&amp;quot;) son un tipo de estructura de datos que comparte las características de las colas (&amp;quot;Queues&amp;quot;) y las pilas (&amp;quot;Stacks&amp;quot;). Como en las colas , los elementos pueden ser empujados por un extremo al interior del contenedor, y el primer elemento introducido puede ser extraído por el extremo opuesto. Al mismo tiempo, el último elemento introducido por el principio puede ser extraído en ese mismo extremo como si fuese una pila.&lt;br /&gt;
 &lt;br /&gt;
Estos contenedores suelen ser implementados bajo la forma de matrices bidimensionales.&lt;br /&gt;
&lt;br /&gt;
Las características de los deques implementados en la STL pueden resumirse en: Acceso aleatorio; mecanismo eficiente de inserción al principio o al final.&lt;br /&gt;
|-&lt;br /&gt;
| string&lt;br /&gt;
| Contenedor de caracteres adaptado a operaciones con cadenas de caracteres.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;big&amp;gt;Asociaciones&amp;lt;/big&amp;gt;&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| set&lt;br /&gt;
| Como el resto de contenedores asociativos, esta forma de contenedor mantiene los elementos en orden. Dispone de mecanismos eficientes para inclusión, inserción y eliminación de elementos, y soporta claves únicas (solo puede existir un miembro con una clave determinada).&lt;br /&gt;
|-&lt;br /&gt;
| multiset&lt;br /&gt;
| Versión del anterior que permite la existencia de claves duplicadas. Es decir, distintos elementos dentro del conjunto pueden responder a la misma clave.&lt;br /&gt;
|-&lt;br /&gt;
| bitset&lt;br /&gt;
| Contenedor de bit más orientado al tamaño que hacia el tipo de contenido. Permite almacenar secuencias de bits de tamaño fijo. No existen iteradores para reccorrerlas, y sus elementos se acceden utilizando el operador subíndice.&lt;br /&gt;
 &lt;br /&gt;
Se dispone de varias funciones para realizar con ellos operaciones de bits &lt;br /&gt;
|-&lt;br /&gt;
| map&lt;br /&gt;
| Como el resto de estructuras asociativas, el map mantiene sus elementos ordenados. Se caracteriza porque sus miembros son pares de valores que pueden ser de tipos distintos. Uno de ellos, el que actúa como clave para el índice (&amp;quot;Key-value&amp;quot;), puede ser de cualquier tipo, a condición de que sus elementos puedan ser ordenados según un criterio (por defecto se utiliza el operador &amp;lt;).&lt;br /&gt;
 &lt;br /&gt;
Permite claves únicas. Es decir, que solo puede existir un miembro para cada clave. Dispone de mecanismos de inserción y borrado muy eficientes y no existe límite de tamaño. La estructura se encarga de crecer y disminuir en concordancia con las necesidades de sus miembros. Permite el operador [ ] subíndice para los elementos de la clave así como otras técnicas de acceso.&lt;br /&gt;
&lt;br /&gt;
Estas estructuras de datos recibe también los nombres de diccionarios, tablas y matrices asociativas, en referencia a que pueden considerarse como dos matrices del mismo número de elementos, en las que existe una relación entre cada miembro de una con otro miembro de la otra.  Una de las matrices (que actúa de índice) estaría ordenada según su contenido&lt;br /&gt;
|-&lt;br /&gt;
| multimap&lt;br /&gt;
| En todo igual que el anterior pero permitiendo además claves duplicadas. Es decir, que una misma clave pueda estar asociada a dos &amp;quot;valores&amp;quot; distintos.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Adaptador&lt;br /&gt;
! Características&lt;br /&gt;
|-&lt;br /&gt;
| queue&lt;br /&gt;
| Contenedor tipo cola FIFO que permite inserciones al final y eliminaciones al principio.&lt;br /&gt;
|-&lt;br /&gt;
| priority queue&lt;br /&gt;
| Este contenedor dispone de mecanismos eficientes para acceso y eliminación de grandes valores.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Seleccionar un contenedor ==&lt;br /&gt;
El binomio contendor-iterador conforma una herramienta que se adapta a circunstancias muy variadas. Es posible que un determinado problema pueda ser abordado de varias formas, en estos casos la selección de la forma de contenedor más adecuado depende de las circunstancias. En ciertas ocasiones puede resultar bastante obvia; en otras puede no estar tan claro cuál es la mejor opción, pues &amp;quot;a priori&amp;quot;, pueden adaptarse varias formas al caso concreto. Puede utilizarse el sistema de prueba y comparación. Por ejemplo, cronometrando los resultados obtenidos en un modo u otro. También será de gran ayuda la experiencia, pero como una guía o criterio general puede utilizarse el principio de selección que se indica a continuación.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Como se accederá a los datos?.&lt;br /&gt;
| Si es importante un acceso aleatorio, pueden utilizarse un vector o un deque. Si basta con un acceso secuencial cualquiera de los dos puede ser el elegido.&lt;br /&gt;
|-&lt;br /&gt;
| Es importante el orden en que serán mantenidos los valores dentro de la colección de datos?&lt;br /&gt;
| Existen muchas formas de secuenciar los valores. Si es importante un orden estricto a lo largo de toda la vida del contenedor, la elección obvia es un set, dado que las inserciones en una de estas estructuras se realizan automáticamente en orden.&lt;br /&gt;
 &lt;br /&gt;
Si este orden es importante solo en algún momento, por ejemplo al final de una serie de inserciones, puede ser más sencillo colocar los valores en un list o vector para ordenar más tarde el resultado en el momento necesario.&lt;br /&gt;
&lt;br /&gt;
Si el orden en que se almacenan los valores en la estructura está relacionado con el orden de su inserción, entonces un stack, un queue o un list pueden ser la mejor elección.&lt;br /&gt;
|-&lt;br /&gt;
| Puede variar mucho el tamaño de la estructura de datos durante el curso de la ejecución del programa?&lt;br /&gt;
| Si es así, entonces puede ser que la mejor opción sean un list o un set. Un vector o un deque pueden conducir a mantener un gran almacenamiento intermedio (buffer); incluso después que los elementos hayan sido eliminados de la colección de datos. Estos dos contenedores no son adecuados para cambios de tamaño, aunque vector dispone de un mecanismo de inserción al final eficiente.&lt;br /&gt;
 &lt;br /&gt;
Recíprocamente: si el tamaño de la colección se mantiene relativamente estable, entonces un vector o un deque pueden utilizar menos memoria que un list o un set que almacenen el mismo número de elementos.&lt;br /&gt;
|-&lt;br /&gt;
| Es posible determinar el tamaño de la colección?&lt;br /&gt;
| La estructura de datos vector proporciona un medio para pre-seleccionar un bloque de memoria de un tamaño específico con la función miembro reserve, posibilidad que no existe en otros contenedores.&lt;br /&gt;
|-&lt;br /&gt;
| Es frecuente tener que comprobar si un valor cualquiera está incluido en la colección?&lt;br /&gt;
| En este caso, un contenedor set o map pueden ser buena elección. En estos casos comprobar si un determinado valor está incluido puede ser realizado con un pequeño número de pasos (logarítmicos con el tamaño del contenedor). Mientras que la misma verificación en cualquiera de los otros tipos puede requerir comparar el valor con cada elemento almacenado en el contenedor.&lt;br /&gt;
|-&lt;br /&gt;
| Está indexada la colección de datos? &lt;br /&gt;
| Si las claves son enteros entre 0 y un límite superior, pueden utilizarse un vector o un deque. &lt;br /&gt;
|-&lt;br /&gt;
| Si es así, puede ser vista la colección como una serie de pares clave/valor?&lt;br /&gt;
| Si la clave es algún otro valor, como cadenas de caracteres o tipos definidos por el usuario, puede utilizarse un contenedor map.&lt;br /&gt;
|-&lt;br /&gt;
| Pueden los valores estar relacionados unos con otros?&lt;br /&gt;
| Todos los valores almacenados en cualquier contenedor de la STL debe ser capaz de comprobar la igualdad con cualquier otro valor similar, pero recuerde que no todos son capaces de reconocer el operador de relación menor-que; sin embargo, si los valores no pueden ser ordenados utilizando el operador menor-que, no pueden ser almacenados en un set o en un map.&lt;br /&gt;
|-&lt;br /&gt;
| Es una operación frecuente tener que encontrar y eliminar el valor mayor de la colección?&lt;br /&gt;
| En caso afirmativo, la estructura de datos más idónea es el priority queue.&lt;br /&gt;
|-&lt;br /&gt;
| En que posiciones son insertados o eliminados los elementos de la estructura?&lt;br /&gt;
| Si los valores son añadidos o eliminados en la zona interior, entonces la mejor opción es un list.&lt;br /&gt;
 &lt;br /&gt;
Si los valores son insertados solo al comienzo, un deque o un list pueden ser lo más adecuado.&lt;br /&gt;
&lt;br /&gt;
Si los valores son insertados y eliminados solo al final, un stack o un queue pueden ser elecciones lógicas.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| Es frecuente tener que refundir dos o más secuencias en una sola?&lt;br /&gt;
| En caso afirmativo, puede considerarse que las mejores opciones son un set o un list, dependiendo que la colección deba o no ser mantenida en orden.&lt;br /&gt;
 &lt;br /&gt;
Refundir dos set es una operación muy eficiente.  Si la colección de datos no está ordenada, pero puede utilizarse la función miembro splice() de las list (que es muy eficiente), entonces es preferible este último tipo de contenedor, dado que esta operación no está contemplada en las demás formas.&lt;br /&gt;
|}&lt;br /&gt;
=== Tipos no incluidos ===&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] incluye contenedores adecuados para la mayoría de los casos prácticos, aunque quizás existen una serie de estructuras de datos clásicas que no han sido incluidas. En la mayoría de los casos, la causa es que los contenedores proporcionados pueden ser fácilmente adaptados para suplir los usos facilitados por los tipos omitidos.&lt;br /&gt;
&lt;br /&gt;
Tipos clásicos no incluidos y la sustitución más fácil.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Contenedor omitido&lt;br /&gt;
! Sustitución utilizando elementos de STL&lt;br /&gt;
|-&lt;br /&gt;
| tree&lt;br /&gt;
| El modo set está implementado internamente como un árbol de búsqueda binaria. &lt;br /&gt;
&lt;br /&gt;
Para la mayoría de los casos prácticos que pueden ser resueltos utilizando árboles este modo es un sustituto adecuado.&lt;br /&gt;
|-&lt;br /&gt;
| matrices multidimensionales&lt;br /&gt;
| Puesto que los vectores pueden almacenar elementos que sean otros vectores, estas estructuras pueden ser construidas fácilmente.&lt;br /&gt;
|-&lt;br /&gt;
| graph&lt;br /&gt;
| La representación de un gráfico puede ser fácilmente construida como un map que contiene otros map. Un map cuyos elementos son a su vez maps, es la representación natural de un gráfico directo. &lt;br /&gt;
|-&lt;br /&gt;
| sparse array&lt;br /&gt;
| Una novedosa sustitución es la representación de un gráfico&lt;br /&gt;
|-&lt;br /&gt;
| hash table&lt;br /&gt;
| Las tablas hash proporcionan un tiempo de acceso constante, así como inserción y borrado de elementos, convirtiendo estas operaciones en operaciones de índice.&lt;br /&gt;
 &lt;br /&gt;
Una tabla hash puede ser construida fácilmente como un vector (o deque) cuyos elementos son lists (o incluso sets).  En el ejemplo de la ordenación raíz (  xxx) se describe una de estas estructuras (un vector de deques), aunque en este ejemplo no incluye invocación la función hash para convertir un valor en un índice.&lt;br /&gt;
|-&lt;br /&gt;
| Funcionalidad set&lt;br /&gt;
| En la STL, los tipos set están específicamente ordenados, y sus operaciones (como la unión intersección, etc.) no pueden ser realizadas sobre colecciones de valores no ordenados (por ejemplo un conjunto de números complejos).&lt;br /&gt;
 &lt;br /&gt;
Una list puede ser utilizada como sustituto, aunque es necesario escribir funciones de operación especiales, dado que los algoritmos genéricos no pueden ser utilizados con listas.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Gestión de memoria ==&lt;br /&gt;
La gestión de memoria realizada por los contenedores comprende tanto la asignación y liberación de espacio para sus miembros, como para las claves que constituyen el sistema de índice de algunos tipos de contenedor. En general los algoritmos de la STL están muy optimizados y el sistema de asignación de memoria intenta compaginar rapidez y eficacia. La primera exige asignar y desasignar espacio cada vez que se introduce o elimina un miembro del contenedor. La eficacia, e incluso la disminución de la fragmentación inherentes al manejo del montón, exige asignar y rehusar trozos de memoria lo más grandes posible cada vez. El abordaje a este problema se ha realizado de dos formas básicas: (a) Contenedores que no pueden alterar su tamaño, de forma que la asignación de espacio para sus elementos debe realizarse en el momento de su declaración. (b) Contenedores que pueden crecer y/o disminuir en consonancia con los elementos a albergar.&lt;br /&gt;
&lt;br /&gt;
Refiriéndonos al caso (b), para balancear estas exigencias contrapuestas, algunas implementaciones utilizan el siguiente esquema de trabajo: inicialmente el sistema asigna al contenedor un trozo de memoria de tamaño adecuado para contener cierto número de elementos; espacio que es utilizando hasta que se agota. A partir de aquí, cada nueva demanda origina la asignación una zona de doble tamaño que la anterior. Por ejemplo, supongamos que para gestionar un vector de enteros, el compilador asigna inicialmente espacio para un máximo de 16 miembros.  Cuando se agotara, se realizaría una nueva asignación de espacio para 32 miembros, e inmediatamente se efectuaría una recolocación del contenido actual en el nuevo espacio y la liberación del primitivo. Si el nuevo contenedor quedara lleno de nuevo, la siguiente asignación sería capaz de 64 miembros y así sucesivamente.&lt;br /&gt;
&lt;br /&gt;
El factor de aumento de tamaño puede ser cualquiera. Muchos compiladores utilizan un factor 1.5 cada vez que deben ampliar el espacio necesario.&lt;br /&gt;
&lt;br /&gt;
Cada nueva recolocación implica varios pasos:&lt;br /&gt;
  •	Asignación de memoria al estilo malloc() de la librería clásica en cantidad suficiente para el nuevo tamaño.&lt;br /&gt;
  •	Copia de los elementos actuales en la nueva localización. Los elementos son colocados en la nueva situación utilizando el constructor copia.&lt;br /&gt;
  •	Actualización de las estructuras internas del nuevo contenedor (sistema de índices).&lt;br /&gt;
  •	Eliminación de los elementos originales mediante invocación sucesiva de sus correspondientes destructores.&lt;br /&gt;
  •	Liberación de la memoria utilizada por las estructuras internas.&lt;br /&gt;
  •	Liberación de la zona original mediante una invocación al estilo free de la librería clásica.&lt;br /&gt;
&lt;br /&gt;
En general, al referirse al tamaño de un contenedor existen tres magnitudes distintas aunque relacionadas, cuyos valores pueden obtenerse mediante tres métodos:&lt;br /&gt;
&lt;br /&gt;
  •	El número de elementos contenidos actualmente. size()&lt;br /&gt;
  •	El máximo número de elementos que pueden alcanzarse actualmente sin necesidad de una nueva recolocación. capacity()&lt;br /&gt;
  •	El máximo número de elementos que pueden alcanzarse en cualquier caso. max_size().&lt;br /&gt;
&lt;br /&gt;
 Ejemplo:&lt;br /&gt;
   #include &amp;lt;iostream&amp;gt;&lt;br /&gt;
   using namespace std;&lt;br /&gt;
   #include &amp;lt;vector&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   int main() {         // ================&lt;br /&gt;
   vector&amp;lt;int&amp;gt; vInt;&lt;br /&gt;
   for (int i=0; i &amp;lt; 100; i++) vInt.push_back(i);&lt;br /&gt;
&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Tamaño actual:   &amp;quot; &amp;lt;&amp;lt; vInt.size()     &amp;lt;&amp;lt; endl;&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Capacidad actual: &amp;quot; &amp;lt;&amp;lt; vInt.capacity() &amp;lt;&amp;lt; endl;&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Tamano maximo:   &amp;quot; &amp;lt;&amp;lt; vInt.max_size() &amp;lt;&amp;lt; endl;&lt;br /&gt;
   return 0;&lt;br /&gt;
   }&lt;br /&gt;
   Salida:&lt;br /&gt;
   Tamaño actual: 100&lt;br /&gt;
   Capacidad actual: 256&lt;br /&gt;
   Tamano maximo: 1073741823&lt;br /&gt;
&lt;br /&gt;
En todos los casos: size() &amp;lt;= capacity()&lt;br /&gt;
&lt;br /&gt;
Es posible comprobar si un contenedor está vacío, comparando su tamaño actual size() con cero, aunque es más rápido utilizar el método empty(), que devuelve true si realmente size() == 0.&lt;br /&gt;
&lt;br /&gt;
=== Reserva de espacio ===&lt;br /&gt;
Como puede suponer, cada recolocación supone un proceso considerable, sobre todo en contenedores muy grandes. Para evitar sus inconvenientes si se conoce de antemano el tamaño máximo a utilizar, la STL ofrece la posibilidad de preasignar un espacio arbitrario. Para esto se dispone del método reserve(n), que garantiza la asignación de espacio inicial suficiente para alojar n miembros en el contenedor. Si el argumento n es mayor que la capacidad actual, se produce una recolocación y el nuevo argumento determina la nueva capacidad. Si es menor no se produce ninguna acción.&lt;br /&gt;
&lt;br /&gt;
Ejemplo, para crear un vector de enteros capaz para al menos 1000 miembros:&lt;br /&gt;
  vector &amp;lt;int&amp;gt; v;&lt;br /&gt;
  v.reserve(1000);&lt;br /&gt;
&lt;br /&gt;
En el siguiente ejemplo se muestran los resultados compilado con Borland C++ 5.5 para Win32; con MS Visual C++ 6.0 y con GNU gcc 2.95.3 para Linux:&lt;br /&gt;
  // resultados con:         BC++   VC++   GNU   &lt;br /&gt;
  vector&amp;lt;int&amp;gt; v;&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 0      0      0   &lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 0      0      0&lt;br /&gt;
  v.push_back(3);&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    1      1&lt;br /&gt;
  v.reserve(100);&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    100    100&lt;br /&gt;
&lt;br /&gt;
=== Operaciones sobre contenedores ===&lt;br /&gt;
Los elementos de un contenedor son colocados en él utilizando el constructor copia, aunque algunas operaciones requieren la existencia de un constructor por defecto. A su vez, los algoritmos genéricos, como copy(), que copian a un contenedor, utilizan el operador de asignación.&lt;br /&gt;
&lt;br /&gt;
Cuando se duplica todo un contenedor de tipos T por invocación del [[Constructor (C++)|constructor]] copia o por asignación, cada miembro es copiado en la nueva estructura utilizando el constructor copia o el operador de asignación. Tanto si una copia profunda o una copia somera, el resultado es controlado por el programador, que puede proporcionar el operador de asignación para el tipo T con cualquier significado que desee. Si se ha definido un destructor para el tipo T, este destructor es invocado cada vez que deba ser eliminado un elemento del contenedor. Cuando se destruye toda la colección, el destructor es invocado por cada elemento que permaneciera almacenado.&lt;br /&gt;
&lt;br /&gt;
En estos casos, el contenedor es solamente responsable de mantener los propios punteros, siendo responsabilidad del programador manejar la memoria de los valores referenciados por estos, lo que supone que los espacios de memoria son asignados correctamente; por lo general mediante el operador new; que no son desasignados mientras el contenedor albergue referencias a ellos, y que sean adecuadamente desasignados una vez que han sido eliminados del contenedor.&lt;br /&gt;
&lt;br /&gt;
===  Secuencias ===&lt;br /&gt;
Las secuencias son estructuras de datos de tipo lineal, con posibilidad de que su tamaño puede ser alterado insertando elementos al principio, al final o en cualquier posición, si bien la idoneidad en este sentido es distinta entre los diversos tipos.&lt;br /&gt;
&lt;br /&gt;
La STL ofrece los siguientes:&lt;br /&gt;
  • deque&lt;br /&gt;
  • list&lt;br /&gt;
  • stack&lt;br /&gt;
  • vector&lt;br /&gt;
  • vector&amp;lt;bool&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La estructura lineal implica que sus datos son lógicamente contiguos, aunque su disposición física puede que no lo sea. Los elementos pueden ser accedidos por un índice numérico, aunque en algunos tipos de secuencia el acceso a un elemento implica un recorrido por la lista.&lt;br /&gt;
&lt;br /&gt;
== Contenedores asociativos ==&lt;br /&gt;
Los contenedores asociativos son una extensión de las secuencias. Mientras que en estas para acceder a los elementos solo pueden utilizarse claves numéricas, que señalan el número de orden del elemento dentro de la secuencia (al estilo de los índices en las matrices). Los contenedores asociativos admiten cualquier tipo de clave de acceso. Las más frecuentes son las cadenas alfanuméricas (stings).&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, razón por la que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.&lt;br /&gt;
&lt;br /&gt;
La ordenación se realiza según los valores de ciertos miembros del contenedor. Estos elementos son denominados &amp;quot;de claves&amp;quot; (&amp;quot;Key values&amp;quot;). Lo que exige que los objetos &amp;quot;de clave&amp;quot; sean de un tipo para el que estén definidos los operadores relacionales. El contenedor es mantenido ordenado de forma automática por los algoritmos de inserción y borrado.&lt;br /&gt;
&lt;br /&gt;
La STL proporciona cinco tipo distintos, aunque en realidad son tres clases; dos de ellas en dos variedades (permitiendo o no claves duplicadas). Uno de los tipos (bitset) sirve para almacenar campos de bits de longitud constante. Los otros dos permiten elementos ordenados de cualquier tipo (set y multiset), mientras que map y multimap permiten alojar pares de elementos. Uno que actúa como &amp;quot;Key value&amp;quot; y otro que puede ser un tipo cualquiera al que llamaremos valor-dato.&lt;br /&gt;
&lt;br /&gt;
  • bitset&lt;br /&gt;
  • set&lt;br /&gt;
  • multiset&lt;br /&gt;
  • map&lt;br /&gt;
  • multimap&lt;br /&gt;
&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave, y para recorrer el conjunto (ordenado) de las claves.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http://www.zator.com/Cpp/E5_1_1.htm Contenerores C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Contenedores en C.conclase.net]&lt;br /&gt;
* [https://docs.microsoft.com/es-es/cpp/standard-library/stl-containers?view=vs-2017  Contenedores de la biblioteca estándar de C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234257</id>
		<title>Contenedores C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234257"/>
		<updated>2018-11-29T18:31:57Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Contenedores C++ |imagen=  |concepto= En sentido [[C++|C++]] estricto, un contenedor de la STL es una clase genérica que puede instanciarse para representar diversos tipos de objetos. Esta clase incluye ciertas operaciones  sobre los objetos de su tipo; estas operaciones están representadas por [[Función (programación)|funciones]]-miembro, incluyendo constructores y funciones-operador, que son a su vez funciones genéricas}}''' Contenedores [[C++|C++]] '''. Al mismo tiempo, desde el punto de vista de las teorías de la información, podemos considerarlos estructuras de datos más o menos adecuadas (según el caso) para aplicarles ciertos algoritmos.&lt;br /&gt;
De su propio nombre (&amp;quot;Containers&amp;quot;) podemos deducir que su misión principal, y razón de su existencia, es su función como estructuras de datos, y en este sentido podemos adelantar que entre sus funcionalidades más destacadas se encuentran la gestión del espacio de almacenamiento necesario.&lt;br /&gt;
Una de las primerísimas ventajas de la utilización de contenedores es que el programador no tiene que enredarse con las cuestiones siempre espinosas de asignar o liberar memoria para los objetos creados, de forma que queda liberado de los [[Operadores|operadores]] [[Operador new|new]] y [[Operador delete|delete]].&lt;br /&gt;
== Filosofía de uso ==&lt;br /&gt;
Una primera pincelada sobre la filosofía de uso de los contenedores mediante un sencillo ejemplo: si tenemos que manejar un conjunto de enteros, puede utilizarse una matriz de enteros, pero ya hemos señalado  que esta estructura nos obliga a conocer de antemano la cantidad de datos a almacenar (el tamaño de la matriz). En consecuencia, si el número de datos puede variar, esta opción no es muy adecuada. Además, si es importante mantener los datos ordenados, la utilización de una matriz nos obligaría a ingeniar por nuestra cuenta la forma de hacerlo; seguramente mediante complicadas rutinas de &amp;quot;sort&amp;quot; hechas manualmente.&lt;br /&gt;
&lt;br /&gt;
Una alternativa es utilizar como &amp;quot;contenedor&amp;quot; para nuestros enteros una clase genérica de la STL denominada vector. En este caso, serían posibles expresiones como las siguientes:&lt;br /&gt;
&lt;br /&gt;
  vector&amp;lt;int&amp;gt; v(3);         // L1:&lt;br /&gt;
  v[0] = 7;                 // L2:&lt;br /&gt;
  v[1] = v[0] + 1;          // L3:&lt;br /&gt;
  v[2] = v[0] + v[1];       // L4:&lt;br /&gt;
&lt;br /&gt;
Al encontrar la primera sentencia, el compilador crea una instancia (especialidad) anónima de la plantilla vector para alojar enteros; a continuación una instancia de ella para alojar tres enteros, a la que denominamos v.&lt;br /&gt;
&lt;br /&gt;
Una primera inspección de las sentencias L2 a L3, nos muestra que la clase ofrece la posibilidad de utilizar con sus miembros el operador subíndice de matriz [ ]. Deducimos por tanto, que dispone de una versión sobrecargada de este operador para los miembros de la clase, lo que nos permite utilizar el objeto v como una matriz, aunque con algunas funcionalidades no incluidas en aquellas.&lt;br /&gt;
&lt;br /&gt;
Después de L4 los valores finales para los miembros de nuestra &amp;quot;matriz&amp;quot; serian:&lt;br /&gt;
 v[0] == 7, v[1] == 8, v[2] == 15&lt;br /&gt;
&lt;br /&gt;
Si deseamos invertir el orden de los elementos de nuestra matriz. Para ello utilizamos una [[Función (programación)|función]] especial:&lt;br /&gt;
&lt;br /&gt;
 reverse(v.begin(), v.end());&lt;br /&gt;
&lt;br /&gt;
después de lo cual, el orden de miembros sería:&lt;br /&gt;
&lt;br /&gt;
 v[0] == 15, v[1] == 8, v[2] == 7&lt;br /&gt;
&lt;br /&gt;
La primera observación es que la función reverse utiliza dos argumentos, que son a su vez el valor devuelto por sendos métodos de clase (los aplicamos sobre nuestro objeto v).  El valor devuelto por estos métodos es lo que se conoce como un [[Iteradores (Programación)|iterador]]; una especie de puntero que señalan al interior de la estructura de datos representada por el contenedor v. En este caso, el primer iterador señala al primer miembro y el segundo a una posición después del último; de esta forma se indican los miembros inicial y final entre los que se realizará la operación de inversión efectuada por reverse.&lt;br /&gt;
&lt;br /&gt;
La segunda observación es que la función reverse no es un método de clase, sino una función global; es lo que denominamos un [[Algoritmo|algoritmo]]. Esta función tiene la peculiaridad de que puede ser aplicado sobre el contenedor vector (y algún otro); que opera sobre un rango de los elementos del contenedor, en nuestro caso sobre la totalidad (esta capacidad de operar sobre una parte de un contenedor es característica de los algoritmos). También que pueden operar sobre otros contenedores produciendo un efecto similar. Por ejemplo, el algoritmo reverse puede operar incluso sobre una simple matriz:&lt;br /&gt;
 char Ch[5] = { 'A', 'E', 'I', 'O', 'U' };&lt;br /&gt;
 reverse(Ch, Ch + 5);&lt;br /&gt;
 for (int i = 0; i &amp;lt; 5; ++i) cout &amp;lt;&amp;lt; &amp;quot;Ch[&amp;quot; &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &amp;quot;] = &amp;quot; &amp;lt;&amp;lt; Ch[i];&lt;br /&gt;
 Salida:&lt;br /&gt;
 Ch[0] = U Ch[1] = O Ch[2] = I Ch[3] = E Ch[4] = A&lt;br /&gt;
&lt;br /&gt;
Es significativo que el objeto v es una estructura de datos que permite acceder individualmente a sus miembros &amp;quot;como si&amp;quot; fuesen elementos de una matriz. También que se pueden aplicar ciertas operaciones sobre la totalidad, o parte, de esta estructura considerada como una unidad.&lt;br /&gt;
== Clasificación ==&lt;br /&gt;
Existen dos tipos de contenedores: secuencias y asociativos; a su vez se subdividen según el tipo de [[Iteradores (Programación)|iterador]] que soportan.&lt;br /&gt;
&lt;br /&gt;
Las secuencias almacenan los elementos en orden secuencial (de ahí su nombre). El contenedor agrupa a todos sus miembros como una sucesión lineal, y en consecuencia son adecuadas para accesos directos y secuenciales. Un ejemplo de secuencia es una matriz. De hecho, los algoritmos que pueden aplicarse a las secuencias pueden aplicarse también a las matrices.&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, por lo que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.  La STL proporciona cinco tipos distintos.&lt;br /&gt;
&lt;br /&gt;
La existencia de índices supone una ordenación según los valores de un conjunto de elementos (denominado &amp;quot;de claves&amp;quot;) para el que debe existir un criterio de ordenación. Dicho en otras palabras, los objetos &amp;quot;de clave&amp;quot; deben ser de un tipo para el que estén definidos los operadores relacionales. El árbol es mantenido ordenado de forma automática por los algoritmos de inserción y borrado del contenedor.&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave y para recorrer el conjunto (ordenado) de los elementos.&lt;br /&gt;
&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] contiene diez formas de contenedores y tres adaptadores de contenedor (denominados simplemente [[Adapter|adaptadores]]). En esta sección se expondrán brevemente cuales son estas formas; sus características, y cuál es la más adecuada para cada tipo de problema específico. En secciones sucesivas se comentarán individualmente con mayor detalle.&lt;br /&gt;
Relación siguiendo la clasificación utilizada en el Estándar:&lt;br /&gt;
  • Secuencias&lt;br /&gt;
      o	deque&lt;br /&gt;
      o	list&lt;br /&gt;
      o	stack&lt;br /&gt;
      o	vector&lt;br /&gt;
      o	vector &amp;lt;bool&amp;gt;&lt;br /&gt;
  • adaptadores&lt;br /&gt;
      o	queue&lt;br /&gt;
      o	priority_queue&lt;br /&gt;
  • Contenedores asociativos&lt;br /&gt;
      o	map&lt;br /&gt;
      o	multimap&lt;br /&gt;
      o	set&lt;br /&gt;
      o	multiset&lt;br /&gt;
      o	bitset&lt;br /&gt;
== Características ==&lt;br /&gt;
Las características más significativas de las diversas formas de contenedor son:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Contenedor&lt;br /&gt;
! Características&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;big&amp;gt;Secuencias&amp;lt;/big&amp;gt;&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| vector&lt;br /&gt;
| Este contenedor es una estructura de datos de tamaño fijo preferentemente. Aunque la STL proporciona herramientas para cambiar el tamaño de un vector de forma dinámica, esta operación es costosa y debe ser evitada dentro de lo posible (en este sentido el vector se comporta como una matriz ordinaria).&lt;br /&gt;
&lt;br /&gt;
Disponen de un buén mecanismo de acceso aleatorio a elementos y de un mecanismo de inserción al final muy eficiente.&lt;br /&gt;
&lt;br /&gt;
Generalmente es preferible utilizar un vector que un deque o un list, a menos que sea frecuentemente necesario insertar datos al comienzo o al final, en cuyo caso es mejor utilizar un deque.  Si por el contrario es frecuente la inserción de elementos en el centro, entonces es preferible un list.&lt;br /&gt;
|-&lt;br /&gt;
| vector&amp;lt;bool&amp;gt;&lt;br /&gt;
| Es una versión de la anterior especial para valores binarios (bits).&lt;br /&gt;
|-&lt;br /&gt;
| list&lt;br /&gt;
| Este contenedor responde a la idéa intuitiva de &amp;quot;lista&amp;quot;, el almacenamiento de objetos en una secuencia lineal que no está necesariamente ordenada (aunque sus miembros pueden ser ordenados fácilmente mediante la función-miembro sort() ). Estos contenedores suelen ser implementados como listas doblemente enlazadas. &lt;br /&gt;
&lt;br /&gt;
Dispone de mecanismos eficientes para insertar elementos al principio, al final o en cualquier posición (utilizando iteradores que denoten posición). Estas operaciones consumen un tiempo constante con independencia del número de elmentos albergados en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Dado que son estructuras lineales, en general los elementos no pueden ser accedidos por subíndices como en un vector.  Es necesario realizar un recorrido lineal por todos los valores, por lo que en las operaciones de acceso se utilizan tiempos proporcionales al número de elementos.&lt;br /&gt;
|-&lt;br /&gt;
| stack&lt;br /&gt;
| Contenedor de elementos tipo pila LIFO que permite inserciones y eliminaciones solo en la parte superior.&lt;br /&gt;
|-&lt;br /&gt;
| deque&lt;br /&gt;
| Los deques o colas de doble terminación (&amp;quot;Double-ended queue&amp;quot;) son un tipo de estructura de datos que comparte las características de las colas (&amp;quot;Queues&amp;quot;) y las pilas (&amp;quot;Stacks&amp;quot;). Como en las colas , los elementos pueden ser empujados por un extremo al interior del contenedor, y el primer elemento introducido puede ser extraído por el extremo opuesto. Al mismo tiempo, el último elemento introducido por el principio puede ser extraído en ese mismo extremo como si fuese una pila.&lt;br /&gt;
 &lt;br /&gt;
Estos contenedores suelen ser implementados bajo la forma de matrices bidimensionales.&lt;br /&gt;
&lt;br /&gt;
Las características de los deques implementados en la STL pueden resumirse en: Acceso aleatorio; mecanismo eficiente de inserción al principio o al final.&lt;br /&gt;
|-&lt;br /&gt;
| string&lt;br /&gt;
| Contenedor de caracteres adaptado a operaciones con cadenas de caracteres.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;big&amp;gt;Asociaciones&amp;lt;/big&amp;gt;&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| set&lt;br /&gt;
| Como el resto de contenedores asociativos, esta forma de contenedor mantiene los elementos en orden. Dispone de mecanismos eficientes para inclusión, inserción y eliminación de elementos, y soporta claves únicas (solo puede existir un miembro con una clave determinada).&lt;br /&gt;
|-&lt;br /&gt;
| multiset&lt;br /&gt;
| Versión del anterior que permite la existencia de claves duplicadas. Es decir, distintos elementos dentro del conjunto pueden responder a la misma clave.&lt;br /&gt;
|-&lt;br /&gt;
| bitset&lt;br /&gt;
| Contenedor de bit más orientado al tamaño que hacia el tipo de contenido. Permite almacenar secuencias de bits de tamaño fijo. No existen iteradores para reccorrerlas, y sus elementos se acceden utilizando el operador subíndice.&lt;br /&gt;
 &lt;br /&gt;
Se dispone de varias funciones para realizar con ellos operaciones de bits &lt;br /&gt;
|-&lt;br /&gt;
| map&lt;br /&gt;
| Como el resto de estructuras asociativas, el map mantiene sus elementos ordenados. Se caracteriza porque sus miembros son pares de valores que pueden ser de tipos distintos. Uno de ellos, el que actúa como clave para el índice (&amp;quot;Key-value&amp;quot;), puede ser de cualquier tipo, a condición de que sus elementos puedan ser ordenados según un criterio (por defecto se utiliza el operador &amp;lt;).&lt;br /&gt;
 &lt;br /&gt;
Permite claves únicas. Es decir, que solo puede existir un miembro para cada clave. Dispone de mecanismos de inserción y borrado muy eficientes y no existe límite de tamaño. La estructura se encarga de crecer y disminuir en concordancia con las necesidades de sus miembros. Permite el operador [ ] subíndice para los elementos de la clave así como otras técnicas de acceso.&lt;br /&gt;
&lt;br /&gt;
Estas estructuras de datos recibe también los nombres de diccionarios, tablas y matrices asociativas, en referencia a que pueden considerarse como dos matrices del mismo número de elementos, en las que existe una relación entre cada miembro de una con otro miembro de la otra.  Una de las matrices (que actúa de índice) estaría ordenada según su contenido&lt;br /&gt;
|-&lt;br /&gt;
| multimap&lt;br /&gt;
| En todo igual que el anterior pero permitiendo además claves duplicadas. Es decir, que una misma clave pueda estar asociada a dos &amp;quot;valores&amp;quot; distintos.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Adaptador&lt;br /&gt;
! Características&lt;br /&gt;
|-&lt;br /&gt;
| queue&lt;br /&gt;
| Contenedor tipo cola FIFO que permite inserciones al final y eliminaciones al principio.&lt;br /&gt;
|-&lt;br /&gt;
| priority queue&lt;br /&gt;
| Este contenedor dispone de mecanismos eficientes para acceso y eliminación de grandes valores.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Seleccionar un contenedor ==&lt;br /&gt;
El binomio contendor-iterador conforma una herramienta que se adapta a circunstancias muy variadas. Es posible que un determinado problema pueda ser abordado de varias formas, en estos casos la selección de la forma de contenedor más adecuado depende de las circunstancias. En ciertas ocasiones puede resultar bastante obvia; en otras puede no estar tan claro cuál es la mejor opción, pues &amp;quot;a priori&amp;quot;, pueden adaptarse varias formas al caso concreto. Puede utilizarse el sistema de prueba y comparación. Por ejemplo, cronometrando los resultados obtenidos en un modo u otro. También será de gran ayuda la experiencia, pero como una guía o criterio general puede utilizarse el principio de selección que se indica a continuación.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Como se accederá a los datos?.&lt;br /&gt;
| Si es importante un acceso aleatorio, pueden utilizarse un vector o un deque. Si basta con un acceso secuencial cualquiera de los dos puede ser el elegido.&lt;br /&gt;
|-&lt;br /&gt;
| Es importante el orden en que serán mantenidos los valores dentro de la colección de datos?&lt;br /&gt;
| Existen muchas formas de secuenciar los valores. Si es importante un orden estricto a lo largo de toda la vida del contenedor, la elección obvia es un set, dado que las inserciones en una de estas estructuras se realizan automáticamente en orden.&lt;br /&gt;
 &lt;br /&gt;
Si este orden es importante solo en algún momento, por ejemplo al final de una serie de inserciones, puede ser más sencillo colocar los valores en un list o vector para ordenar más tarde el resultado en el momento necesario.&lt;br /&gt;
&lt;br /&gt;
Si el orden en que se almacenan los valores en la estructura está relacionado con el orden de su inserción, entonces un stack, un queue o un list pueden ser la mejor elección.&lt;br /&gt;
|-&lt;br /&gt;
| Puede variar mucho el tamaño de la estructura de datos durante el curso de la ejecución del programa?&lt;br /&gt;
| Si es así, entonces puede ser que la mejor opción sean un list o un set. Un vector o un deque pueden conducir a mantener un gran almacenamiento intermedio (buffer); incluso después que los elementos hayan sido eliminados de la colección de datos. Estos dos contenedores no son adecuados para cambios de tamaño, aunque vector dispone de un mecanismo de inserción al final eficiente.&lt;br /&gt;
 &lt;br /&gt;
Recíprocamente: si el tamaño de la colección se mantiene relativamente estable, entonces un vector o un deque pueden utilizar menos memoria que un list o un set que almacenen el mismo número de elementos.&lt;br /&gt;
|-&lt;br /&gt;
| Es posible determinar el tamaño de la colección?&lt;br /&gt;
| La estructura de datos vector proporciona un medio para pre-seleccionar un bloque de memoria de un tamaño específico con la función miembro reserve, posibilidad que no existe en otros contenedores.&lt;br /&gt;
|-&lt;br /&gt;
| Es frecuente tener que comprobar si un valor cualquiera está incluido en la colección?&lt;br /&gt;
| En este caso, un contenedor set o map pueden ser buena elección. En estos casos comprobar si un determinado valor está incluido puede ser realizado con un pequeño número de pasos (logarítmicos con el tamaño del contenedor). Mientras que la misma verificación en cualquiera de los otros tipos puede requerir comparar el valor con cada elemento almacenado en el contenedor.&lt;br /&gt;
|-&lt;br /&gt;
| Está indexada la colección de datos? &lt;br /&gt;
| Si las claves son enteros entre 0 y un límite superior, pueden utilizarse un vector o un deque. &lt;br /&gt;
|-&lt;br /&gt;
| Si es así, puede ser vista la colección como una serie de pares clave/valor?&lt;br /&gt;
| Si la clave es algún otro valor, como cadenas de caracteres o tipos definidos por el usuario, puede utilizarse un contenedor map.&lt;br /&gt;
|-&lt;br /&gt;
| Pueden los valores estar relacionados unos con otros?&lt;br /&gt;
| Todos los valores almacenados en cualquier contenedor de la STL debe ser capaz de comprobar la igualdad con cualquier otro valor similar, pero recuerde que no todos son capaces de reconocer el operador de relación menor-que; sin embargo, si los valores no pueden ser ordenados utilizando el operador menor-que, no pueden ser almacenados en un set o en un map.&lt;br /&gt;
|-&lt;br /&gt;
| Es una operación frecuente tener que encontrar y eliminar el valor mayor de la colección?&lt;br /&gt;
| En caso afirmativo, la estructura de datos más idónea es el priority queue.&lt;br /&gt;
|-&lt;br /&gt;
| En que posiciones son insertados o eliminados los elementos de la estructura?&lt;br /&gt;
| Si los valores son añadidos o eliminados en la zona interior, entonces la mejor opción es un list.&lt;br /&gt;
 &lt;br /&gt;
Si los valores son insertados solo al comienzo, un deque o un list pueden ser lo más adecuado.&lt;br /&gt;
&lt;br /&gt;
Si los valores son insertados y eliminados solo al final, un stack o un queue pueden ser elecciones lógicas.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| Es frecuente tener que refundir dos o más secuencias en una sola?&lt;br /&gt;
| En caso afirmativo, puede considerarse que las mejores opciones son un set o un list, dependiendo que la colección deba o no ser mantenida en orden.&lt;br /&gt;
 &lt;br /&gt;
Refundir dos set es una operación muy eficiente.  Si la colección de datos no está ordenada, pero puede utilizarse la función miembro splice() de las list (que es muy eficiente), entonces es preferible este último tipo de contenedor, dado que esta operación no está contemplada en las demás formas.&lt;br /&gt;
|}&lt;br /&gt;
=== Tipos no incluidos ===&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] incluye contenedores adecuados para la mayoría de los casos prácticos, aunque quizás existen una serie de estructuras de datos clásicas que no han sido incluidas. En la mayoría de los casos, la causa es que los contenedores proporcionados pueden ser fácilmente adaptados para suplir los usos facilitados por los tipos omitidos.&lt;br /&gt;
&lt;br /&gt;
Tipos clásicos no incluidos y la sustitución más fácil.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Contenedor omitido&lt;br /&gt;
! Sustitución utilizando elementos de STL&lt;br /&gt;
|-&lt;br /&gt;
| tree&lt;br /&gt;
| El modo set está implementado internamente como un árbol de búsqueda binaria. &lt;br /&gt;
&lt;br /&gt;
Para la mayoría de los casos prácticos que pueden ser resueltos utilizando árboles este modo es un sustituto adecuado.&lt;br /&gt;
|-&lt;br /&gt;
| matrices multidimensionales&lt;br /&gt;
| Puesto que los vectores pueden almacenar elementos que sean otros vectores, estas estructuras pueden ser construidas fácilmente.&lt;br /&gt;
|-&lt;br /&gt;
| graph&lt;br /&gt;
| La representación de un gráfico puede ser fácilmente construida como un map que contiene otros map. Un map cuyos elementos son a su vez maps, es la representación natural de un gráfico directo. &lt;br /&gt;
|-&lt;br /&gt;
| sparse array&lt;br /&gt;
| Una novedosa sustitución es la representación de un gráfico&lt;br /&gt;
|-&lt;br /&gt;
| hash table&lt;br /&gt;
| Las tablas hash proporcionan un tiempo de acceso constante, así como inserción y borrado de elementos, convirtiendo estas operaciones en operaciones de índice.&lt;br /&gt;
 &lt;br /&gt;
Una tabla hash puede ser construida fácilmente como un vector (o deque) cuyos elementos son lists (o incluso sets).  En el ejemplo de la ordenación raíz (  xxx) se describe una de estas estructuras (un vector de deques), aunque en este ejemplo no incluye invocación la función hash para convertir un valor en un índice.&lt;br /&gt;
|-&lt;br /&gt;
| Funcionalidad set&lt;br /&gt;
| En la STL, los tipos set están específicamente ordenados, y sus operaciones (como la unión intersección, etc.) no pueden ser realizadas sobre colecciones de valores no ordenados (por ejemplo un conjunto de números complejos).&lt;br /&gt;
 &lt;br /&gt;
Una list puede ser utilizada como sustituto, aunque es necesario escribir funciones de operación especiales, dado que los algoritmos genéricos no pueden ser utilizados con listas.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Gestión de memoria ==&lt;br /&gt;
La gestión de memoria realizada por los contenedores comprende tanto la asignación y liberación de espacio para sus miembros, como para las claves que constituyen el sistema de índice de algunos tipos de contenedor. En general los algoritmos de la STL están muy optimizados y el sistema de asignación de memoria intenta compaginar rapidez y eficacia. La primera exige asignar y desasignar espacio cada vez que se introduce o elimina un miembro del contenedor. La eficacia, e incluso la disminución de la fragmentación inherentes al manejo del montón, exige asignar y rehusar trozos de memoria lo más grandes posible cada vez. El abordaje a este problema se ha realizado de dos formas básicas: (a) Contenedores que no pueden alterar su tamaño, de forma que la asignación de espacio para sus elementos debe realizarse en el momento de su declaración. (b) Contenedores que pueden crecer y/o disminuir en consonancia con los elementos a albergar.&lt;br /&gt;
&lt;br /&gt;
Refiriéndonos al caso (b), para balancear estas exigencias contrapuestas, algunas implementaciones utilizan el siguiente esquema de trabajo: inicialmente el sistema asigna al contenedor un trozo de memoria de tamaño adecuado para contener cierto número de elementos; espacio que es utilizando hasta que se agota. A partir de aquí, cada nueva demanda origina la asignación una zona de doble tamaño que la anterior. Por ejemplo, supongamos que para gestionar un vector de enteros, el compilador asigna inicialmente espacio para un máximo de 16 miembros.  Cuando se agotara, se realizaría una nueva asignación de espacio para 32 miembros, e inmediatamente se efectuaría una recolocación del contenido actual en el nuevo espacio y la liberación del primitivo. Si el nuevo contenedor quedara lleno de nuevo, la siguiente asignación sería capaz de 64 miembros y así sucesivamente.&lt;br /&gt;
&lt;br /&gt;
El factor de aumento de tamaño puede ser cualquiera. Muchos compiladores utilizan un factor 1.5 cada vez que deben ampliar el espacio necesario.&lt;br /&gt;
&lt;br /&gt;
Cada nueva recolocación implica varios pasos:&lt;br /&gt;
  •	Asignación de memoria al estilo malloc() de la librería clásica en cantidad suficiente para el nuevo tamaño.&lt;br /&gt;
  •	Copia de los elementos actuales en la nueva localización. Los elementos son colocados en la nueva situación utilizando el constructor copia.&lt;br /&gt;
  •	Actualización de las estructuras internas del nuevo contenedor (sistema de índices).&lt;br /&gt;
  •	Eliminación de los elementos originales mediante invocación sucesiva de sus correspondientes destructores.&lt;br /&gt;
  •	Liberación de la memoria utilizada por las estructuras internas.&lt;br /&gt;
  •	Liberación de la zona original mediante una invocación al estilo free de la librería clásica.&lt;br /&gt;
&lt;br /&gt;
En general, al referirse al tamaño de un contenedor existen tres magnitudes distintas aunque relacionadas, cuyos valores pueden obtenerse mediante tres métodos:&lt;br /&gt;
&lt;br /&gt;
  •	El número de elementos contenidos actualmente. size()&lt;br /&gt;
  •	El máximo número de elementos que pueden alcanzarse actualmente sin necesidad de una nueva recolocación. capacity()&lt;br /&gt;
  •	El máximo número de elementos que pueden alcanzarse en cualquier caso. max_size().&lt;br /&gt;
&lt;br /&gt;
 Ejemplo:&lt;br /&gt;
   #include &amp;lt;iostream&amp;gt;&lt;br /&gt;
   using namespace std;&lt;br /&gt;
   #include &amp;lt;vector&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   int main() {         // ================&lt;br /&gt;
   vector&amp;lt;int&amp;gt; vInt;&lt;br /&gt;
   for (int i=0; i &amp;lt; 100; i++) vInt.push_back(i);&lt;br /&gt;
&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Tamaño actual:   &amp;quot; &amp;lt;&amp;lt; vInt.size()     &amp;lt;&amp;lt; endl;&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Capacidad actual: &amp;quot; &amp;lt;&amp;lt; vInt.capacity() &amp;lt;&amp;lt; endl;&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Tamano maximo:   &amp;quot; &amp;lt;&amp;lt; vInt.max_size() &amp;lt;&amp;lt; endl;&lt;br /&gt;
   return 0;&lt;br /&gt;
   }&lt;br /&gt;
   Salida:&lt;br /&gt;
   Tamaño actual: 100&lt;br /&gt;
   Capacidad actual: 256&lt;br /&gt;
   Tamano maximo: 1073741823&lt;br /&gt;
&lt;br /&gt;
En todos los casos: size() &amp;lt;= capacity()&lt;br /&gt;
&lt;br /&gt;
Es posible comprobar si un contenedor está vacío, comparando su tamaño actual size() con cero, aunque es más rápido utilizar el método empty(), que devuelve true si realmente size() == 0.&lt;br /&gt;
&lt;br /&gt;
=== Reserva de espacio ===&lt;br /&gt;
Como puede suponer, cada recolocación supone un proceso considerable, sobre todo en contenedores muy grandes. Para evitar sus inconvenientes si se conoce de antemano el tamaño máximo a utilizar, la STL ofrece la posibilidad de preasignar un espacio arbitrario. Para esto se dispone del método reserve(n), que garantiza la asignación de espacio inicial suficiente para alojar n miembros en el contenedor. Si el argumento n es mayor que la capacidad actual, se produce una recolocación y el nuevo argumento determina la nueva capacidad. Si es menor no se produce ninguna acción.&lt;br /&gt;
&lt;br /&gt;
Ejemplo, para crear un vector de enteros capaz para al menos 1000 miembros:&lt;br /&gt;
  vector &amp;lt;int&amp;gt; v;&lt;br /&gt;
  v.reserve(1000);&lt;br /&gt;
&lt;br /&gt;
En el siguiente ejemplo se muestran los resultados compilado con Borland C++ 5.5 para Win32; con MS Visual C++ 6.0 y con GNU gcc 2.95.3 para Linux:&lt;br /&gt;
  // resultados con:         BC++   VC++   GNU   &lt;br /&gt;
  vector&amp;lt;int&amp;gt; v;&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 0      0      0   &lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 0      0      0&lt;br /&gt;
  v.push_back(3);&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    1      1&lt;br /&gt;
  v.reserve(100);&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    100    100&lt;br /&gt;
&lt;br /&gt;
=== Operaciones sobre contenedores ===&lt;br /&gt;
Los elementos de un contenedor son colocados en él utilizando el constructor copia, aunque algunas operaciones requieren la existencia de un constructor por defecto. A su vez, los algoritmos genéricos, como copy(), que copian a un contenedor, utilizan el operador de asignación.&lt;br /&gt;
&lt;br /&gt;
Cuando se duplica todo un contenedor de tipos T por invocación del [[Constructor (C++)|constructor]] copia o por asignación, cada miembro es copiado en la nueva estructura utilizando el constructor copia o el operador de asignación. Tanto si una copia profunda o una copia somera, el resultado es controlado por el programador, que puede proporcionar el operador de asignación para el tipo T con cualquier significado que desee. Si se ha definido un destructor para el tipo T, este destructor es invocado cada vez que deba ser eliminado un elemento del contenedor. Cuando se destruye toda la colección, el destructor es invocado por cada elemento que permaneciera almacenado.&lt;br /&gt;
&lt;br /&gt;
En estos casos, el contenedor es solamente responsable de mantener los propios punteros, siendo responsabilidad del programador manejar la memoria de los valores referenciados por estos, lo que supone que los espacios de memoria son asignados correctamente; por lo general mediante el operador new; que no son desasignados mientras el contenedor albergue referencias a ellos, y que sean adecuadamente desasignados una vez que han sido eliminados del contenedor.&lt;br /&gt;
&lt;br /&gt;
===  Secuencias ===&lt;br /&gt;
Las secuencias son estructuras de datos de tipo lineal, con posibilidad de que su tamaño puede ser alterado insertando elementos al principio, al final o en cualquier posición, si bien la idoneidad en este sentido es distinta entre los diversos tipos.&lt;br /&gt;
&lt;br /&gt;
La STL ofrece los siguientes:&lt;br /&gt;
  • deque&lt;br /&gt;
  • list&lt;br /&gt;
  • stack&lt;br /&gt;
  • vector&lt;br /&gt;
  • vector&amp;lt;bool&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La estructura lineal implica que sus datos son lógicamente contiguos, aunque su disposición física puede que no lo sea. Los elementos pueden ser accedidos por un índice numérico, aunque en algunos tipos de secuencia el acceso a un elemento implica un recorrido por la lista.&lt;br /&gt;
&lt;br /&gt;
== Contenedores asociativos ==&lt;br /&gt;
Los contenedores asociativos son una extensión de las secuencias. Mientras que en estas para acceder a los elementos solo pueden utilizarse claves numéricas, que señalan el número de orden del elemento dentro de la secuencia (al estilo de los índices en las matrices). Los contenedores asociativos admiten cualquier tipo de clave de acceso. Las más frecuentes son las cadenas alfanuméricas (stings).&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, razón por la que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.&lt;br /&gt;
&lt;br /&gt;
La ordenación se realiza según los valores de ciertos miembros del contenedor. Estos elementos son denominados &amp;quot;de claves&amp;quot; (&amp;quot;Key values&amp;quot;). Lo que exige que los objetos &amp;quot;de clave&amp;quot; sean de un tipo para el que estén definidos los operadores relacionales. El contenedor es mantenido ordenado de forma automática por los algoritmos de inserción y borrado.&lt;br /&gt;
&lt;br /&gt;
La STL proporciona cinco tipo distintos, aunque en realidad son tres clases; dos de ellas en dos variedades (permitiendo o no claves duplicadas). Uno de los tipos (bitset) sirve para almacenar campos de bits de longitud constante. Los otros dos permiten elementos ordenados de cualquier tipo (set y multiset), mientras que map y multimap permiten alojar pares de elementos. Uno que actúa como &amp;quot;Key value&amp;quot; y otro que puede ser un tipo cualquiera al que llamaremos valor-dato.&lt;br /&gt;
&lt;br /&gt;
  • bitset&lt;br /&gt;
  • set&lt;br /&gt;
  • multiset&lt;br /&gt;
  • map&lt;br /&gt;
  • multimap&lt;br /&gt;
&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave, y para recorrer el conjunto (ordenado) de las claves.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http://www.zator.com/Cpp/E5_1_1.htm Contenerores C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Contenedores en C.conclase.net]&lt;br /&gt;
* [https://docs.microsoft.com/es-es/cpp/standard-library/stl-containers?view=vs-2017  Contenedores de la biblioteca estándar de C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234253</id>
		<title>Contenedores C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234253"/>
		<updated>2018-11-29T18:30:55Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Contenedores C++ |imagen=  |concepto= En sentido [[C++|C++]] estricto, un contenedor de la STL es una clase genérica que puede instanciarse para representar diversos tipos de objetos. Esta clase incluye ciertas operaciones  sobre los objetos de su tipo; estas operaciones están representadas por funciones-miembro, incluyendo constructores y funciones-operador, que son a su vez funciones genéricas}}''' Contenedores [[C++|C++]] '''. Al mismo tiempo, desde el punto de vista de las teorías de la información, podemos considerarlos estructuras de datos más o menos adecuadas (según el caso) para aplicarles ciertos algoritmos.&lt;br /&gt;
De su propio nombre (&amp;quot;Containers&amp;quot;) podemos deducir que su misión principal, y razón de su existencia, es su función como estructuras de datos, y en este sentido podemos adelantar que entre sus funcionalidades más destacadas se encuentran la gestión del espacio de almacenamiento necesario.&lt;br /&gt;
Una de las primerísimas ventajas de la utilización de contenedores es que el programador no tiene que enredarse con las cuestiones siempre espinosas de asignar o liberar memoria para los objetos creados, de forma que queda liberado de los [[Operadores|operadores]] [[Operador new|new]] y [[Operador delete|delete]].&lt;br /&gt;
== Filosofía de uso ==&lt;br /&gt;
Una primera pincelada sobre la filosofía de uso de los contenedores mediante un sencillo ejemplo: si tenemos que manejar un conjunto de enteros, puede utilizarse una matriz de enteros, pero ya hemos señalado  que esta estructura nos obliga a conocer de antemano la cantidad de datos a almacenar (el tamaño de la matriz). En consecuencia, si el número de datos puede variar, esta opción no es muy adecuada. Además, si es importante mantener los datos ordenados, la utilización de una matriz nos obligaría a ingeniar por nuestra cuenta la forma de hacerlo; seguramente mediante complicadas rutinas de &amp;quot;sort&amp;quot; hechas manualmente.&lt;br /&gt;
&lt;br /&gt;
Una alternativa es utilizar como &amp;quot;contenedor&amp;quot; para nuestros enteros una clase genérica de la STL denominada vector. En este caso, serían posibles expresiones como las siguientes:&lt;br /&gt;
&lt;br /&gt;
  vector&amp;lt;int&amp;gt; v(3);         // L1:&lt;br /&gt;
  v[0] = 7;                 // L2:&lt;br /&gt;
  v[1] = v[0] + 1;          // L3:&lt;br /&gt;
  v[2] = v[0] + v[1];       // L4:&lt;br /&gt;
&lt;br /&gt;
Al encontrar la primera sentencia, el compilador crea una instancia (especialidad) anónima de la plantilla vector para alojar enteros; a continuación una instancia de ella para alojar tres enteros, a la que denominamos v.&lt;br /&gt;
&lt;br /&gt;
Una primera inspección de las sentencias L2 a L3, nos muestra que la clase ofrece la posibilidad de utilizar con sus miembros el operador subíndice de matriz [ ]. Deducimos por tanto, que dispone de una versión sobrecargada de este operador para los miembros de la clase, lo que nos permite utilizar el objeto v como una matriz, aunque con algunas funcionalidades no incluidas en aquellas.&lt;br /&gt;
&lt;br /&gt;
Después de L4 los valores finales para los miembros de nuestra &amp;quot;matriz&amp;quot; serian:&lt;br /&gt;
 v[0] == 7, v[1] == 8, v[2] == 15&lt;br /&gt;
&lt;br /&gt;
Si deseamos invertir el orden de los elementos de nuestra matriz. Para ello utilizamos una [[Función (programación)|función]] especial:&lt;br /&gt;
&lt;br /&gt;
 reverse(v.begin(), v.end());&lt;br /&gt;
&lt;br /&gt;
después de lo cual, el orden de miembros sería:&lt;br /&gt;
&lt;br /&gt;
 v[0] == 15, v[1] == 8, v[2] == 7&lt;br /&gt;
&lt;br /&gt;
La primera observación es que la función reverse utiliza dos argumentos, que son a su vez el valor devuelto por sendos métodos de clase (los aplicamos sobre nuestro objeto v).  El valor devuelto por estos métodos es lo que se conoce como un [[Iteradores (Programación)|iterador]]; una especie de puntero que señalan al interior de la estructura de datos representada por el contenedor v. En este caso, el primer iterador señala al primer miembro y el segundo a una posición después del último; de esta forma se indican los miembros inicial y final entre los que se realizará la operación de inversión efectuada por reverse.&lt;br /&gt;
&lt;br /&gt;
La segunda observación es que la función reverse no es un método de clase, sino una función global; es lo que denominamos un [[Algoritmo|algoritmo]]. Esta función tiene la peculiaridad de que puede ser aplicado sobre el contenedor vector (y algún otro); que opera sobre un rango de los elementos del contenedor, en nuestro caso sobre la totalidad (esta capacidad de operar sobre una parte de un contenedor es característica de los algoritmos). También que pueden operar sobre otros contenedores produciendo un efecto similar. Por ejemplo, el algoritmo reverse puede operar incluso sobre una simple matriz:&lt;br /&gt;
 char Ch[5] = { 'A', 'E', 'I', 'O', 'U' };&lt;br /&gt;
 reverse(Ch, Ch + 5);&lt;br /&gt;
 for (int i = 0; i &amp;lt; 5; ++i) cout &amp;lt;&amp;lt; &amp;quot;Ch[&amp;quot; &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &amp;quot;] = &amp;quot; &amp;lt;&amp;lt; Ch[i];&lt;br /&gt;
 Salida:&lt;br /&gt;
 Ch[0] = U Ch[1] = O Ch[2] = I Ch[3] = E Ch[4] = A&lt;br /&gt;
&lt;br /&gt;
Es significativo que el objeto v es una estructura de datos que permite acceder individualmente a sus miembros &amp;quot;como si&amp;quot; fuesen elementos de una matriz. También que se pueden aplicar ciertas operaciones sobre la totalidad, o parte, de esta estructura considerada como una unidad.&lt;br /&gt;
== Clasificación ==&lt;br /&gt;
Existen dos tipos de contenedores: secuencias y asociativos; a su vez se subdividen según el tipo de [[Iteradores (Programación)|iterador]] que soportan.&lt;br /&gt;
&lt;br /&gt;
Las secuencias almacenan los elementos en orden secuencial (de ahí su nombre). El contenedor agrupa a todos sus miembros como una sucesión lineal, y en consecuencia son adecuadas para accesos directos y secuenciales. Un ejemplo de secuencia es una matriz. De hecho, los algoritmos que pueden aplicarse a las secuencias pueden aplicarse también a las matrices.&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, por lo que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.  La STL proporciona cinco tipos distintos.&lt;br /&gt;
&lt;br /&gt;
La existencia de índices supone una ordenación según los valores de un conjunto de elementos (denominado &amp;quot;de claves&amp;quot;) para el que debe existir un criterio de ordenación. Dicho en otras palabras, los objetos &amp;quot;de clave&amp;quot; deben ser de un tipo para el que estén definidos los operadores relacionales. El árbol es mantenido ordenado de forma automática por los algoritmos de inserción y borrado del contenedor.&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave y para recorrer el conjunto (ordenado) de los elementos.&lt;br /&gt;
&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] contiene diez formas de contenedores y tres adaptadores de contenedor (denominados simplemente [[Adapter|adaptadores]]). En esta sección se expondrán brevemente cuales son estas formas; sus características, y cuál es la más adecuada para cada tipo de problema específico. En secciones sucesivas se comentarán individualmente con mayor detalle.&lt;br /&gt;
Relación siguiendo la clasificación utilizada en el Estándar:&lt;br /&gt;
  • Secuencias&lt;br /&gt;
      o	deque&lt;br /&gt;
      o	list&lt;br /&gt;
      o	stack&lt;br /&gt;
      o	vector&lt;br /&gt;
      o	vector &amp;lt;bool&amp;gt;&lt;br /&gt;
  • adaptadores&lt;br /&gt;
      o	queue&lt;br /&gt;
      o	priority_queue&lt;br /&gt;
  • Contenedores asociativos&lt;br /&gt;
      o	map&lt;br /&gt;
      o	multimap&lt;br /&gt;
      o	set&lt;br /&gt;
      o	multiset&lt;br /&gt;
      o	bitset&lt;br /&gt;
== Características ==&lt;br /&gt;
Las características más significativas de las diversas formas de contenedor son:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Contenedor&lt;br /&gt;
! Características&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;big&amp;gt;Secuencias&amp;lt;/big&amp;gt;&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| vector&lt;br /&gt;
| Este contenedor es una estructura de datos de tamaño fijo preferentemente. Aunque la STL proporciona herramientas para cambiar el tamaño de un vector de forma dinámica, esta operación es costosa y debe ser evitada dentro de lo posible (en este sentido el vector se comporta como una matriz ordinaria).&lt;br /&gt;
&lt;br /&gt;
Disponen de un buén mecanismo de acceso aleatorio a elementos y de un mecanismo de inserción al final muy eficiente.&lt;br /&gt;
&lt;br /&gt;
Generalmente es preferible utilizar un vector que un deque o un list, a menos que sea frecuentemente necesario insertar datos al comienzo o al final, en cuyo caso es mejor utilizar un deque.  Si por el contrario es frecuente la inserción de elementos en el centro, entonces es preferible un list.&lt;br /&gt;
|-&lt;br /&gt;
| vector&amp;lt;bool&amp;gt;&lt;br /&gt;
| Es una versión de la anterior especial para valores binarios (bits).&lt;br /&gt;
|-&lt;br /&gt;
| list&lt;br /&gt;
| Este contenedor responde a la idéa intuitiva de &amp;quot;lista&amp;quot;, el almacenamiento de objetos en una secuencia lineal que no está necesariamente ordenada (aunque sus miembros pueden ser ordenados fácilmente mediante la función-miembro sort() ). Estos contenedores suelen ser implementados como listas doblemente enlazadas. &lt;br /&gt;
&lt;br /&gt;
Dispone de mecanismos eficientes para insertar elementos al principio, al final o en cualquier posición (utilizando iteradores que denoten posición). Estas operaciones consumen un tiempo constante con independencia del número de elmentos albergados en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Dado que son estructuras lineales, en general los elementos no pueden ser accedidos por subíndices como en un vector.  Es necesario realizar un recorrido lineal por todos los valores, por lo que en las operaciones de acceso se utilizan tiempos proporcionales al número de elementos.&lt;br /&gt;
|-&lt;br /&gt;
| stack&lt;br /&gt;
| Contenedor de elementos tipo pila LIFO que permite inserciones y eliminaciones solo en la parte superior.&lt;br /&gt;
|-&lt;br /&gt;
| deque&lt;br /&gt;
| Los deques o colas de doble terminación (&amp;quot;Double-ended queue&amp;quot;) son un tipo de estructura de datos que comparte las características de las colas (&amp;quot;Queues&amp;quot;) y las pilas (&amp;quot;Stacks&amp;quot;). Como en las colas , los elementos pueden ser empujados por un extremo al interior del contenedor, y el primer elemento introducido puede ser extraído por el extremo opuesto. Al mismo tiempo, el último elemento introducido por el principio puede ser extraído en ese mismo extremo como si fuese una pila.&lt;br /&gt;
 &lt;br /&gt;
Estos contenedores suelen ser implementados bajo la forma de matrices bidimensionales.&lt;br /&gt;
&lt;br /&gt;
Las características de los deques implementados en la STL pueden resumirse en: Acceso aleatorio; mecanismo eficiente de inserción al principio o al final.&lt;br /&gt;
|-&lt;br /&gt;
| string&lt;br /&gt;
| Contenedor de caracteres adaptado a operaciones con cadenas de caracteres.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;big&amp;gt;Asociaciones&amp;lt;/big&amp;gt;&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| set&lt;br /&gt;
| Como el resto de contenedores asociativos, esta forma de contenedor mantiene los elementos en orden. Dispone de mecanismos eficientes para inclusión, inserción y eliminación de elementos, y soporta claves únicas (solo puede existir un miembro con una clave determinada).&lt;br /&gt;
|-&lt;br /&gt;
| multiset&lt;br /&gt;
| Versión del anterior que permite la existencia de claves duplicadas. Es decir, distintos elementos dentro del conjunto pueden responder a la misma clave.&lt;br /&gt;
|-&lt;br /&gt;
| bitset&lt;br /&gt;
| Contenedor de bit más orientado al tamaño que hacia el tipo de contenido. Permite almacenar secuencias de bits de tamaño fijo. No existen iteradores para reccorrerlas, y sus elementos se acceden utilizando el operador subíndice.&lt;br /&gt;
 &lt;br /&gt;
Se dispone de varias funciones para realizar con ellos operaciones de bits &lt;br /&gt;
|-&lt;br /&gt;
| map&lt;br /&gt;
| Como el resto de estructuras asociativas, el map mantiene sus elementos ordenados. Se caracteriza porque sus miembros son pares de valores que pueden ser de tipos distintos. Uno de ellos, el que actúa como clave para el índice (&amp;quot;Key-value&amp;quot;), puede ser de cualquier tipo, a condición de que sus elementos puedan ser ordenados según un criterio (por defecto se utiliza el operador &amp;lt;).&lt;br /&gt;
 &lt;br /&gt;
Permite claves únicas. Es decir, que solo puede existir un miembro para cada clave. Dispone de mecanismos de inserción y borrado muy eficientes y no existe límite de tamaño. La estructura se encarga de crecer y disminuir en concordancia con las necesidades de sus miembros. Permite el operador [ ] subíndice para los elementos de la clave así como otras técnicas de acceso.&lt;br /&gt;
&lt;br /&gt;
Estas estructuras de datos recibe también los nombres de diccionarios, tablas y matrices asociativas, en referencia a que pueden considerarse como dos matrices del mismo número de elementos, en las que existe una relación entre cada miembro de una con otro miembro de la otra.  Una de las matrices (que actúa de índice) estaría ordenada según su contenido&lt;br /&gt;
|-&lt;br /&gt;
| multimap&lt;br /&gt;
| En todo igual que el anterior pero permitiendo además claves duplicadas. Es decir, que una misma clave pueda estar asociada a dos &amp;quot;valores&amp;quot; distintos.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Adaptador&lt;br /&gt;
! Características&lt;br /&gt;
|-&lt;br /&gt;
| queue&lt;br /&gt;
| Contenedor tipo cola FIFO que permite inserciones al final y eliminaciones al principio.&lt;br /&gt;
|-&lt;br /&gt;
| priority queue&lt;br /&gt;
| Este contenedor dispone de mecanismos eficientes para acceso y eliminación de grandes valores.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Seleccionar un contenedor ==&lt;br /&gt;
El binomio contendor-iterador conforma una herramienta que se adapta a circunstancias muy variadas. Es posible que un determinado problema pueda ser abordado de varias formas, en estos casos la selección de la forma de contenedor más adecuado depende de las circunstancias. En ciertas ocasiones puede resultar bastante obvia; en otras puede no estar tan claro cuál es la mejor opción, pues &amp;quot;a priori&amp;quot;, pueden adaptarse varias formas al caso concreto. Puede utilizarse el sistema de prueba y comparación. Por ejemplo, cronometrando los resultados obtenidos en un modo u otro. También será de gran ayuda la experiencia, pero como una guía o criterio general puede utilizarse el principio de selección que se indica a continuación.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Como se accederá a los datos?.&lt;br /&gt;
| Si es importante un acceso aleatorio, pueden utilizarse un vector o un deque. Si basta con un acceso secuencial cualquiera de los dos puede ser el elegido.&lt;br /&gt;
|-&lt;br /&gt;
| Es importante el orden en que serán mantenidos los valores dentro de la colección de datos?&lt;br /&gt;
| Existen muchas formas de secuenciar los valores. Si es importante un orden estricto a lo largo de toda la vida del contenedor, la elección obvia es un set, dado que las inserciones en una de estas estructuras se realizan automáticamente en orden.&lt;br /&gt;
 &lt;br /&gt;
Si este orden es importante solo en algún momento, por ejemplo al final de una serie de inserciones, puede ser más sencillo colocar los valores en un list o vector para ordenar más tarde el resultado en el momento necesario.&lt;br /&gt;
&lt;br /&gt;
Si el orden en que se almacenan los valores en la estructura está relacionado con el orden de su inserción, entonces un stack, un queue o un list pueden ser la mejor elección.&lt;br /&gt;
|-&lt;br /&gt;
| Puede variar mucho el tamaño de la estructura de datos durante el curso de la ejecución del programa?&lt;br /&gt;
| Si es así, entonces puede ser que la mejor opción sean un list o un set. Un vector o un deque pueden conducir a mantener un gran almacenamiento intermedio (buffer); incluso después que los elementos hayan sido eliminados de la colección de datos. Estos dos contenedores no son adecuados para cambios de tamaño, aunque vector dispone de un mecanismo de inserción al final eficiente.&lt;br /&gt;
 &lt;br /&gt;
Recíprocamente: si el tamaño de la colección se mantiene relativamente estable, entonces un vector o un deque pueden utilizar menos memoria que un list o un set que almacenen el mismo número de elementos.&lt;br /&gt;
|-&lt;br /&gt;
| Es posible determinar el tamaño de la colección?&lt;br /&gt;
| La estructura de datos vector proporciona un medio para pre-seleccionar un bloque de memoria de un tamaño específico con la función miembro reserve, posibilidad que no existe en otros contenedores.&lt;br /&gt;
|-&lt;br /&gt;
| Es frecuente tener que comprobar si un valor cualquiera está incluido en la colección?&lt;br /&gt;
| En este caso, un contenedor set o map pueden ser buena elección. En estos casos comprobar si un determinado valor está incluido puede ser realizado con un pequeño número de pasos (logarítmicos con el tamaño del contenedor). Mientras que la misma verificación en cualquiera de los otros tipos puede requerir comparar el valor con cada elemento almacenado en el contenedor.&lt;br /&gt;
|-&lt;br /&gt;
| Está indexada la colección de datos? &lt;br /&gt;
| Si las claves son enteros entre 0 y un límite superior, pueden utilizarse un vector o un deque. &lt;br /&gt;
|-&lt;br /&gt;
| Si es así, puede ser vista la colección como una serie de pares clave/valor?&lt;br /&gt;
| Si la clave es algún otro valor, como cadenas de caracteres o tipos definidos por el usuario, puede utilizarse un contenedor map.&lt;br /&gt;
|-&lt;br /&gt;
| Pueden los valores estar relacionados unos con otros?&lt;br /&gt;
| Todos los valores almacenados en cualquier contenedor de la STL debe ser capaz de comprobar la igualdad con cualquier otro valor similar, pero recuerde que no todos son capaces de reconocer el operador de relación menor-que; sin embargo, si los valores no pueden ser ordenados utilizando el operador menor-que, no pueden ser almacenados en un set o en un map.&lt;br /&gt;
|-&lt;br /&gt;
| Es una operación frecuente tener que encontrar y eliminar el valor mayor de la colección?&lt;br /&gt;
| En caso afirmativo, la estructura de datos más idónea es el priority queue.&lt;br /&gt;
|-&lt;br /&gt;
| En que posiciones son insertados o eliminados los elementos de la estructura?&lt;br /&gt;
| Si los valores son añadidos o eliminados en la zona interior, entonces la mejor opción es un list.&lt;br /&gt;
 &lt;br /&gt;
Si los valores son insertados solo al comienzo, un deque o un list pueden ser lo más adecuado.&lt;br /&gt;
&lt;br /&gt;
Si los valores son insertados y eliminados solo al final, un stack o un queue pueden ser elecciones lógicas.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| Es frecuente tener que refundir dos o más secuencias en una sola?&lt;br /&gt;
| En caso afirmativo, puede considerarse que las mejores opciones son un set o un list, dependiendo que la colección deba o no ser mantenida en orden.&lt;br /&gt;
 &lt;br /&gt;
Refundir dos set es una operación muy eficiente.  Si la colección de datos no está ordenada, pero puede utilizarse la función miembro splice() de las list (que es muy eficiente), entonces es preferible este último tipo de contenedor, dado que esta operación no está contemplada en las demás formas.&lt;br /&gt;
|}&lt;br /&gt;
=== Tipos no incluidos ===&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] incluye contenedores adecuados para la mayoría de los casos prácticos, aunque quizás existen una serie de estructuras de datos clásicas que no han sido incluidas. En la mayoría de los casos, la causa es que los contenedores proporcionados pueden ser fácilmente adaptados para suplir los usos facilitados por los tipos omitidos.&lt;br /&gt;
&lt;br /&gt;
Tipos clásicos no incluidos y la sustitución más fácil.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Contenedor omitido&lt;br /&gt;
! Sustitución utilizando elementos de STL&lt;br /&gt;
|-&lt;br /&gt;
| tree&lt;br /&gt;
| El modo set está implementado internamente como un árbol de búsqueda binaria. &lt;br /&gt;
&lt;br /&gt;
Para la mayoría de los casos prácticos que pueden ser resueltos utilizando árboles este modo es un sustituto adecuado.&lt;br /&gt;
|-&lt;br /&gt;
| matrices multidimensionales&lt;br /&gt;
| Puesto que los vectores pueden almacenar elementos que sean otros vectores, estas estructuras pueden ser construidas fácilmente.&lt;br /&gt;
|-&lt;br /&gt;
| graph&lt;br /&gt;
| La representación de un gráfico puede ser fácilmente construida como un map que contiene otros map. Un map cuyos elementos son a su vez maps, es la representación natural de un gráfico directo. &lt;br /&gt;
|-&lt;br /&gt;
| sparse array&lt;br /&gt;
| Una novedosa sustitución es la representación de un gráfico&lt;br /&gt;
|-&lt;br /&gt;
| hash table&lt;br /&gt;
| Las tablas hash proporcionan un tiempo de acceso constante, así como inserción y borrado de elementos, convirtiendo estas operaciones en operaciones de índice.&lt;br /&gt;
 &lt;br /&gt;
Una tabla hash puede ser construida fácilmente como un vector (o deque) cuyos elementos son lists (o incluso sets).  En el ejemplo de la ordenación raíz (  xxx) se describe una de estas estructuras (un vector de deques), aunque en este ejemplo no incluye invocación la función hash para convertir un valor en un índice.&lt;br /&gt;
|-&lt;br /&gt;
| Funcionalidad set&lt;br /&gt;
| En la STL, los tipos set están específicamente ordenados, y sus operaciones (como la unión intersección, etc.) no pueden ser realizadas sobre colecciones de valores no ordenados (por ejemplo un conjunto de números complejos).&lt;br /&gt;
 &lt;br /&gt;
Una list puede ser utilizada como sustituto, aunque es necesario escribir funciones de operación especiales, dado que los algoritmos genéricos no pueden ser utilizados con listas.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Gestión de memoria ==&lt;br /&gt;
La gestión de memoria realizada por los contenedores comprende tanto la asignación y liberación de espacio para sus miembros, como para las claves que constituyen el sistema de índice de algunos tipos de contenedor. En general los algoritmos de la STL están muy optimizados y el sistema de asignación de memoria intenta compaginar rapidez y eficacia. La primera exige asignar y desasignar espacio cada vez que se introduce o elimina un miembro del contenedor. La eficacia, e incluso la disminución de la fragmentación inherentes al manejo del montón, exige asignar y rehusar trozos de memoria lo más grandes posible cada vez. El abordaje a este problema se ha realizado de dos formas básicas: (a) Contenedores que no pueden alterar su tamaño, de forma que la asignación de espacio para sus elementos debe realizarse en el momento de su declaración. (b) Contenedores que pueden crecer y/o disminuir en consonancia con los elementos a albergar.&lt;br /&gt;
&lt;br /&gt;
Refiriéndonos al caso (b), para balancear estas exigencias contrapuestas, algunas implementaciones utilizan el siguiente esquema de trabajo: inicialmente el sistema asigna al contenedor un trozo de memoria de tamaño adecuado para contener cierto número de elementos; espacio que es utilizando hasta que se agota. A partir de aquí, cada nueva demanda origina la asignación una zona de doble tamaño que la anterior. Por ejemplo, supongamos que para gestionar un vector de enteros, el compilador asigna inicialmente espacio para un máximo de 16 miembros.  Cuando se agotara, se realizaría una nueva asignación de espacio para 32 miembros, e inmediatamente se efectuaría una recolocación del contenido actual en el nuevo espacio y la liberación del primitivo. Si el nuevo contenedor quedara lleno de nuevo, la siguiente asignación sería capaz de 64 miembros y así sucesivamente.&lt;br /&gt;
&lt;br /&gt;
El factor de aumento de tamaño puede ser cualquiera. Muchos compiladores utilizan un factor 1.5 cada vez que deben ampliar el espacio necesario.&lt;br /&gt;
&lt;br /&gt;
Cada nueva recolocación implica varios pasos:&lt;br /&gt;
  •	Asignación de memoria al estilo malloc() de la librería clásica en cantidad suficiente para el nuevo tamaño.&lt;br /&gt;
  •	Copia de los elementos actuales en la nueva localización. Los elementos son colocados en la nueva situación utilizando el constructor copia.&lt;br /&gt;
  •	Actualización de las estructuras internas del nuevo contenedor (sistema de índices).&lt;br /&gt;
  •	Eliminación de los elementos originales mediante invocación sucesiva de sus correspondientes destructores.&lt;br /&gt;
  •	Liberación de la memoria utilizada por las estructuras internas.&lt;br /&gt;
  •	Liberación de la zona original mediante una invocación al estilo free de la librería clásica.&lt;br /&gt;
&lt;br /&gt;
En general, al referirse al tamaño de un contenedor existen tres magnitudes distintas aunque relacionadas, cuyos valores pueden obtenerse mediante tres métodos:&lt;br /&gt;
&lt;br /&gt;
  •	El número de elementos contenidos actualmente. size()&lt;br /&gt;
  •	El máximo número de elementos que pueden alcanzarse actualmente sin necesidad de una nueva recolocación. capacity()&lt;br /&gt;
  •	El máximo número de elementos que pueden alcanzarse en cualquier caso. max_size().&lt;br /&gt;
&lt;br /&gt;
 Ejemplo:&lt;br /&gt;
   #include &amp;lt;iostream&amp;gt;&lt;br /&gt;
   using namespace std;&lt;br /&gt;
   #include &amp;lt;vector&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   int main() {         // ================&lt;br /&gt;
   vector&amp;lt;int&amp;gt; vInt;&lt;br /&gt;
   for (int i=0; i &amp;lt; 100; i++) vInt.push_back(i);&lt;br /&gt;
&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Tamaño actual:   &amp;quot; &amp;lt;&amp;lt; vInt.size()     &amp;lt;&amp;lt; endl;&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Capacidad actual: &amp;quot; &amp;lt;&amp;lt; vInt.capacity() &amp;lt;&amp;lt; endl;&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Tamano maximo:   &amp;quot; &amp;lt;&amp;lt; vInt.max_size() &amp;lt;&amp;lt; endl;&lt;br /&gt;
   return 0;&lt;br /&gt;
   }&lt;br /&gt;
   Salida:&lt;br /&gt;
   Tamaño actual: 100&lt;br /&gt;
   Capacidad actual: 256&lt;br /&gt;
   Tamano maximo: 1073741823&lt;br /&gt;
&lt;br /&gt;
En todos los casos: size() &amp;lt;= capacity()&lt;br /&gt;
&lt;br /&gt;
Es posible comprobar si un contenedor está vacío, comparando su tamaño actual size() con cero, aunque es más rápido utilizar el método empty(), que devuelve true si realmente size() == 0.&lt;br /&gt;
&lt;br /&gt;
=== Reserva de espacio ===&lt;br /&gt;
Como puede suponer, cada recolocación supone un proceso considerable, sobre todo en contenedores muy grandes. Para evitar sus inconvenientes si se conoce de antemano el tamaño máximo a utilizar, la STL ofrece la posibilidad de preasignar un espacio arbitrario. Para esto se dispone del método reserve(n), que garantiza la asignación de espacio inicial suficiente para alojar n miembros en el contenedor. Si el argumento n es mayor que la capacidad actual, se produce una recolocación y el nuevo argumento determina la nueva capacidad. Si es menor no se produce ninguna acción.&lt;br /&gt;
&lt;br /&gt;
Ejemplo, para crear un vector de enteros capaz para al menos 1000 miembros:&lt;br /&gt;
  vector &amp;lt;int&amp;gt; v;&lt;br /&gt;
  v.reserve(1000);&lt;br /&gt;
&lt;br /&gt;
En el siguiente ejemplo se muestran los resultados compilado con Borland C++ 5.5 para Win32; con MS Visual C++ 6.0 y con GNU gcc 2.95.3 para Linux:&lt;br /&gt;
  // resultados con:         BC++   VC++   GNU   &lt;br /&gt;
  vector&amp;lt;int&amp;gt; v;&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 0      0      0   &lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 0      0      0&lt;br /&gt;
  v.push_back(3);&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    1      1&lt;br /&gt;
  v.reserve(100);&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    100    100&lt;br /&gt;
&lt;br /&gt;
=== Operaciones sobre contenedores ===&lt;br /&gt;
Los elementos de un contenedor son colocados en él utilizando el constructor copia, aunque algunas operaciones requieren la existencia de un constructor por defecto. A su vez, los algoritmos genéricos, como copy(), que copian a un contenedor, utilizan el operador de asignación.&lt;br /&gt;
&lt;br /&gt;
Cuando se duplica todo un contenedor de tipos T por invocación del [[Constructor (C++)|constructor]] copia o por asignación, cada miembro es copiado en la nueva estructura utilizando el constructor copia o el operador de asignación. Tanto si una copia profunda o una copia somera, el resultado es controlado por el programador, que puede proporcionar el operador de asignación para el tipo T con cualquier significado que desee. Si se ha definido un destructor para el tipo T, este destructor es invocado cada vez que deba ser eliminado un elemento del contenedor. Cuando se destruye toda la colección, el destructor es invocado por cada elemento que permaneciera almacenado.&lt;br /&gt;
&lt;br /&gt;
En estos casos, el contenedor es solamente responsable de mantener los propios punteros, siendo responsabilidad del programador manejar la memoria de los valores referenciados por estos, lo que supone que los espacios de memoria son asignados correctamente; por lo general mediante el operador new; que no son desasignados mientras el contenedor albergue referencias a ellos, y que sean adecuadamente desasignados una vez que han sido eliminados del contenedor.&lt;br /&gt;
&lt;br /&gt;
===  Secuencias ===&lt;br /&gt;
Las secuencias son estructuras de datos de tipo lineal, con posibilidad de que su tamaño puede ser alterado insertando elementos al principio, al final o en cualquier posición, si bien la idoneidad en este sentido es distinta entre los diversos tipos.&lt;br /&gt;
&lt;br /&gt;
La STL ofrece los siguientes:&lt;br /&gt;
  • deque&lt;br /&gt;
  • list&lt;br /&gt;
  • stack&lt;br /&gt;
  • vector&lt;br /&gt;
  • vector&amp;lt;bool&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La estructura lineal implica que sus datos son lógicamente contiguos, aunque su disposición física puede que no lo sea. Los elementos pueden ser accedidos por un índice numérico, aunque en algunos tipos de secuencia el acceso a un elemento implica un recorrido por la lista.&lt;br /&gt;
&lt;br /&gt;
== Contenedores asociativos ==&lt;br /&gt;
Los contenedores asociativos son una extensión de las secuencias. Mientras que en estas para acceder a los elementos solo pueden utilizarse claves numéricas, que señalan el número de orden del elemento dentro de la secuencia (al estilo de los índices en las matrices). Los contenedores asociativos admiten cualquier tipo de clave de acceso. Las más frecuentes son las cadenas alfanuméricas (stings).&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, razón por la que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.&lt;br /&gt;
&lt;br /&gt;
La ordenación se realiza según los valores de ciertos miembros del contenedor. Estos elementos son denominados &amp;quot;de claves&amp;quot; (&amp;quot;Key values&amp;quot;). Lo que exige que los objetos &amp;quot;de clave&amp;quot; sean de un tipo para el que estén definidos los operadores relacionales. El contenedor es mantenido ordenado de forma automática por los algoritmos de inserción y borrado.&lt;br /&gt;
&lt;br /&gt;
La STL proporciona cinco tipo distintos, aunque en realidad son tres clases; dos de ellas en dos variedades (permitiendo o no claves duplicadas). Uno de los tipos (bitset) sirve para almacenar campos de bits de longitud constante. Los otros dos permiten elementos ordenados de cualquier tipo (set y multiset), mientras que map y multimap permiten alojar pares de elementos. Uno que actúa como &amp;quot;Key value&amp;quot; y otro que puede ser un tipo cualquiera al que llamaremos valor-dato.&lt;br /&gt;
&lt;br /&gt;
  • bitset&lt;br /&gt;
  • set&lt;br /&gt;
  • multiset&lt;br /&gt;
  • map&lt;br /&gt;
  • multimap&lt;br /&gt;
&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave, y para recorrer el conjunto (ordenado) de las claves.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http://www.zator.com/Cpp/E5_1_1.htm Contenerores C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Contenedores en C.conclase.net]&lt;br /&gt;
* [https://docs.microsoft.com/es-es/cpp/standard-library/stl-containers?view=vs-2017  Contenedores de la biblioteca estándar de C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234251</id>
		<title>Contenedores C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234251"/>
		<updated>2018-11-29T18:30:34Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Contenedores C++ |imagen=  |concepto= En sentido C++ estricto, un contenedor de la STL es una clase genérica que puede instanciarse para representar diversos tipos de objetos. Esta clase incluye ciertas operaciones  sobre los objetos de su tipo; estas operaciones están representadas por funciones-miembro, incluyendo constructores y funciones-operador, que son a su vez funciones genéricas}}''' Contenedores [[C++|C++]] '''. Al mismo tiempo, desde el punto de vista de las teorías de la información, podemos considerarlos estructuras de datos más o menos adecuadas (según el caso) para aplicarles ciertos algoritmos.&lt;br /&gt;
De su propio nombre (&amp;quot;Containers&amp;quot;) podemos deducir que su misión principal, y razón de su existencia, es su función como estructuras de datos, y en este sentido podemos adelantar que entre sus funcionalidades más destacadas se encuentran la gestión del espacio de almacenamiento necesario.&lt;br /&gt;
Una de las primerísimas ventajas de la utilización de contenedores es que el programador no tiene que enredarse con las cuestiones siempre espinosas de asignar o liberar memoria para los objetos creados, de forma que queda liberado de los [[Operadores|operadores]] [[Operador new|new]] y [[Operador delete|delete]].&lt;br /&gt;
== Filosofía de uso ==&lt;br /&gt;
Una primera pincelada sobre la filosofía de uso de los contenedores mediante un sencillo ejemplo: si tenemos que manejar un conjunto de enteros, puede utilizarse una matriz de enteros, pero ya hemos señalado  que esta estructura nos obliga a conocer de antemano la cantidad de datos a almacenar (el tamaño de la matriz). En consecuencia, si el número de datos puede variar, esta opción no es muy adecuada. Además, si es importante mantener los datos ordenados, la utilización de una matriz nos obligaría a ingeniar por nuestra cuenta la forma de hacerlo; seguramente mediante complicadas rutinas de &amp;quot;sort&amp;quot; hechas manualmente.&lt;br /&gt;
&lt;br /&gt;
Una alternativa es utilizar como &amp;quot;contenedor&amp;quot; para nuestros enteros una clase genérica de la STL denominada vector. En este caso, serían posibles expresiones como las siguientes:&lt;br /&gt;
&lt;br /&gt;
  vector&amp;lt;int&amp;gt; v(3);         // L1:&lt;br /&gt;
  v[0] = 7;                 // L2:&lt;br /&gt;
  v[1] = v[0] + 1;          // L3:&lt;br /&gt;
  v[2] = v[0] + v[1];       // L4:&lt;br /&gt;
&lt;br /&gt;
Al encontrar la primera sentencia, el compilador crea una instancia (especialidad) anónima de la plantilla vector para alojar enteros; a continuación una instancia de ella para alojar tres enteros, a la que denominamos v.&lt;br /&gt;
&lt;br /&gt;
Una primera inspección de las sentencias L2 a L3, nos muestra que la clase ofrece la posibilidad de utilizar con sus miembros el operador subíndice de matriz [ ]. Deducimos por tanto, que dispone de una versión sobrecargada de este operador para los miembros de la clase, lo que nos permite utilizar el objeto v como una matriz, aunque con algunas funcionalidades no incluidas en aquellas.&lt;br /&gt;
&lt;br /&gt;
Después de L4 los valores finales para los miembros de nuestra &amp;quot;matriz&amp;quot; serian:&lt;br /&gt;
 v[0] == 7, v[1] == 8, v[2] == 15&lt;br /&gt;
&lt;br /&gt;
Si deseamos invertir el orden de los elementos de nuestra matriz. Para ello utilizamos una [[Función (programación)|función]] especial:&lt;br /&gt;
&lt;br /&gt;
 reverse(v.begin(), v.end());&lt;br /&gt;
&lt;br /&gt;
después de lo cual, el orden de miembros sería:&lt;br /&gt;
&lt;br /&gt;
 v[0] == 15, v[1] == 8, v[2] == 7&lt;br /&gt;
&lt;br /&gt;
La primera observación es que la función reverse utiliza dos argumentos, que son a su vez el valor devuelto por sendos métodos de clase (los aplicamos sobre nuestro objeto v).  El valor devuelto por estos métodos es lo que se conoce como un [[Iteradores (Programación)|iterador]]; una especie de puntero que señalan al interior de la estructura de datos representada por el contenedor v. En este caso, el primer iterador señala al primer miembro y el segundo a una posición después del último; de esta forma se indican los miembros inicial y final entre los que se realizará la operación de inversión efectuada por reverse.&lt;br /&gt;
&lt;br /&gt;
La segunda observación es que la función reverse no es un método de clase, sino una función global; es lo que denominamos un [[Algoritmo|algoritmo]]. Esta función tiene la peculiaridad de que puede ser aplicado sobre el contenedor vector (y algún otro); que opera sobre un rango de los elementos del contenedor, en nuestro caso sobre la totalidad (esta capacidad de operar sobre una parte de un contenedor es característica de los algoritmos). También que pueden operar sobre otros contenedores produciendo un efecto similar. Por ejemplo, el algoritmo reverse puede operar incluso sobre una simple matriz:&lt;br /&gt;
 char Ch[5] = { 'A', 'E', 'I', 'O', 'U' };&lt;br /&gt;
 reverse(Ch, Ch + 5);&lt;br /&gt;
 for (int i = 0; i &amp;lt; 5; ++i) cout &amp;lt;&amp;lt; &amp;quot;Ch[&amp;quot; &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &amp;quot;] = &amp;quot; &amp;lt;&amp;lt; Ch[i];&lt;br /&gt;
 Salida:&lt;br /&gt;
 Ch[0] = U Ch[1] = O Ch[2] = I Ch[3] = E Ch[4] = A&lt;br /&gt;
&lt;br /&gt;
Es significativo que el objeto v es una estructura de datos que permite acceder individualmente a sus miembros &amp;quot;como si&amp;quot; fuesen elementos de una matriz. También que se pueden aplicar ciertas operaciones sobre la totalidad, o parte, de esta estructura considerada como una unidad.&lt;br /&gt;
== Clasificación ==&lt;br /&gt;
Existen dos tipos de contenedores: secuencias y asociativos; a su vez se subdividen según el tipo de [[Iteradores (Programación)|iterador]] que soportan.&lt;br /&gt;
&lt;br /&gt;
Las secuencias almacenan los elementos en orden secuencial (de ahí su nombre). El contenedor agrupa a todos sus miembros como una sucesión lineal, y en consecuencia son adecuadas para accesos directos y secuenciales. Un ejemplo de secuencia es una matriz. De hecho, los algoritmos que pueden aplicarse a las secuencias pueden aplicarse también a las matrices.&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, por lo que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.  La STL proporciona cinco tipos distintos.&lt;br /&gt;
&lt;br /&gt;
La existencia de índices supone una ordenación según los valores de un conjunto de elementos (denominado &amp;quot;de claves&amp;quot;) para el que debe existir un criterio de ordenación. Dicho en otras palabras, los objetos &amp;quot;de clave&amp;quot; deben ser de un tipo para el que estén definidos los operadores relacionales. El árbol es mantenido ordenado de forma automática por los algoritmos de inserción y borrado del contenedor.&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave y para recorrer el conjunto (ordenado) de los elementos.&lt;br /&gt;
&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] contiene diez formas de contenedores y tres adaptadores de contenedor (denominados simplemente [[Adapter|adaptadores]]). En esta sección se expondrán brevemente cuales son estas formas; sus características, y cuál es la más adecuada para cada tipo de problema específico. En secciones sucesivas se comentarán individualmente con mayor detalle.&lt;br /&gt;
Relación siguiendo la clasificación utilizada en el Estándar:&lt;br /&gt;
  • Secuencias&lt;br /&gt;
      o	deque&lt;br /&gt;
      o	list&lt;br /&gt;
      o	stack&lt;br /&gt;
      o	vector&lt;br /&gt;
      o	vector &amp;lt;bool&amp;gt;&lt;br /&gt;
  • adaptadores&lt;br /&gt;
      o	queue&lt;br /&gt;
      o	priority_queue&lt;br /&gt;
  • Contenedores asociativos&lt;br /&gt;
      o	map&lt;br /&gt;
      o	multimap&lt;br /&gt;
      o	set&lt;br /&gt;
      o	multiset&lt;br /&gt;
      o	bitset&lt;br /&gt;
== Características ==&lt;br /&gt;
Las características más significativas de las diversas formas de contenedor son:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Contenedor&lt;br /&gt;
! Características&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;big&amp;gt;Secuencias&amp;lt;/big&amp;gt;&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| vector&lt;br /&gt;
| Este contenedor es una estructura de datos de tamaño fijo preferentemente. Aunque la STL proporciona herramientas para cambiar el tamaño de un vector de forma dinámica, esta operación es costosa y debe ser evitada dentro de lo posible (en este sentido el vector se comporta como una matriz ordinaria).&lt;br /&gt;
&lt;br /&gt;
Disponen de un buén mecanismo de acceso aleatorio a elementos y de un mecanismo de inserción al final muy eficiente.&lt;br /&gt;
&lt;br /&gt;
Generalmente es preferible utilizar un vector que un deque o un list, a menos que sea frecuentemente necesario insertar datos al comienzo o al final, en cuyo caso es mejor utilizar un deque.  Si por el contrario es frecuente la inserción de elementos en el centro, entonces es preferible un list.&lt;br /&gt;
|-&lt;br /&gt;
| vector&amp;lt;bool&amp;gt;&lt;br /&gt;
| Es una versión de la anterior especial para valores binarios (bits).&lt;br /&gt;
|-&lt;br /&gt;
| list&lt;br /&gt;
| Este contenedor responde a la idéa intuitiva de &amp;quot;lista&amp;quot;, el almacenamiento de objetos en una secuencia lineal que no está necesariamente ordenada (aunque sus miembros pueden ser ordenados fácilmente mediante la función-miembro sort() ). Estos contenedores suelen ser implementados como listas doblemente enlazadas. &lt;br /&gt;
&lt;br /&gt;
Dispone de mecanismos eficientes para insertar elementos al principio, al final o en cualquier posición (utilizando iteradores que denoten posición). Estas operaciones consumen un tiempo constante con independencia del número de elmentos albergados en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Dado que son estructuras lineales, en general los elementos no pueden ser accedidos por subíndices como en un vector.  Es necesario realizar un recorrido lineal por todos los valores, por lo que en las operaciones de acceso se utilizan tiempos proporcionales al número de elementos.&lt;br /&gt;
|-&lt;br /&gt;
| stack&lt;br /&gt;
| Contenedor de elementos tipo pila LIFO que permite inserciones y eliminaciones solo en la parte superior.&lt;br /&gt;
|-&lt;br /&gt;
| deque&lt;br /&gt;
| Los deques o colas de doble terminación (&amp;quot;Double-ended queue&amp;quot;) son un tipo de estructura de datos que comparte las características de las colas (&amp;quot;Queues&amp;quot;) y las pilas (&amp;quot;Stacks&amp;quot;). Como en las colas , los elementos pueden ser empujados por un extremo al interior del contenedor, y el primer elemento introducido puede ser extraído por el extremo opuesto. Al mismo tiempo, el último elemento introducido por el principio puede ser extraído en ese mismo extremo como si fuese una pila.&lt;br /&gt;
 &lt;br /&gt;
Estos contenedores suelen ser implementados bajo la forma de matrices bidimensionales.&lt;br /&gt;
&lt;br /&gt;
Las características de los deques implementados en la STL pueden resumirse en: Acceso aleatorio; mecanismo eficiente de inserción al principio o al final.&lt;br /&gt;
|-&lt;br /&gt;
| string&lt;br /&gt;
| Contenedor de caracteres adaptado a operaciones con cadenas de caracteres.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;big&amp;gt;Asociaciones&amp;lt;/big&amp;gt;&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| set&lt;br /&gt;
| Como el resto de contenedores asociativos, esta forma de contenedor mantiene los elementos en orden. Dispone de mecanismos eficientes para inclusión, inserción y eliminación de elementos, y soporta claves únicas (solo puede existir un miembro con una clave determinada).&lt;br /&gt;
|-&lt;br /&gt;
| multiset&lt;br /&gt;
| Versión del anterior que permite la existencia de claves duplicadas. Es decir, distintos elementos dentro del conjunto pueden responder a la misma clave.&lt;br /&gt;
|-&lt;br /&gt;
| bitset&lt;br /&gt;
| Contenedor de bit más orientado al tamaño que hacia el tipo de contenido. Permite almacenar secuencias de bits de tamaño fijo. No existen iteradores para reccorrerlas, y sus elementos se acceden utilizando el operador subíndice.&lt;br /&gt;
 &lt;br /&gt;
Se dispone de varias funciones para realizar con ellos operaciones de bits &lt;br /&gt;
|-&lt;br /&gt;
| map&lt;br /&gt;
| Como el resto de estructuras asociativas, el map mantiene sus elementos ordenados. Se caracteriza porque sus miembros son pares de valores que pueden ser de tipos distintos. Uno de ellos, el que actúa como clave para el índice (&amp;quot;Key-value&amp;quot;), puede ser de cualquier tipo, a condición de que sus elementos puedan ser ordenados según un criterio (por defecto se utiliza el operador &amp;lt;).&lt;br /&gt;
 &lt;br /&gt;
Permite claves únicas. Es decir, que solo puede existir un miembro para cada clave. Dispone de mecanismos de inserción y borrado muy eficientes y no existe límite de tamaño. La estructura se encarga de crecer y disminuir en concordancia con las necesidades de sus miembros. Permite el operador [ ] subíndice para los elementos de la clave así como otras técnicas de acceso.&lt;br /&gt;
&lt;br /&gt;
Estas estructuras de datos recibe también los nombres de diccionarios, tablas y matrices asociativas, en referencia a que pueden considerarse como dos matrices del mismo número de elementos, en las que existe una relación entre cada miembro de una con otro miembro de la otra.  Una de las matrices (que actúa de índice) estaría ordenada según su contenido&lt;br /&gt;
|-&lt;br /&gt;
| multimap&lt;br /&gt;
| En todo igual que el anterior pero permitiendo además claves duplicadas. Es decir, que una misma clave pueda estar asociada a dos &amp;quot;valores&amp;quot; distintos.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Adaptador&lt;br /&gt;
! Características&lt;br /&gt;
|-&lt;br /&gt;
| queue&lt;br /&gt;
| Contenedor tipo cola FIFO que permite inserciones al final y eliminaciones al principio.&lt;br /&gt;
|-&lt;br /&gt;
| priority queue&lt;br /&gt;
| Este contenedor dispone de mecanismos eficientes para acceso y eliminación de grandes valores.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Seleccionar un contenedor ==&lt;br /&gt;
El binomio contendor-iterador conforma una herramienta que se adapta a circunstancias muy variadas. Es posible que un determinado problema pueda ser abordado de varias formas, en estos casos la selección de la forma de contenedor más adecuado depende de las circunstancias. En ciertas ocasiones puede resultar bastante obvia; en otras puede no estar tan claro cuál es la mejor opción, pues &amp;quot;a priori&amp;quot;, pueden adaptarse varias formas al caso concreto. Puede utilizarse el sistema de prueba y comparación. Por ejemplo, cronometrando los resultados obtenidos en un modo u otro. También será de gran ayuda la experiencia, pero como una guía o criterio general puede utilizarse el principio de selección que se indica a continuación.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Como se accederá a los datos?.&lt;br /&gt;
| Si es importante un acceso aleatorio, pueden utilizarse un vector o un deque. Si basta con un acceso secuencial cualquiera de los dos puede ser el elegido.&lt;br /&gt;
|-&lt;br /&gt;
| Es importante el orden en que serán mantenidos los valores dentro de la colección de datos?&lt;br /&gt;
| Existen muchas formas de secuenciar los valores. Si es importante un orden estricto a lo largo de toda la vida del contenedor, la elección obvia es un set, dado que las inserciones en una de estas estructuras se realizan automáticamente en orden.&lt;br /&gt;
 &lt;br /&gt;
Si este orden es importante solo en algún momento, por ejemplo al final de una serie de inserciones, puede ser más sencillo colocar los valores en un list o vector para ordenar más tarde el resultado en el momento necesario.&lt;br /&gt;
&lt;br /&gt;
Si el orden en que se almacenan los valores en la estructura está relacionado con el orden de su inserción, entonces un stack, un queue o un list pueden ser la mejor elección.&lt;br /&gt;
|-&lt;br /&gt;
| Puede variar mucho el tamaño de la estructura de datos durante el curso de la ejecución del programa?&lt;br /&gt;
| Si es así, entonces puede ser que la mejor opción sean un list o un set. Un vector o un deque pueden conducir a mantener un gran almacenamiento intermedio (buffer); incluso después que los elementos hayan sido eliminados de la colección de datos. Estos dos contenedores no son adecuados para cambios de tamaño, aunque vector dispone de un mecanismo de inserción al final eficiente.&lt;br /&gt;
 &lt;br /&gt;
Recíprocamente: si el tamaño de la colección se mantiene relativamente estable, entonces un vector o un deque pueden utilizar menos memoria que un list o un set que almacenen el mismo número de elementos.&lt;br /&gt;
|-&lt;br /&gt;
| Es posible determinar el tamaño de la colección?&lt;br /&gt;
| La estructura de datos vector proporciona un medio para pre-seleccionar un bloque de memoria de un tamaño específico con la función miembro reserve, posibilidad que no existe en otros contenedores.&lt;br /&gt;
|-&lt;br /&gt;
| Es frecuente tener que comprobar si un valor cualquiera está incluido en la colección?&lt;br /&gt;
| En este caso, un contenedor set o map pueden ser buena elección. En estos casos comprobar si un determinado valor está incluido puede ser realizado con un pequeño número de pasos (logarítmicos con el tamaño del contenedor). Mientras que la misma verificación en cualquiera de los otros tipos puede requerir comparar el valor con cada elemento almacenado en el contenedor.&lt;br /&gt;
|-&lt;br /&gt;
| Está indexada la colección de datos? &lt;br /&gt;
| Si las claves son enteros entre 0 y un límite superior, pueden utilizarse un vector o un deque. &lt;br /&gt;
|-&lt;br /&gt;
| Si es así, puede ser vista la colección como una serie de pares clave/valor?&lt;br /&gt;
| Si la clave es algún otro valor, como cadenas de caracteres o tipos definidos por el usuario, puede utilizarse un contenedor map.&lt;br /&gt;
|-&lt;br /&gt;
| Pueden los valores estar relacionados unos con otros?&lt;br /&gt;
| Todos los valores almacenados en cualquier contenedor de la STL debe ser capaz de comprobar la igualdad con cualquier otro valor similar, pero recuerde que no todos son capaces de reconocer el operador de relación menor-que; sin embargo, si los valores no pueden ser ordenados utilizando el operador menor-que, no pueden ser almacenados en un set o en un map.&lt;br /&gt;
|-&lt;br /&gt;
| Es una operación frecuente tener que encontrar y eliminar el valor mayor de la colección?&lt;br /&gt;
| En caso afirmativo, la estructura de datos más idónea es el priority queue.&lt;br /&gt;
|-&lt;br /&gt;
| En que posiciones son insertados o eliminados los elementos de la estructura?&lt;br /&gt;
| Si los valores son añadidos o eliminados en la zona interior, entonces la mejor opción es un list.&lt;br /&gt;
 &lt;br /&gt;
Si los valores son insertados solo al comienzo, un deque o un list pueden ser lo más adecuado.&lt;br /&gt;
&lt;br /&gt;
Si los valores son insertados y eliminados solo al final, un stack o un queue pueden ser elecciones lógicas.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| Es frecuente tener que refundir dos o más secuencias en una sola?&lt;br /&gt;
| En caso afirmativo, puede considerarse que las mejores opciones son un set o un list, dependiendo que la colección deba o no ser mantenida en orden.&lt;br /&gt;
 &lt;br /&gt;
Refundir dos set es una operación muy eficiente.  Si la colección de datos no está ordenada, pero puede utilizarse la función miembro splice() de las list (que es muy eficiente), entonces es preferible este último tipo de contenedor, dado que esta operación no está contemplada en las demás formas.&lt;br /&gt;
|}&lt;br /&gt;
=== Tipos no incluidos ===&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] incluye contenedores adecuados para la mayoría de los casos prácticos, aunque quizás existen una serie de estructuras de datos clásicas que no han sido incluidas. En la mayoría de los casos, la causa es que los contenedores proporcionados pueden ser fácilmente adaptados para suplir los usos facilitados por los tipos omitidos.&lt;br /&gt;
&lt;br /&gt;
Tipos clásicos no incluidos y la sustitución más fácil.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Contenedor omitido&lt;br /&gt;
! Sustitución utilizando elementos de STL&lt;br /&gt;
|-&lt;br /&gt;
| tree&lt;br /&gt;
| El modo set está implementado internamente como un árbol de búsqueda binaria. &lt;br /&gt;
&lt;br /&gt;
Para la mayoría de los casos prácticos que pueden ser resueltos utilizando árboles este modo es un sustituto adecuado.&lt;br /&gt;
|-&lt;br /&gt;
| matrices multidimensionales&lt;br /&gt;
| Puesto que los vectores pueden almacenar elementos que sean otros vectores, estas estructuras pueden ser construidas fácilmente.&lt;br /&gt;
|-&lt;br /&gt;
| graph&lt;br /&gt;
| La representación de un gráfico puede ser fácilmente construida como un map que contiene otros map. Un map cuyos elementos son a su vez maps, es la representación natural de un gráfico directo. &lt;br /&gt;
|-&lt;br /&gt;
| sparse array&lt;br /&gt;
| Una novedosa sustitución es la representación de un gráfico&lt;br /&gt;
|-&lt;br /&gt;
| hash table&lt;br /&gt;
| Las tablas hash proporcionan un tiempo de acceso constante, así como inserción y borrado de elementos, convirtiendo estas operaciones en operaciones de índice.&lt;br /&gt;
 &lt;br /&gt;
Una tabla hash puede ser construida fácilmente como un vector (o deque) cuyos elementos son lists (o incluso sets).  En el ejemplo de la ordenación raíz (  xxx) se describe una de estas estructuras (un vector de deques), aunque en este ejemplo no incluye invocación la función hash para convertir un valor en un índice.&lt;br /&gt;
|-&lt;br /&gt;
| Funcionalidad set&lt;br /&gt;
| En la STL, los tipos set están específicamente ordenados, y sus operaciones (como la unión intersección, etc.) no pueden ser realizadas sobre colecciones de valores no ordenados (por ejemplo un conjunto de números complejos).&lt;br /&gt;
 &lt;br /&gt;
Una list puede ser utilizada como sustituto, aunque es necesario escribir funciones de operación especiales, dado que los algoritmos genéricos no pueden ser utilizados con listas.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Gestión de memoria ==&lt;br /&gt;
La gestión de memoria realizada por los contenedores comprende tanto la asignación y liberación de espacio para sus miembros, como para las claves que constituyen el sistema de índice de algunos tipos de contenedor. En general los algoritmos de la STL están muy optimizados y el sistema de asignación de memoria intenta compaginar rapidez y eficacia. La primera exige asignar y desasignar espacio cada vez que se introduce o elimina un miembro del contenedor. La eficacia, e incluso la disminución de la fragmentación inherentes al manejo del montón, exige asignar y rehusar trozos de memoria lo más grandes posible cada vez. El abordaje a este problema se ha realizado de dos formas básicas: (a) Contenedores que no pueden alterar su tamaño, de forma que la asignación de espacio para sus elementos debe realizarse en el momento de su declaración. (b) Contenedores que pueden crecer y/o disminuir en consonancia con los elementos a albergar.&lt;br /&gt;
&lt;br /&gt;
Refiriéndonos al caso (b), para balancear estas exigencias contrapuestas, algunas implementaciones utilizan el siguiente esquema de trabajo: inicialmente el sistema asigna al contenedor un trozo de memoria de tamaño adecuado para contener cierto número de elementos; espacio que es utilizando hasta que se agota. A partir de aquí, cada nueva demanda origina la asignación una zona de doble tamaño que la anterior. Por ejemplo, supongamos que para gestionar un vector de enteros, el compilador asigna inicialmente espacio para un máximo de 16 miembros.  Cuando se agotara, se realizaría una nueva asignación de espacio para 32 miembros, e inmediatamente se efectuaría una recolocación del contenido actual en el nuevo espacio y la liberación del primitivo. Si el nuevo contenedor quedara lleno de nuevo, la siguiente asignación sería capaz de 64 miembros y así sucesivamente.&lt;br /&gt;
&lt;br /&gt;
El factor de aumento de tamaño puede ser cualquiera. Muchos compiladores utilizan un factor 1.5 cada vez que deben ampliar el espacio necesario.&lt;br /&gt;
&lt;br /&gt;
Cada nueva recolocación implica varios pasos:&lt;br /&gt;
  •	Asignación de memoria al estilo malloc() de la librería clásica en cantidad suficiente para el nuevo tamaño.&lt;br /&gt;
  •	Copia de los elementos actuales en la nueva localización. Los elementos son colocados en la nueva situación utilizando el constructor copia.&lt;br /&gt;
  •	Actualización de las estructuras internas del nuevo contenedor (sistema de índices).&lt;br /&gt;
  •	Eliminación de los elementos originales mediante invocación sucesiva de sus correspondientes destructores.&lt;br /&gt;
  •	Liberación de la memoria utilizada por las estructuras internas.&lt;br /&gt;
  •	Liberación de la zona original mediante una invocación al estilo free de la librería clásica.&lt;br /&gt;
&lt;br /&gt;
En general, al referirse al tamaño de un contenedor existen tres magnitudes distintas aunque relacionadas, cuyos valores pueden obtenerse mediante tres métodos:&lt;br /&gt;
&lt;br /&gt;
  •	El número de elementos contenidos actualmente. size()&lt;br /&gt;
  •	El máximo número de elementos que pueden alcanzarse actualmente sin necesidad de una nueva recolocación. capacity()&lt;br /&gt;
  •	El máximo número de elementos que pueden alcanzarse en cualquier caso. max_size().&lt;br /&gt;
&lt;br /&gt;
 Ejemplo:&lt;br /&gt;
   #include &amp;lt;iostream&amp;gt;&lt;br /&gt;
   using namespace std;&lt;br /&gt;
   #include &amp;lt;vector&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   int main() {         // ================&lt;br /&gt;
   vector&amp;lt;int&amp;gt; vInt;&lt;br /&gt;
   for (int i=0; i &amp;lt; 100; i++) vInt.push_back(i);&lt;br /&gt;
&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Tamaño actual:   &amp;quot; &amp;lt;&amp;lt; vInt.size()     &amp;lt;&amp;lt; endl;&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Capacidad actual: &amp;quot; &amp;lt;&amp;lt; vInt.capacity() &amp;lt;&amp;lt; endl;&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Tamano maximo:   &amp;quot; &amp;lt;&amp;lt; vInt.max_size() &amp;lt;&amp;lt; endl;&lt;br /&gt;
   return 0;&lt;br /&gt;
   }&lt;br /&gt;
   Salida:&lt;br /&gt;
   Tamaño actual: 100&lt;br /&gt;
   Capacidad actual: 256&lt;br /&gt;
   Tamano maximo: 1073741823&lt;br /&gt;
&lt;br /&gt;
En todos los casos: size() &amp;lt;= capacity()&lt;br /&gt;
&lt;br /&gt;
Es posible comprobar si un contenedor está vacío, comparando su tamaño actual size() con cero, aunque es más rápido utilizar el método empty(), que devuelve true si realmente size() == 0.&lt;br /&gt;
&lt;br /&gt;
=== Reserva de espacio ===&lt;br /&gt;
Como puede suponer, cada recolocación supone un proceso considerable, sobre todo en contenedores muy grandes. Para evitar sus inconvenientes si se conoce de antemano el tamaño máximo a utilizar, la STL ofrece la posibilidad de preasignar un espacio arbitrario. Para esto se dispone del método reserve(n), que garantiza la asignación de espacio inicial suficiente para alojar n miembros en el contenedor. Si el argumento n es mayor que la capacidad actual, se produce una recolocación y el nuevo argumento determina la nueva capacidad. Si es menor no se produce ninguna acción.&lt;br /&gt;
&lt;br /&gt;
Ejemplo, para crear un vector de enteros capaz para al menos 1000 miembros:&lt;br /&gt;
  vector &amp;lt;int&amp;gt; v;&lt;br /&gt;
  v.reserve(1000);&lt;br /&gt;
&lt;br /&gt;
En el siguiente ejemplo se muestran los resultados compilado con Borland C++ 5.5 para Win32; con MS Visual C++ 6.0 y con GNU gcc 2.95.3 para Linux:&lt;br /&gt;
  // resultados con:         BC++   VC++   GNU   &lt;br /&gt;
  vector&amp;lt;int&amp;gt; v;&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 0      0      0   &lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 0      0      0&lt;br /&gt;
  v.push_back(3);&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    1      1&lt;br /&gt;
  v.reserve(100);&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    100    100&lt;br /&gt;
&lt;br /&gt;
=== Operaciones sobre contenedores ===&lt;br /&gt;
Los elementos de un contenedor son colocados en él utilizando el constructor copia, aunque algunas operaciones requieren la existencia de un constructor por defecto. A su vez, los algoritmos genéricos, como copy(), que copian a un contenedor, utilizan el operador de asignación.&lt;br /&gt;
&lt;br /&gt;
Cuando se duplica todo un contenedor de tipos T por invocación del [[Constructor (C++)|constructor]] copia o por asignación, cada miembro es copiado en la nueva estructura utilizando el constructor copia o el operador de asignación. Tanto si una copia profunda o una copia somera, el resultado es controlado por el programador, que puede proporcionar el operador de asignación para el tipo T con cualquier significado que desee. Si se ha definido un destructor para el tipo T, este destructor es invocado cada vez que deba ser eliminado un elemento del contenedor. Cuando se destruye toda la colección, el destructor es invocado por cada elemento que permaneciera almacenado.&lt;br /&gt;
&lt;br /&gt;
En estos casos, el contenedor es solamente responsable de mantener los propios punteros, siendo responsabilidad del programador manejar la memoria de los valores referenciados por estos, lo que supone que los espacios de memoria son asignados correctamente; por lo general mediante el operador new; que no son desasignados mientras el contenedor albergue referencias a ellos, y que sean adecuadamente desasignados una vez que han sido eliminados del contenedor.&lt;br /&gt;
&lt;br /&gt;
===  Secuencias ===&lt;br /&gt;
Las secuencias son estructuras de datos de tipo lineal, con posibilidad de que su tamaño puede ser alterado insertando elementos al principio, al final o en cualquier posición, si bien la idoneidad en este sentido es distinta entre los diversos tipos.&lt;br /&gt;
&lt;br /&gt;
La STL ofrece los siguientes:&lt;br /&gt;
  • deque&lt;br /&gt;
  • list&lt;br /&gt;
  • stack&lt;br /&gt;
  • vector&lt;br /&gt;
  • vector&amp;lt;bool&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La estructura lineal implica que sus datos son lógicamente contiguos, aunque su disposición física puede que no lo sea. Los elementos pueden ser accedidos por un índice numérico, aunque en algunos tipos de secuencia el acceso a un elemento implica un recorrido por la lista.&lt;br /&gt;
&lt;br /&gt;
== Contenedores asociativos ==&lt;br /&gt;
Los contenedores asociativos son una extensión de las secuencias. Mientras que en estas para acceder a los elementos solo pueden utilizarse claves numéricas, que señalan el número de orden del elemento dentro de la secuencia (al estilo de los índices en las matrices). Los contenedores asociativos admiten cualquier tipo de clave de acceso. Las más frecuentes son las cadenas alfanuméricas (stings).&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, razón por la que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.&lt;br /&gt;
&lt;br /&gt;
La ordenación se realiza según los valores de ciertos miembros del contenedor. Estos elementos son denominados &amp;quot;de claves&amp;quot; (&amp;quot;Key values&amp;quot;). Lo que exige que los objetos &amp;quot;de clave&amp;quot; sean de un tipo para el que estén definidos los operadores relacionales. El contenedor es mantenido ordenado de forma automática por los algoritmos de inserción y borrado.&lt;br /&gt;
&lt;br /&gt;
La STL proporciona cinco tipo distintos, aunque en realidad son tres clases; dos de ellas en dos variedades (permitiendo o no claves duplicadas). Uno de los tipos (bitset) sirve para almacenar campos de bits de longitud constante. Los otros dos permiten elementos ordenados de cualquier tipo (set y multiset), mientras que map y multimap permiten alojar pares de elementos. Uno que actúa como &amp;quot;Key value&amp;quot; y otro que puede ser un tipo cualquiera al que llamaremos valor-dato.&lt;br /&gt;
&lt;br /&gt;
  • bitset&lt;br /&gt;
  • set&lt;br /&gt;
  • multiset&lt;br /&gt;
  • map&lt;br /&gt;
  • multimap&lt;br /&gt;
&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave, y para recorrer el conjunto (ordenado) de las claves.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http://www.zator.com/Cpp/E5_1_1.htm Contenerores C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Contenedores en C.conclase.net]&lt;br /&gt;
* [https://docs.microsoft.com/es-es/cpp/standard-library/stl-containers?view=vs-2017  Contenedores de la biblioteca estándar de C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Operador_new&amp;diff=3234249</id>
		<title>Operador new</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Operador_new&amp;diff=3234249"/>
		<updated>2018-11-29T18:29:32Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre=Operador new|imagen=  |concepto=Proporciona espacio de almacenamiento persistente, similar pero superior a la función de Librería Estándar malloc. Este operador permite crear un objeto de cualquier tipo, incluyendo tipos definidos por el usuario, y devuelve un puntero (del tipo adecuado) al objeto creado}}'''Operador new'''. Proporciona espacio de almacenamiento persistente, similar pero superior a la función de Librería Estándar malloc. Este operador permite crear un objeto de cualquier tipo, incluyendo tipos definidos por el usuario, y devuelve un puntero (del tipo adecuado) al objeto creado. Su utilización exige que el usuario declarare un puntero del tipo adecuado; a continuación debe ser inicializado con el valor devuelto por el operador. &lt;br /&gt;
== Sintaxis ==&lt;br /&gt;
 &amp;lt;::&amp;gt; new &amp;lt;(situación)&amp;gt;  tipoX  &amp;lt;(iniciador)&amp;gt;&lt;br /&gt;
 &amp;lt;::&amp;gt; new &amp;lt;(situación)&amp;gt; (tipoX) &amp;lt;(iniciador)&amp;gt;&lt;br /&gt;
* El argumento tipoX  es imprescindible. Indica el tipo de objeto para el que se obtendrá espacio de almacenamiento. Ejemplo:&lt;br /&gt;
 ClaseA* ptr = new ClaseA;&lt;br /&gt;
Si la especificación de tipoX es complicada, se permite englobarla en paréntesis para facilitar al compilador la correcta interpretación (segunda forma de la sintaxis). Ejemplo: el tipo de una matriz de diez punteros a función que no reciben argumentos y devuelven un int es: int(*[10])(). Sin embargo, la invocación a su construcción con new:&lt;br /&gt;
 new int(*[10])();        // Error&lt;br /&gt;
produce un error, ya que el compilador es incapaz de interpretar correctamente una sentencia como la anterior; en su lugar interpretaría:&lt;br /&gt;
 (new int) (*[10])();     // Error&lt;br /&gt;
Para evitar el error es necesario incluir la expresión en paréntesis:&lt;br /&gt;
 new (int (*[10])());     // Ok.&lt;br /&gt;
&lt;br /&gt;
El resto de argumentos, opcionales, son los siguientes:&lt;br /&gt;
* &amp;lt;::&amp;gt; Operador que invoca la versión global de new. Este argumento opcional se utiliza cuando existe una versión específica de usuario (sobrecargada) pero se desea utilizar la versión global (en caso contrario no es necesario).&lt;br /&gt;
* &amp;lt;(situación)&amp;gt;, este especificador opcional permite especificar el sitio concreto en que se realizará la reserva de memoria. Ejemplo:&lt;br /&gt;
 tipoX* xp = new (z) tipoX;   // definir sitio de almacenamiento&lt;br /&gt;
* &amp;lt;(iniciador)&amp;gt;, en su caso, se utiliza para inicializar el almacenamiento. Ejemplo:&lt;br /&gt;
 tipoX* xp = new tipoX (z);   // definir valor inicial&lt;br /&gt;
== Descripción == &lt;br /&gt;
En la expresión&lt;br /&gt;
 new ClaseC;&lt;br /&gt;
El operador new intenta asignar un espacio de tamaño sizeof(ClaseC) en la zona de memoria dinámica. A continuación intenta crear en esta posición una instancia de la clase utilizando el constructor adecuado. Como resultado de estas dos operaciones se obtiene la dirección (puntero) del objeto creado. Este puntero devuelto por new es del tipo correcto: puntero-a-ClaseC, sin que se necesaria ninguna conversión de tipo (&amp;quot;casting&amp;quot;) explícita.&lt;br /&gt;
Aunque el operador tiene algunas limitaciones, puede utilizarse con tipos calificados. Por ejemplo, es válido:&lt;br /&gt;
 new const ClaseC;&lt;br /&gt;
&lt;br /&gt;
Los objetos creados con new son persistentes, es decir, la vida del nuevo objeto es desde el punto de creación hasta el final del programa o hasta que el programador lo destruya explícitamente con el operador delete. Este último desasigna la zona de memoria ocupada por el objeto, de forma que queda disponible para nuevo uso. Las sucesivas invocaciones de este operador van reservando zonas de memoria en el montón para los objetos sucesivamente creados. El gestor de memoria del compilador se encarga de mantener una tabla con los sitios ocupados y libres sin que haya conflictos hasta que la memoria se ha agota, o no existe espacio contiguo suficiente para el nuevo objeto. En cuyo caso se lanza una excepción como indicativo del error.&lt;br /&gt;
El operador new puede aceptar un inicializador opcional para que rellene el espacio reservado con el valor suministrado. Sin embargo, su versión para matrices new[ ] no acepta iniciador. En caso de no proporcionarse iniciador, el objeto creado contiene basura.&lt;br /&gt;
Recordar que:&lt;br /&gt;
* Los objetos creados con new deben ser destruidos necesariamente con delete, y que las matrices creadas con new[ ] deben ser borradas con delete[ ]. &lt;br /&gt;
* Los objetos estáticos aunque son de carácter permanente, tienen su propia zona de almacenamiento distinta del montón, por lo que no se crean con este operador. &lt;br /&gt;
* Por razones evidentes, no es posible crear un objeto de un tipo ClaseC que sea una clase abstracta. &lt;br /&gt;
&lt;br /&gt;
La invocación del operador new en una sentencia como&lt;br /&gt;
 ClaseC* cPtr = new ClaseC;&lt;br /&gt;
implica tres operaciones que son realizadas automáticamente:&lt;br /&gt;
# Se reserva espacio suficiente en el montón para el objeto. new utiliza el operador sizeof para determinar el      espacio adecuado a reservar. A continuación invoca al constructor del      objeto (ver punto 3º ).&lt;br /&gt;
# Se crea un puntero cPtr adecuado al tipo (en este caso su tipo es      puntero-a-ClaseC). Este puntero se inicia con el valor de la dirección del      espacio reservado en el punto anterior.&lt;br /&gt;
# Si se utiliza un iniciador opcional, new invoca el constructor      correspondiente (que debe corresponder con los argumentos utilizados); en      caso contrario se utiliza el constructor por defecto. Así pues, si tipoX      es un tipo abstracto, definido por el usuario, debe existir un constructor      por defecto (que pueda ser invocado sin argumentos, pues new lo utilizará para crear el      objeto cuando sea invocado sin especificador de inicio.&lt;br /&gt;
== Peligros ==&lt;br /&gt;
La persistencia de los objetos creados con new y su independencia del ámbito desde el que han sido creados, es muy importante y de tener en cuenta, pues suele ser motivo de pérdidas de memoria en el programa si olvidamos destruirlos cuando ya no son necesarios. Hay que prestar especial atención, porque en una sentencia como:&lt;br /&gt;
 void func() {&lt;br /&gt;
  ...&lt;br /&gt;
  tipoX* Xptr = new tipoX;&lt;br /&gt;
  ...&lt;br /&gt;
 }&lt;br /&gt;
El área de almacenamiento señalada por el puntero es persistente, pero Xptr que es una variable local automática no lo es. Si olvidamos destruir el objeto creado (con delete) antes de salir del ámbito, el área de almacenamiento permanecerá ocupando espacio en el montón y no podrá ser recuperada nunca, pues el puntero Xptr habrá desaparecido.&lt;br /&gt;
== Limitaciones ==&lt;br /&gt;
En la especificación del tipo de objeto que debe crearse con new, no están permitidos los especificadores de almacenamiento static, auto y register. Tampoco typedef.&lt;br /&gt;
Ejemplo:&lt;br /&gt;
 int* iptr = new static int;        // Error!!&lt;br /&gt;
 int* iptr = new typedef int;       // Error!!&lt;br /&gt;
 int* iptr = new auto int;          // Error!!&lt;br /&gt;
 int* iptr = new register int;      // Error!!&lt;br /&gt;
Tampoco es posible crear referencias con new, ya que las referencias no son objetos sino nombres alternativos (alias) de objetos.&lt;br /&gt;
== Control de la operación ==&lt;br /&gt;
Si la operación tiene éxito, new devuelve un puntero no nulo (distinto de cero) al objeto. Si la asignación falla (como en caso de no haber suficiente espacio en memoria dinámica), se lanza la excepción bad_alloc, a menos que se defina un nuevo manejador de excepciones. Antes de intentar usar el nuevo objeto, el programa debe estar siempre preparado para capturar dicha excepción &lt;br /&gt;
Puesto que la invocación de new con éxito devuelve un puntero no nulo, la petición de espacio para 0 bytes devuelve un puntero &amp;quot;no nulo&amp;quot;, y las peticiones sucesivas en este sentido, devuelven punteros &amp;quot;no nulos&amp;quot; distintos.&lt;br /&gt;
== Asignar el valor devuelto ==&lt;br /&gt;
La forma usual de utilizar el operador new es en sentencias de asignación. Puesto que new devuelve un puntero, es utilizado en el lado derecho (Rvalue) de la asignación. En el lado izquierdo (Lvalue) debe existir un puntero de tipo adecuado para recibir el valor devuelto. Preste atención a las declaraciones de punteros de los siguientes ejemplos:&lt;br /&gt;
 UnaClase*  punt1 = new UnaClase;    // Ok.&lt;br /&gt;
 int* punt2 = new int;               // Ok.&lt;br /&gt;
 char* punt3 = new int;              // Ilegal&lt;br /&gt;
 char* punt4 = new char;             // Ok.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Operador new con matrices|Operador new con matrices]]&lt;br /&gt;
*[[Errores con el operador new|Errores con el operador new]]&lt;br /&gt;
*[[Operadores aritméticos|Operadores aritméticos]]&lt;br /&gt;
*[[Operadores lógicos|Operadores lógicos]]&lt;br /&gt;
*[[Operadores de manejo de bits|Operadores de manejo de bits]]&lt;br /&gt;
*[[Operador condicional|Operador condicional]]&lt;br /&gt;
*[[Operador coma|Operador coma]]&lt;br /&gt;
*[[Operadores relacionales|Operadores relacionales]]&lt;br /&gt;
*[[Operadores de asignación|Operadores de asignación]]&lt;br /&gt;
*[[Operadores de modelado de tipos|Operadores de modelado de tipos]]&lt;br /&gt;
*[[Operadores añadidos a expresión|Operadores añadidos a expresión]]&lt;br /&gt;
*[[Operador de acceso a ámbito|Operador de acceso a ámbito]]&lt;br /&gt;
*[[Operadores de puntero|Operadores de puntero]]&lt;br /&gt;
*[[Operador delete|Operador delete]]&lt;br /&gt;
*[[Operador sizeof|Operador sizeof]]&lt;br /&gt;
*[[Operador typeid|Operador typeid]]&lt;br /&gt;
*[[Operador de preproceso|Operador de preproceso]]&lt;br /&gt;
*[[Contenedores C++]]&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://www.zator.com/Cpp/E4_9_20.htm Operador new]&lt;br /&gt;
* [http://c.conclase.net/curso/?cap=013b Operador new en C.conclase.net]&lt;br /&gt;
* [http://es.scribd.com/doc/52676357/57/Operadores-new-y-delete Operadores new y delete]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]] [[Category:Programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Operador_delete&amp;diff=3234248</id>
		<title>Operador delete</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Operador_delete&amp;diff=3234248"/>
		<updated>2018-11-29T18:29:17Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre=Operador delete|imagen=  |concepto=El operador delete ofrece una desasignación dinámica de memoria, desasignando un bloque previamente asignado con new. Es similar pero superior a la función free de la Librería Estándar.}}&lt;br /&gt;
'''Operador delete.''' Los operadores delete y delete[] sirven respectivamente para destruir los objetos creados con new y new[], volviendo a dejar la memoria asignada a disposición del gestor de memoria del [[compilador]].&lt;br /&gt;
Los objetos creados con [[Operador new|new]] deben ser destruidos necesariamente con delete, y que las matrices creadas con new[ ] deben ser borradas con delete[ ].&lt;br /&gt;
== El operador delete ==&lt;br /&gt;
El operador delete (palabra clave) ofrece una desasignación dinámica de memoria, desasignando un bloque previamente asignado con new. Es similar pero superior a la función free de la Librería Estándar.&lt;br /&gt;
Este [[Operadores|operador]] debe utilizarse para remover toda la memoria previamente asignada con new; de no hacerse así, puede producirse un agotamiento de la memoria. Sin embargo no puede usarse para desasignar memoria previamente asignada con malloc.&lt;br /&gt;
Es muy frecuente encontrar a este operador en destructores de clases, a fin de desasignar el espacio de los objetos cuando dicho espacio fue asignado con el [[Operador new|operador new]] en el constructor.&lt;br /&gt;
=== Sintaxis ===&lt;br /&gt;
 &amp;lt;::&amp;gt; delete &amp;lt;cast-expression&amp;gt;&lt;br /&gt;
 &amp;lt;::&amp;gt; delete [ ] &amp;lt;cast-expression&amp;gt;  // para matrices&lt;br /&gt;
 delete &amp;lt;array-name&amp;gt; [ ];           // para matrices&lt;br /&gt;
=== Ejemplos ===&lt;br /&gt;
 char* p;&lt;br /&gt;
 void func() {&lt;br /&gt;
   p = new char[10];     // asigna espacio para 10 char&lt;br /&gt;
   ...&lt;br /&gt;
   delete[] p;           // desasigna el espacio anterior&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 void* sptr;            // puntero genérico&lt;br /&gt;
 (std::string*) sptr = new std::string[10];    // L.2&lt;br /&gt;
 ...&lt;br /&gt;
 delete [] (std::string*) sptr;                // L.4&lt;br /&gt;
std::string es un calificador de tipo; se refiere a un objeto tipo string. Observe que L.2 realiza la asignación de espacio para el objeto (en este caso el contenedor está previsto para 10 caracteres) y además realiza un modelado sobre el puntero genérico sptr para adecuarlo al tipo devuelto por new. Finalmente, la sentencia L4 restituye el espacio reservado en L2.&lt;br /&gt;
== Precauciones con delete ==&lt;br /&gt;
Cuando este operador se utiliza con punteros (como en el ejemplo), es un gran error volver a utilizar la misma sentencia con el mismo puntero (esto puede suceder por error). Considere el siguiente código:&lt;br /&gt;
 delete ptr;&lt;br /&gt;
 ...&lt;br /&gt;
 delete ptr;       // Error!!&lt;br /&gt;
Si las sentencias entre ambos deleteno modifican el valor del puntero ptr, puede producirse un error grave. Recuerde que la desasignación de la memoria señalada por ptr no implica alteración del Rvalue(ptr), así que lo mejor es hacer:&lt;br /&gt;
 delete ptr;&lt;br /&gt;
 ptr = 0;&lt;br /&gt;
 ...&lt;br /&gt;
 delete ptr;       // Ahora sin riesgo!&lt;br /&gt;
Ya que por definición, el operador delete sobre un puntero nulo es una operación nula. Por esta razón, si se sobrecarga este operador, puede ser buena idea incluir en la función asignar cero al puntero:&lt;br /&gt;
 tipoX::operator delete(ptr) {&lt;br /&gt;
   ...&lt;br /&gt;
   ptr = NULL;&lt;br /&gt;
 }&lt;br /&gt;
Idéntica situación de riesgo se presenta cuando más de un puntero señala al mismo objeto:&lt;br /&gt;
 C* cptr = new C;&lt;br /&gt;
 C* dptr = cptr;&lt;br /&gt;
 ...&lt;br /&gt;
 delete cptr;&lt;br /&gt;
 delete dptr;        // Error!!&lt;br /&gt;
&lt;br /&gt;
También cuando el puntero inicial ha sido modificado inadvertidamente:&lt;br /&gt;
 char* p = new char[10];&lt;br /&gt;
 ...&lt;br /&gt;
 p++;&lt;br /&gt;
 ...&lt;br /&gt;
 delete[] p;         // Error!!&lt;br /&gt;
&lt;br /&gt;
Es un error aplicar el operador delete a un puntero cuyo valor no haya sido previamente asignado por new. Por ejemplo:&lt;br /&gt;
 void (* fptr)();&lt;br /&gt;
 void func() {...}&lt;br /&gt;
 const int ki;&lt;br /&gt;
 const int* kptr;&lt;br /&gt;
 ...&lt;br /&gt;
 ftpr = func;&lt;br /&gt;
 delete fptr;        // Error!! intento de borrar puntero a función&lt;br /&gt;
 kptr = &amp;amp;ki;&lt;br /&gt;
 delete kptr;        // Error!! intento de borrar puntero a constante&lt;br /&gt;
== Sobrecarga de los operadores delete/delete[ ] ==&lt;br /&gt;
No es posible sobrecargar la versión global de las funciones-operador ::operator delete() y ::operator delete()[ ]. Sin embargo es posible ocultarlas con versiones globales propias, aunque solo es posible definir una versión global de cada operador en cada aplicación.&lt;br /&gt;
Estas versiones deben devolver void, y su primer argumento debe ser un puntero-a-void (void*). Se admite un segundo argumento opcional de tipo size_t para indicar la cantidad de espacio a liberar. Por consiguiente, el prototipo puede ser algo así:&lt;br /&gt;
 void delete(void* Type_ptr [, size_t Type_size]) { ... };&lt;br /&gt;
 void delete[](void* Type_ptr [, size_t Type_size]) { ... };&lt;br /&gt;
&lt;br /&gt;
Las clases C que tengan su propia versión de los operadores new() y/o new()[], pueden tener también sus propias versiones sobrecargadas de los operadores delete y delete[]. Para ello se definen versiones propias de las funciones-operador C::operator delete[]() y C::operator delete() según los siguientes prototipos:&lt;br /&gt;
void operator delete(void* Type_ptr [, size_t Type_size]);&lt;br /&gt;
void operator delete[](size_t Type_ptr [, size_t Type_size]);&lt;br /&gt;
* Type_ptr es un puntero-al-objeto (instancia de clase) que se desea destruir.&lt;br /&gt;
* Type_size es un argumento opcional tipo size_t indicando el tamaño del objeto.&lt;br /&gt;
== El operador delete con matrices ==&lt;br /&gt;
Para borrar matrices debe utilizarse la segunda forma de la sintaxis:&lt;br /&gt;
delete [] &amp;lt;array-name&amp;gt;;&lt;br /&gt;
=== Ejemplo ===&lt;br /&gt;
 for (i = 0; i &amp;lt; fil; i++)   // Paso 1: Borrar columnas&lt;br /&gt;
  delete [] x[i];&lt;br /&gt;
 delete [] x;                // paso 2: borrar filas&lt;br /&gt;
&lt;br /&gt;
Estas expresiones el primer par de llaves [ ] están vacías, es la forma de indicar al operador delete que se trata del espacio de una matriz. Como puede verse en la segunda línea, opcionalmente puede indicarse un elemento a borrar.&lt;br /&gt;
En el capítulo dedicado a la Inicialización indirecta de matrices puede encontrarse una completa descripción y ejemplos del proceso para crear y destruir matrices en el montón, lo que supone la utilización de los operadores new y delete.&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Operadores aritméticos|Operadores aritméticos]]&lt;br /&gt;
*[[Operadores lógicos|Operadores lógicos]]&lt;br /&gt;
*[[Operadores de manejo de bits|Operadores de manejo de bits]]&lt;br /&gt;
*[[Operador condicional|Operador condicional]]&lt;br /&gt;
*[[Operador coma|Operador coma]]&lt;br /&gt;
*[[Operadores relacionales|Operadores relacionales]]&lt;br /&gt;
*[[Operadores de asignación|Operadores de asignación]]&lt;br /&gt;
*[[Operadores de modelado de tipos|Operadores de modelado de tipos]]&lt;br /&gt;
*[[Operadores añadidos a expresión|Operadores añadidos a expresión]]&lt;br /&gt;
*[[Operador de acceso a ámbito|Operador de acceso a ámbito]]&lt;br /&gt;
*[[Operadores de puntero|Operadores de puntero]]&lt;br /&gt;
*[[Operador new|Operador new]]&lt;br /&gt;
*[[Operador new con matrices|Operador new con matrices]]&lt;br /&gt;
*[[Operador sizeof|Operador sizeof]]&lt;br /&gt;
*[[Operador typeid|Operador typeid]]&lt;br /&gt;
*[[Operador de preproceso|Operador de preproceso]]&lt;br /&gt;
*[[Contenedores C++]]&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://www.zator.com/Cpp/E4_9_21.htm Los operadores delete y delete[ ]]&lt;br /&gt;
* [http://es.scribd.com/doc/52676357/57/Operadores-new-y-delete Operadores new y delete]&lt;br /&gt;
* [http://es.scribd.com/doc/51802416/121/Operador-delete Operadores de manejo de memoria &amp;quot;new&amp;quot; y &amp;quot;delete&amp;quot;]&lt;br /&gt;
* [http://c.conclase.net/curso/?cap=013b Operador delete en c.conclase.net]&lt;br /&gt;
&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]] [[Category:Programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Constante_(Inform%C3%A1tica)&amp;diff=3234246</id>
		<title>Constante (Informática)</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Constante_(Inform%C3%A1tica)&amp;diff=3234246"/>
		<updated>2018-11-29T18:28:54Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;&lt;br /&gt;
{{Definición|Nombre=Constante (informática|imagen= |concepto=Es un valor que no puede ser alterado durante la ejecución de un programa}} &lt;br /&gt;
'''Constante (Informática).''' En [[Lenguaje de Programación|programación]], una constante es un valor que no puede ser alterado durante la ejecución de un programa. Corresponde a una longitud fija de un área reservada en la memoria principal del ordenador, donde el programa almacena valores fijos. El nombre de las constantes suele escribirse en mayúsculas en la mayoría de lenguajes. &lt;br /&gt;
&lt;br /&gt;
== Connotaciones  ==&lt;br /&gt;
&lt;br /&gt;
La palabra constante tiene en [[C++|C++]] dos connotaciones sutilmente diferentes aunque relacionadas:&amp;lt;br&amp;gt;1.1 La primera es el sentido normal de la palabra constante en lenguaje natural; es decir, datos (de cualquiera de los tipos posible) cuyos valores se han definido en el momento de escribir el código del programa, y no pueden ser modificados más tarde en tiempo de ejecución (lo que significa que sus valores deben ser resueltos en tiempo de compilación). Dicho en otras palabras: el [[Compilador (Informática)|compilador]] sabe cual es el valor de los objetos declarados como constantes y en base a este conocimiento puede hacer cuantas suposiciones sean válidas para conseguir la mayor eficiencia en tiempo de ejecución.&amp;lt;br&amp;gt;En este sentido, el concepto constante es justamente el opuesto a [[Variables|variable]], que corresponde a aquellos objetos-dato que pueden recibir nuevas asignaciones de valor a lo largo del programa. Dicho en otras palabras: entidades cuyo valor solo es conocido en tiempo de ejecución.&amp;lt;br&amp;gt;1.2 La segunda connotación es la de tipo de objeto-dato. En este sentido podemos afirmar que en [[C++|C++]] los enteros (variables) forman un tipo distinto de los enteros constantes (constantes enteras), y que los caracteres (variables) forman un tipo distinto de las constantes carácter. Así pues, distinguimos entre un tipo char y un tipo const char. Como prácticamente todos los tipos de objeto-dato posibles en C++ puede declararse constantes, existe un universo de tipos C++, simétrico al de los tipos de objetos variables, pero de objetos constantes.&amp;lt;br&amp;gt;Por ejemplo, un entero y una constante entera son tipos distintos y que una constante entera C++ significa algo más que un entero al que no se le puede cambiar su valor. &lt;br /&gt;
&lt;br /&gt;
Lo que hace el compilador con los objetos declarados inicialmente como constantes depende de la implementación. Esto significa que no está garantizado que tales objetos tengan un Lvalue. Por ejemplo: en const int x = 5; no está garantizado que el compilador le asigne a x un Lvalue, es decir, un espacio en memoria determinado (que se permita modificar o no su valor es otra cuestión).&amp;lt;br&amp;gt;Puede ocurrir que, por razones de eficacia, sea simplemente una especie de &amp;quot;define&amp;quot;. Una especie de nemónico que hace que el compilador lo sustituya por un 5 en cada trozo de código donde aparezca x. Incluso en sitios donde aparezca asociada a otras constantes puede estar resuelto el valor en tiempo de compilación. Por ejemplo, si en otro sitio del programa aparece: const int z = 7; y más tarde: int w = x + z + y; puede ocurrir que el [[Compilador (Informática)|compilador]] establezca directamente: int w = 12 + y.&amp;lt;br&amp;gt;Por esta razón no está garantizado que el operador const_cast funcione con objetos declarados inicialmente como constantes. &lt;br /&gt;
&lt;br /&gt;
Como se ha indicado, en C++ existen tantos tipos de constantes como tipos de variables, pero aparte de las ya mencionadas constantes manifiestas, solo nos detendremos en las que por una u otra razón hay cosas interesantes que puntualizar. Son las siguientes:&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
   •[[Expresiones constantes|Expresiones constantes]] &lt;br /&gt;
   •[[Constantes enteras|Constantes enteras]] &lt;br /&gt;
   •[[Constantes fraccionarias|Constantes fraccionarias]] &lt;br /&gt;
   •[[Constantes_carácter_(Informática)|Constantes carácter]] de varios subtipos, incluyendo elementos    aislados y cadenas &lt;br /&gt;
   •[[Constantes de enumeración (Informática)|Enumeraciones]]&lt;br /&gt;
&lt;br /&gt;
El Estándar [[C++|C++]] denomina &amp;quot;literales&amp;quot; a lo que el Estándar [[C (lenguaje de programación)|C]] denomina &amp;quot;constantes&amp;quot;, y establece que existen 5 tipos de estos &amp;quot;literales&amp;quot;:&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
   •[[Constantes enteras|Constantes enteras(&amp;quot;Integer literal&amp;quot;)]]  &lt;br /&gt;
   •[[Constantes_carácter_(Informática)|Constantes carácter(&amp;quot;Character literal&amp;quot;)]]  &lt;br /&gt;
   •[[Constantes fraccionarias|Constantes fraccionarias(&amp;quot;Floating literal&amp;quot;)]] &lt;br /&gt;
   •[[Constantes de cadena (Informática)|Constantes de cadena (&amp;quot;String literal&amp;quot;)]]&lt;br /&gt;
   •Constantes lógicas (&amp;quot;Boolean literal&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Por la forma en que están expresadas en el código pueden considerarse en dos grupos:&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
*Directas si están directamente expresadas. Por ejemplo:&lt;br /&gt;
&lt;br /&gt;
   &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; const float pi = 3.14159; &amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
*Expresiones si su valor está implícito en una expresión. Por ejemplo:&lt;br /&gt;
&lt;br /&gt;
   &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; const float k = pi * 2; &lt;br /&gt;
&lt;br /&gt;
El tipo de dato correspondiente a una constante es deducido por el compilador en base a indicios implícitos, como el valor numérico y formato usados en el fuente. En algunos casos también por ciertos calificadores explícitos. C++ tiene una palabra específica para este fin: const&amp;lt;br&amp;gt;&lt;br /&gt;
'''Ejemplos:'''&amp;lt;br&amp;gt;&lt;br /&gt;
   char c = 'X'; // X es una constante tipo char&lt;br /&gt;
   const int X = 10; // X es un tipo int-constante &lt;br /&gt;
&lt;br /&gt;
== Ejemplo de una constante en C/C++  ==&lt;br /&gt;
&lt;br /&gt;
En C o C++ las constantes se declaran con la directiva #define, esto significa que esa constante tendrá el mismo valor a lo largo de todo el programa. El [[Identificadores|identificador]] de una constante así definida será una cadena de caracteres que deberá cumplir los mismos requisitos que el de una [[Variables|variable]] (sin espacios en blanco, no empezar por un dígito numérico, etc).&lt;br /&gt;
Ejemplo:&lt;br /&gt;
   #include &amp;amp;lt;stdio.h&amp;amp;gt; &lt;br /&gt;
   #define PI 3.1415926 &lt;br /&gt;
   int main()&lt;br /&gt;
   {&lt;br /&gt;
   printf(&amp;quot;Pi vale&amp;amp;nbsp;%f&amp;quot;, PI);&lt;br /&gt;
   return 0;&lt;br /&gt;
   }&lt;br /&gt;
Lo cual mostrará por pantalla:&lt;br /&gt;
   Pi vale 3.1415926&lt;br /&gt;
&lt;br /&gt;
Es decir, PI es una constante a la que le hemos asignado el valor 3.1415926 mediante la directiva #define.&lt;br /&gt;
La directiva #define también se puede utilizar para definir expresiones más elaboradas con operadores (suma, resta, multiplicación etc) y otras constantes que hayan sido definidas previamente, por ejemplo:&amp;lt;br&amp;gt; &lt;br /&gt;
   #define X 2.4 &lt;br /&gt;
   #define Y 9.2&lt;br /&gt;
   #define Z X + Y &amp;amp;lt;/div&amp;amp;gt; &lt;br /&gt;
&lt;br /&gt;
== Véase también  ==&lt;br /&gt;
&lt;br /&gt;
*[[Intérpretes|Intérpretes]] &lt;br /&gt;
*[[Tokens|Tokens]] &lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Contenedores C++]]&lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Signos de puntuación (Informática)|Signos de puntuación]]&lt;br /&gt;
*[[Constantes enteras|Constantes enteras]]&lt;br /&gt;
*[[Constantes fraccionarias|Constantes fraccionarias]]&lt;br /&gt;
*[[Constantes carácter (Informática)|Constantes carácter]]&lt;br /&gt;
*[[Constantes de cadena (Informática)|Constantes de cadena]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
&lt;br /&gt;
*[http://www.zator.com/Cpp/E3_2_3.htm www.zator.com]&lt;br /&gt;
&lt;br /&gt;
[[Category:Lenguajes_de_programación]] [[Category:Programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Enumeraciones_(Inform%C3%A1tica)&amp;diff=3234244</id>
		<title>Enumeraciones (Informática)</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Enumeraciones_(Inform%C3%A1tica)&amp;diff=3234244"/>
		<updated>2018-11-29T18:28:37Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre=Enumeraciones  (Informática)|imagen=   |concepto=Son un tipo especial de variables que tienen la propiedad de que su  rango de valores es un conjunto de constantes enteras denominadas  constantes de enumeración, a cada una de las cuales se le asigna un  valor}}&lt;br /&gt;
'''Enumeraciones (Informática)'''. Las [[Variables|variables]] enumeradas, enumeraciones o más abreviadamente enum (palabra reservada), son un tipo especial de variables que tienen la propiedad de que su rango de valores es un conjunto de constantes enteras denominadas constantes de enumeración, a cada una de las cuales se le asigna un valor. Para mayor legibilidad del código estos valores del rango se identifican por nemónicos. &lt;br /&gt;
 &lt;br /&gt;
==Ejemplo ==&lt;br /&gt;
 &lt;br /&gt;
Por ejemplo, la declaración:&lt;br /&gt;
 enum dia { DOM, LUN, MART, MIER, JUEV, VIER, SAB } diaX;&lt;br /&gt;
 &lt;br /&gt;
Establece un tipo enum al que se identifica por dia. Las [[Variables|variables]] de este tipo pueden adoptar un conjunto de seis valores enteros 0, 1, 2, 3, 4, 5, 6 (enumeradores) representados por los nemónicos DOM, LUN,...,SAB. Además se define una variable diaX de este tipo (variable enumerada).&lt;br /&gt;
 &lt;br /&gt;
En el ejemplo anterior, la variable diaX puede adoptar siete valores enteros (del 0 al 6). El programa los identifica con los nemónicos ya señalados.  Ojo: no confundir la variable -enumeración- con los valores que puede adoptar -[[Constantes de enumeración (Informática)|constante de enumeración]].&lt;br /&gt;
 &lt;br /&gt;
Cada enumeración distinta constituye un tipo de enumerando diferente. &lt;br /&gt;
 &lt;br /&gt;
Ejemplo:&lt;br /&gt;
 enum Calificacion {APTO, NO-APTO}  c1;&lt;br /&gt;
 enum Evolucion {SUBE, BAJA, IGUAL} c2; &lt;br /&gt;
c1 y c2 son objetos de tipo distinto.&lt;br /&gt;
 &lt;br /&gt;
Puede omitirse la palabra clave enum si dia no es [[Identificadores (Informática)|identificador]] de nada más en el mismo ámbito. El [[Compilador|compilador]] sabe que se trata de una variable tipo enum por la sintaxis de la propia declaración. Por ejemplo, es correcto: &lt;br /&gt;
 dia { DOM, LUN, MART, MIER, JUEV, VIER, SAB } diaX; &lt;br /&gt;
El identificador dia es la etiqueta opcional del tipo, y puede ser usada en subsecuentes declaraciones de variables del mismo tipo: &lt;br /&gt;
 enum Dia laborable, festivo;    // declara dos nuevas variables &lt;br /&gt;
aunque también se podría omitir el especificador enum (el compilador ya sabe  que Dia es de tipo enum): &lt;br /&gt;
 Dia laborable, festivo;         // equivalente al anterior &lt;br /&gt;
Como ocurre con las declaraciones de estructuras y uniones, si no existen otras variables del mismo tipo, puede omitirse la etiqueta con lo que tenemos un tipo anónimo:&lt;br /&gt;
 enum { DOM, LUN, MART, MIER, JUEV, VIER, SAB } diaX;&lt;br /&gt;
También aquí (como ocurre con las estructuras y uniones), el inconveniente de declarar un tipo anónimo es que después no podemos volver a declarar otra variable del mismo tipo. Observe que las expresiones que siguen no son equivalentes!!&lt;br /&gt;
 enum diaX { DOM, LUN, MART, MIER, JUEV, VIER, SAB };&lt;br /&gt;
 enum { DOM, LUN, MART, MIER, JUEV, VIER, SAB } diaX; &lt;br /&gt;
En [[C|C]], una variable enumerada puede recibir cualquier valor de tipo int sin que se realice ninguna otra comprobación; en cambio [[C++|C++]] es más fuertemente tipado en este sentido, y a una variable enumerada solo se le puede asignar uno de sus enumeradores. Ejemplo:&lt;br /&gt;
 diaX = LUN;       // Ok.&lt;br /&gt;
 diaX = 1;         // Ilegal, a pesar que LUN == 1 &lt;br /&gt;
Las enumeraciones proporcionan un modo muy flexible de asociar nombres con valores, algo que también puede hacerse con los #define, sin embargo, las enumeraciones (aún de un solo elemento) presentan ventajas entre las que podemos señalar:&lt;br /&gt;
Los valores pueden ser auto-generados &lt;br /&gt;
Las variables de enumeradas ofrecen la      posibilidad de comprobación. &lt;br /&gt;
El depurador puede ser capaz de imprimir los      valores de los enumeradores en su forma simbólica (lo que facilita      grandemente las comprobaciones). &lt;br /&gt;
En la práctica, las enumeraciones proporcionan un lugar (&amp;quot;placeholder&amp;quot;) muy conveniente para almacenar constantes enteras como códigos de error o de cualquier otro tipo que podamos manejar en nuestras aplicaciones. Por ejemplo: en lugar de utilizar&lt;br /&gt;
  #define ERROR_NO_ERROR    0    &lt;br /&gt;
  #define ERROR_NOT_FOUND   1&lt;br /&gt;
  #define ERROR_BUSY        2&lt;br /&gt;
  #define ERROR_FULL        3&lt;br /&gt;
  ...&lt;br /&gt;
Es más conveniente utilizar un enumerador:&lt;br /&gt;
 enum ERRORS { NO_ERROR, NOT_FOUND, BUSY, FULL, ... } err; &lt;br /&gt;
Los tipos enum pueden aparecer en cualquier sitio donde sea permitido un entero. Ejemplo:&lt;br /&gt;
 enum dias { LUN, MAR, MIER, JUEV, VIER, SAB, DOM } diaX;&lt;br /&gt;
 enum dias diapago;&lt;br /&gt;
 typedef enum dias DIAS;&lt;br /&gt;
 DIAS *diaptr;&lt;br /&gt;
 int i = MIER;&lt;br /&gt;
 diaX = LUN;          // Ok.&lt;br /&gt;
 *diaptr = diaX;      // Ok.&lt;br /&gt;
 LUN = MIER;          // ILEGAL: LUN es una constante! &lt;br /&gt;
==Visibilidad==&lt;br /&gt;
Las etiquetas de los enum comparten el mismo espacio de nombres que los de estructuras y uniones. Los [[Identificadores (Informática)|identificadores]] de los enumeradores comparten el mismo espacio que los identificadores de las variables ordinarias; de aquí se deduce que los nombres de los enumeradores de las distintas enumeraciones, tienen que ser diferentes (los valores no tienen porqué serlo ni aún en la misma enumeración).&lt;br /&gt;
===Ejemplo===&lt;br /&gt;
 int dom = 11;&lt;br /&gt;
 {&lt;br /&gt;
    enum dias { dom, lun, mar, mier, juev, vier, sab } diaX;&lt;br /&gt;
    /* el enumerador dom oculta otra declaracion de int dom */&lt;br /&gt;
    struct dias { int i, j;};   // ILEGAL: identificador dias ya usado&lt;br /&gt;
    double mar;                 // ILEGAL: redefinicion de mar&lt;br /&gt;
 }&lt;br /&gt;
 dom = 12;                      // int dom vuelve a ser visible &lt;br /&gt;
==Asignaciones a tipo enum==&lt;br /&gt;
 &lt;br /&gt;
En el [[Compilador|compilador]] Borland [[C++|C++]] 5.5, las reglas para expresiones que contengan tipos enum pueden forzarse a ser más estrictas activando el conmutador -A (que significa ANSI C++ estricto), con lo que el compilador refuerza las reglas con mensajes de error. Así, al asignar un entero a una variable enum (como en el ejemplo) produciría un error.&lt;br /&gt;
 enum color { Rojo, Verde, Azul };&lt;br /&gt;
  int f() {&lt;br /&gt;
    color c;&lt;br /&gt;
    c = 0;    // Incorrecto: a 'c' solo se le puede asignar Rojo, Verde o Azul&lt;br /&gt;
    return c;&lt;br /&gt;
  }&lt;br /&gt;
En estos casos de compilación estricta, se obtiene también un error cuando se pasa un entero como parámetro a una función que espera un enum o viceversa. Estudie el ejemplo propuesto teniendo en cuenta que el resultado de la expresión flag1|flag2 (OR inclusivo entre bits) es un entero.&lt;br /&gt;
 &lt;br /&gt;
En estos casos de compilación estricta, se obtiene también un error cuando se pasa un entero como parámetro a una función que espera un enum o viceversa. Estudie el ejemplo propuesto teniendo en cuenta que el resultado de la expresión flag1 | flag2 (OR inclusivo entre bits) es un entero.&lt;br /&gt;
 #include &amp;lt;iostream.h&amp;gt;&lt;br /&gt;
 enum En { flag1 = 0x01, flag2 = 0x02 };&lt;br /&gt;
 int f1(En) {                 // L.3:&lt;br /&gt;
   return (flag1 + 1);&lt;br /&gt;
 }&lt;br /&gt;
 void f2() {&lt;br /&gt;
   int x = f1(flag1|flag2);   // L.7:&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; x &amp;lt;&amp;lt; endl;&lt;br /&gt;
 }&lt;br /&gt;
 int main () {&lt;br /&gt;
   f2();&lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
Aquí En es un tipo enum; los enumeradores flag1 y flag2 son constantes de enumeración de valores 1 y 2 respectivamente, que han definidas en formato hexadecimal.&lt;br /&gt;
Al intentar compilar se produce un error: Cannot convert 'int' to 'En' in function f2() ya que la invocación a f1 en L7 espera un enum tipo En (como indica el prototipo de L3), pero se le pasa un int, ya que como se ha apuntado, la expresión flag1|flag2 produce un entero.&lt;br /&gt;
Para arreglarlo, aplicamos un modelado de tipo al argumento pasado a la invocación en L.7, que lo transforma en el tipo exigido, con lo que la compilación se realiza sin novedad.&lt;br /&gt;
 #include &amp;lt;iostream.h&amp;gt;&lt;br /&gt;
 enum En { flag1 = 0x01, flag2 = 0x02 };&lt;br /&gt;
 int f1(En) {                       // L.3:&lt;br /&gt;
   return (flag1 + 1);&lt;br /&gt;
 }&lt;br /&gt;
 void f2() {&lt;br /&gt;
   int x = f1(En (flag1|flag2) );   // L.7bis:&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; x &amp;lt;&amp;lt; endl;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 int main () {&lt;br /&gt;
   f2();&lt;br /&gt;
 }&lt;br /&gt;
 Salida:&lt;br /&gt;
 El valor es: 2&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[Sobrecarga de enumeraciones (Informática)|Sobrecarga de enumeraciones (Informática)]] &lt;br /&gt;
*[[Constante (Informática)|Constante]]&lt;br /&gt;
*[[Contenedores C++]]&lt;br /&gt;
*[[Parámetros y argumentos (programación)|Parámetros y argumentos (programación)]]&lt;br /&gt;
*[[Constantes de enumeración (Informática)|Constantes de enumeración (Informática)]]&lt;br /&gt;
*[[Funciones virtuales|Funciones virtuales]] &lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://www.zator.com/Cpp/E4_8.htm Enumeraciones]&lt;br /&gt;
*   [http://msdn.microsoft.com/es-es/library/cc138362.aspx Tipos de enumeración (Guía de programación de C#]&lt;br /&gt;
*  [http://shadowsecurity.info/449/programacion-en-c.html Programacion en C++ enumeracion usando enum]&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]] [[Category:Programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Operadores&amp;diff=3234242</id>
		<title>Operadores</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Operadores&amp;diff=3234242"/>
		<updated>2018-11-29T18:28:14Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre=Operadores |imagen= |concepto=Son un tipo de [[Tokens|tokens]] que pueden aparecer en las expresiones, e indican al compilador la realización de determinadas operaciones matemáticas, lógicas y numéricas}}'''Operadores'''. Son un tipo de [[Tokens|tokens]] que pueden aparecer en las expresiones, e indican al [[Compilador (Informática)|compilador]] la realización de determinadas operaciones [[Matemáticas|matemáticas]], lógicas y numéricas. Se aplican a variables u otros objetos denominados operandos y su efecto es una combinación de las siguientes acciones:&amp;lt;br&amp;gt; &lt;br /&gt;
*Producir un resultado-valor &lt;br /&gt;
*Alterar un operando &lt;br /&gt;
*Designar un objeto o función.&lt;br /&gt;
&lt;br /&gt;
== Ejemplos&amp;lt;br&amp;gt;  ==&lt;br /&gt;
&lt;br /&gt;
*y = a + b;&lt;br /&gt;
&lt;br /&gt;
En esta sentencia, el operador suma + produce un valor nuevo, pero no altera ninguno de los operandos (a y b); a su vez, el nuevo valor es asignado a la [[Variables|variable]] y mediante el operador de asignación =. En este caso el operando de la izquierda sí se ve alterado. &lt;br /&gt;
&lt;br /&gt;
*x++;&lt;br /&gt;
&lt;br /&gt;
Aquí el operador postincremento ++ produce un nuevo valor que es aplicado sobre el propio operando, de forma que queda alterado. Cuando un operador altera un operando se dice que tiene efectos laterales.&amp;lt;br&amp;gt;Nota: por lo general, los operadores aparecen a la derecha de expresiones de asignación (por ejemplo: y = 2 * y + x), pero en ocasiones estos &amp;quot;efectos laterales&amp;quot; se utilizan para conseguir expresiones muy compactas y de un cierto nivel de sofisticación, que incluso no necesitan del operador de asignación para producir el resultado. En estos casos su lógica es un poco más difícil de seguir que cuando estos efectos no se utilizan directamente.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
*z = (*fptr)(x, y);&lt;br /&gt;
&lt;br /&gt;
Aquí, el operador de indirección * es aplicado sobre el operando fptr que es un puntero-a-función. El resultado es un designador de función al que se aplica el operador ( ) de invocación de función con dos operandos x e y que actúan como argumentos. A su vez el resultado de este operador (invocación de función) es utilizado como argumento derecho del operador de asignación = que finalmente modifica uno de sus operandos (el operando izquierdo z)&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
== Clasificación&amp;lt;br&amp;gt;  ==&lt;br /&gt;
&lt;br /&gt;
Los operadores se pueden clasificar en unitarios, binarios y ternarios, según que necesiten uno, dos o tres operandos. Los operadores unitarios (denominados también unarios) se clasifican en dos tipos según la posición del operador (representado aquí por @) respecto del operando (representado aquí por n):&amp;lt;br&amp;gt;@n: Operador prefijo. Ejemplo: ++x&amp;lt;br&amp;gt;n@: Operador posfijo. Ejemplo: x++ &lt;br /&gt;
&lt;br /&gt;
== Observaciones &amp;lt;br&amp;gt;  ==&lt;br /&gt;
&lt;br /&gt;
*Los operadores pueden (en cierta forma) considerarse como funciones que tienen un álgebra un tanto especial. De hecho, al tratar la sobrecarga de operadores, veremos que precisamente la forma en que se definen es mediante una función, la función-operador. En este sentido podríamos imaginar que la expresión y = a + b es otra forma de representar algo como: y = suma(a, b). Del mismo modo, la asignación x = y sería algo así: asigna(x, y). Siguiendo con nuestra analogía, podríamos suponer que los operadores unitarios, binarios y ternarios serían funciones que aceptarían unos, dos o tres argumentos respectivamente y que la sobrecarga de operadores no es sino una forma encubierta de sobrecarga de funciones. &lt;br /&gt;
*Aunque las funciones [[C++|C++]] se designan con [[Identificadores|identificadores]] (nombres) que siguen las reglas generales ya señaladas, estas seudo-funciones se identifican con símbolos (+,=,&amp;amp;nbsp;::,*,-&amp;amp;gt;,etc). Muchos de ellos están compuesto de un solo [[Tokens|token]] (que puede estar repetido + y ++) aunque los hay de dos. Estos últimos son: new[], delete[], () y []. &lt;br /&gt;
*Antes de realizar la operación encomendada, los operadores pueden modificar el tipo de los operandos para que sean homogéneos, de forma que la operación pueda realizarse. Por ejemplo, al indicar i + f donde i sea un entero y f un float. Estas promociones se denominan conversiones estándar y son realizadas automáticamente por el compilador, pero deben ser tenidas en cuenta para evitar sorpresas.&lt;br /&gt;
&lt;br /&gt;
En general los operadores aceptan un tipo de operando determinado y específico, produciendo y/o modificando un valor de acuerdo con ciertas reglas, pero [[C++|C++]] permite redefinir la mayoría de ellos. Es decir, permite que puedan aceptar otro tipo de operandos y seguir otro comportamiento sin que pierdan el sentido y comportamiento originales cuando se usan con los operandos normales (los tipos básicos preconstruidos en el lenguaje). Esta circunstancia recibe el nombre de sobrecarga del operador.&amp;lt;br&amp;gt;No son sobrecargables los siguientes:&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
*( . ) Operador de selección de miembros &lt;br /&gt;
*( .* ) Operador de dereferencia &lt;br /&gt;
*(&amp;amp;nbsp;:: ) Operador de acceso a ámbito &lt;br /&gt;
*(&amp;amp;nbsp;?: ) Operador conditional &lt;br /&gt;
*( # ) Directiva de preprocesado &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Polimorfismo en los operadores&amp;lt;br&amp;gt;  ==&lt;br /&gt;
&lt;br /&gt;
Sin estar sobrecargado, dependiendo del contexto (número y tipo de operandos), un operador [[C++|C++]] puede tener más de un significado. Ejemplos:&amp;lt;br&amp;gt; El símbolo ámpersand &amp;amp;amp; puede ser interpretado como:&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
*[[Operadores_de_manejo_de_bits|AND entre bits]] A &amp;amp;amp; B &lt;br /&gt;
*Operador de referencia y = &amp;amp;amp;x &lt;br /&gt;
*Declarador de referencia int&amp;amp;amp; y = x&lt;br /&gt;
&lt;br /&gt;
El asterisco * puede ser interpretado como:&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
*Declaración de un tipo puntero-a tipo* ptr &lt;br /&gt;
*Operador de indirección x = *ptr &lt;br /&gt;
*Operador de multiplicación x * y &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Precedencia&amp;lt;br&amp;gt;  ==&lt;br /&gt;
&lt;br /&gt;
La precedencia es una regla de orden que se asocia con los operadores para establecer cual se aplicará primero en caso de aparecer varios en una misma expresión (una especie de &amp;quot;orden de importancia&amp;quot; de los operadores). Por ejemplo:&amp;lt;br&amp;gt;x = 2 + 3 * 4;&amp;lt;br&amp;gt;¿Cual será el resultado, 20 o 14? &lt;br /&gt;
&lt;br /&gt;
La primera regla en este sentido es que las expresiones se evalúan de izquierda a derecha, aunque no siempre. Por ejemplo, la regla izquierda → derecha nos conduciría a que en la expresión anterior, el valor de x es 20, lo cual no es cierto, ya que en C++ la multiplicación tiene mayor precedencia que la suma, así que el resultado es 14.&amp;lt;br&amp;gt;En C++ existen 16 niveles de precedencia, de modo que la regla izquierda → derecha solo se aplica en caso de operadores del mismo nivel &amp;lt;br&amp;gt;El operador de jerarquía más alta es el paréntesis, lo que aclara y justificada la tradicional costumbre algabráica de utilizar paréntesis para forzar el orden de las operaciones. Por ejemplo, si queremos que en la expresión anterior se ejecute primero el operador suma:&amp;lt;br&amp;gt;x = (2 + 3) * 4; // el resultado es 20&amp;lt;br&amp;gt;Aunque las reglas de precedencia se suponen conocidas por los programadores C++, aconsejamos generosidad a la hora de utilizar paréntesis en las expresiones. Además de facilitar la legibilidad evitan posibles errores. Así, aunque las dos sentencias que siguen son equivalentes, la segunda es de lectura más &amp;quot;relajante&amp;quot;.&amp;lt;br&amp;gt;x = 2 + 3 * 4;&amp;lt;br&amp;gt;x = 2 + (3 * 4); &lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Contenedores C++]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]  &lt;br /&gt;
*[[Signos de puntuación (Informática)|Signos de puntuación]]&lt;br /&gt;
*[[Operadores aritméticos|Operadores aritméticos]]&lt;br /&gt;
*[[Operadores lógicos|Operadores lógicos]]&lt;br /&gt;
*[[Operadores de manejo de bits|Operadores de manejo de bits]]&lt;br /&gt;
*[[Operador condicional|Operador condicional]]&lt;br /&gt;
*[[Operador coma|Operador coma]]&lt;br /&gt;
*[[Operadores relacionales|Operadores relacionales]]&lt;br /&gt;
*[[Operadores de asignación|Operadores de asignación]]&lt;br /&gt;
*[[Operadores de modelado de tipos|Operadores de modelado de tipos]]&lt;br /&gt;
*[[Operadores añadidos a expresión|Operadores añadidos a expresión]]&lt;br /&gt;
*[[Operador de acceso a ámbito|Operador de acceso a ámbito]]&lt;br /&gt;
*[[Operadores de puntero|Operadores de puntero]]&lt;br /&gt;
*[[Operador new|Operador new]]&lt;br /&gt;
*[[Operador new con matrices|Operador new con matrices]]&lt;br /&gt;
*[[Errores con el operador new|Errores con el operador new]]&lt;br /&gt;
*[[Operador delete|Operador delete]]&lt;br /&gt;
*[[Operador sizeof|Operador sizeof]]&lt;br /&gt;
*[[Operador typeid|Operador typeid]]&lt;br /&gt;
*[[Operador de preproceso|Operador de preproceso]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Sobrecarga de enumeraciones (Informática)|Sobrecarga de enumeraciones (Informática)]] &lt;br /&gt;
== Fuente&amp;lt;br&amp;gt;  ==&lt;br /&gt;
&lt;br /&gt;
*[http://www.zator.com/Cpp/E4_9.htm www.zator.com]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
[[Category:Lenguajes_de_programación]] [[Category:Programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Ficheros_en_C%2B%2B&amp;diff=3234241</id>
		<title>Ficheros en C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Ficheros_en_C%2B%2B&amp;diff=3234241"/>
		<updated>2018-11-29T18:27:29Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Definición&lt;br /&gt;
|nombre= Ficheros en C++&lt;br /&gt;
|imagen=&lt;br /&gt;
|tamaño=&lt;br /&gt;
|concepto= Es una colección de elementos lógicamente relacionados y almacenados en memoria secundaria. A más bajo nivel, un fichero es una secuencia de bits almacenado en algún dispositivo externo (como por ejemplo uno de memoria secundaria).&lt;br /&gt;
}}'''Ficheros en C++'''. Es simplemente un flujo externo que se puede abrir para entrada (dando lugar a un flujo de archivo de entrada que, para simplificar, llamaremos simplemente archivo o fichero de entrada), para salida (dando lugar a un flujo de archivo de salida que, para simplificar, llamaremos simplemente archivo o fichero de salida) o para entrada-salida(archivo o fichero de entrada-salida o archivo de E/S).&lt;br /&gt;
&lt;br /&gt;
== Definición, apertura y cierre de ficheros ==&lt;br /&gt;
*Declaración de Variables de tipo &amp;quot;Fichero&amp;quot;:&lt;br /&gt;
 &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| ifstream descriptor;             // Para fichero de entrada&lt;br /&gt;
|-&lt;br /&gt;
| ofstream descriptor;            // Para ficheros de salida&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*Apertura de [[Ficheros]] de Texto (supongamos TCadena nombre)&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| in.open(nombre);                // Apertura para Lectura&lt;br /&gt;
|-&lt;br /&gt;
| out.open(nombre);   //Apertura para Escritura. (borra el contenido si lo hubiera)&lt;br /&gt;
|-&lt;br /&gt;
| out.open(nombre,ios::app);             //Apertura para añadir datos al final&lt;br /&gt;
|-&lt;br /&gt;
| in.open(nombreios::in ios::out);  //Apertura para Lectura y Escritura&lt;br /&gt;
|-&lt;br /&gt;
| out.open(nombre,ios::in ios::out); //Apertura para Lectura y Escritura&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*Cierre de ficheros: Un fichero anteriormente abierto y con un descriptor asociado a él debe ser cerrado con el fin de liberar los recursos asociados a él de la siguiente forma:&lt;br /&gt;
&lt;br /&gt;
descriptor.close( )&lt;br /&gt;
&lt;br /&gt;
== Detección de fin de fichero y otras funciones==&lt;br /&gt;
*La función eof() que devuelve true si se ha alcanzado el final del fichero y falso en cualquier otro caso. REQUIERE LECTURA ADELANTADA: Para que la función eof() devuelva un valor de verdad (actualizado).&lt;br /&gt;
*La funcioón fail() devuelve true si existe un error en una operación de flujo asociada al fichero.&lt;br /&gt;
*La función bad() devuelve true si el flujo está corrupto.&lt;br /&gt;
*La función good() que devuelve true si no existe un error en una operación de flujo y false en caso contrario.&lt;br /&gt;
Antes de empezar a leer o escribir en un fichero es siempre conveniente verificar que la operación de apertura se realizó con éxito.&lt;br /&gt;
&lt;br /&gt;
== Ficheros de texto==&lt;br /&gt;
&lt;br /&gt;
La lectura y la escritura en un archivo de texto se puede realizar directamente con los operadores y al igual que se realiza sobre los flujos estándares cin y cout.&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
&lt;br /&gt;
*[[Ciencia de la Información]]&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Contenedores C++]]&lt;br /&gt;
*[[Puntero (C++)]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
==Fuente==&lt;br /&gt;
&lt;br /&gt;
*Laboratorio de Programación 1º A E.T.S.I. Informática Gestión&lt;br /&gt;
*[http://www.lcc.uma.es/~pastrana/LP/curso0405/P13_05.pdf Clase Práctica: Ficheros en C++]&lt;br /&gt;
*[http://www.forosuse.org/forosuse/showthread.php?t=3530 Foro Suse]&lt;br /&gt;
*[http://www.todoexpertos.com/categorias/tecnologia-e-internet/programacion/c-y-c------/respuestas/2373771/c-ficheros Todos Expertos]&lt;br /&gt;
&lt;br /&gt;
[[Category: Informática]] [[Category: Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Constructor_(C%2B%2B)&amp;diff=3234239</id>
		<title>Constructor (C++)</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Constructor_(C%2B%2B)&amp;diff=3234239"/>
		<updated>2018-11-29T18:27:17Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Definición&lt;br /&gt;
|nombre= Constructor en C++&lt;br /&gt;
|imagen=cODIGO.jpg.JPG&lt;br /&gt;
|tamaño=200px&lt;br /&gt;
|concepto= Los constructores son funciones miembro especiales que sirven para inicializar un objeto de una determinada clase cuando se declara.&lt;br /&gt;
}}'''Constructor en C++'''. Los constructores tienen el mismo nombre que la clase, no retornan ningún valor y no pueden ser heredados. Además deben ser públicos, no tendría ningún sentido declarar un constructor como privado, ya que siempre se usan desde el exterior de la clase, ni tampoco como protegido, ya que no puede ser heredado.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ejemplo de constructor en una clase llamada pareja==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;iostream.h&amp;gt;&lt;br /&gt;
 class pareja&lt;br /&gt;
 {&lt;br /&gt;
   public:&lt;br /&gt;
    //Constructor&lt;br /&gt;
    pareja(int a2, int b2);&lt;br /&gt;
    //Funciones miembros de la clase &amp;quot;pareja&amp;quot;&lt;br /&gt;
    void Lee(int &amp;amp;a2, int &amp;amp;b2);&lt;br /&gt;
    void Guardar(int a2, int b2);&lt;br /&gt;
   private:&lt;br /&gt;
    //Datos miembros de la clase &amp;quot;pareja&amp;quot;&lt;br /&gt;
    int a, b;&lt;br /&gt;
 }&lt;br /&gt;
 pareja::pareja(int a2, int b2)&lt;br /&gt;
 {&lt;br /&gt;
    a = a2;&lt;br /&gt;
    b = b2;&lt;br /&gt;
 }&lt;br /&gt;
 void pareja::Lee(int &amp;amp;a2, int &amp;amp;b2)&lt;br /&gt;
 {&lt;br /&gt;
    a2 = a;&lt;br /&gt;
    b2 = b;&lt;br /&gt;
 }&lt;br /&gt;
 void pareja::Guarda(int a2, int b2)&lt;br /&gt;
 {&lt;br /&gt;
    a = a2;&lt;br /&gt;
    b = b2;&lt;br /&gt;
 }&lt;br /&gt;
 int main(int argc, char *argv[])&lt;br /&gt;
 {&lt;br /&gt;
    pareja par1(12, 32);&lt;br /&gt;
    int x, y;&lt;br /&gt;
    par1.Lee(x, y);&lt;br /&gt;
    cout &amp;lt;&amp;lt; &amp;quot;Valor de par1.a: &amp;quot; &amp;lt;&amp;lt; x &amp;lt;&amp;lt;endl;&lt;br /&gt;
    cout &amp;lt;&amp;lt; &amp;quot;Valor de par2.b: &amp;quot; &amp;lt;&amp;lt; x &amp;lt;&amp;lt;endl;&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Sobrecarga de constructores==&lt;br /&gt;
&lt;br /&gt;
También pueden definirse varios constructores para cada clase, es decir, la función constructor puede sobrecargarse. La única limitación es que no pueden declararse varios constructores con el mismo número y el mismo tipo de argumentos.&lt;br /&gt;
&lt;br /&gt;
==Constructor copia==&lt;br /&gt;
&lt;br /&gt;
Un constructor de este tipo crea un objeto a partir de otro objeto existente. Estos constructores sólo tienen un argumento, que es una referencia a un objeto de su misma clase.&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
&lt;br /&gt;
*[[Ciencia de la Información]]&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Contenedores C++]]&lt;br /&gt;
*[[Puntero (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
==Fuente==&lt;br /&gt;
&lt;br /&gt;
*Curso de C++. Autor: [[Salvador Pozo Coronado]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Informática]][[Category:Programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=C%2B%2B&amp;diff=3234238</id>
		<title>C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=C%2B%2B&amp;diff=3234238"/>
		<updated>2018-11-29T18:26:55Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Ficha Software&lt;br /&gt;
|nombre=C++&lt;br /&gt;
|familia=Derivados de C&lt;br /&gt;
|imagen=C++.jpg&lt;br /&gt;
|tamaño=&lt;br /&gt;
|descripción=Lenguaje de programación&lt;br /&gt;
|imagen2=&lt;br /&gt;
|tamaño2=&lt;br /&gt;
|descripción2=&lt;br /&gt;
|creador=Bjarne Stroustrup&lt;br /&gt;
|desarrollador=&lt;br /&gt;
|diseñador=&lt;br /&gt;
|modelo de desarrollo=&lt;br /&gt;
|lanzamiento inicial=1983&lt;br /&gt;
|versiones=&lt;br /&gt;
|última versión estable=&lt;br /&gt;
|género=&lt;br /&gt;
|sistemas operativos=Multiplataforma&lt;br /&gt;
|idioma=&lt;br /&gt;
|licencia=&lt;br /&gt;
|premios=&lt;br /&gt;
|web=&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''C++''' es un lenguaje imperativo orientado a objetos derivado del C. En realidad un superconjunto de C, que nació para añadirle cualidades y características de las que carecía. El resultado es que como su ancestro, sigue muy ligado al hardware subyacente, manteniendo una considerable potencia para programación a bajo nivel, pero se la han añadido elementos que le permiten también un estilo de programación con alto nivel de abstracción. Estrictamente hablando, C no es un subconjunto de C++; de hecho es posible escribir código C que es ilegal en C++. Pero a efectos prácticos, dado el esfuerzo de compatibilidad desplegado en su diseño, puede considerarse que C++ es una extensión del C clásico. La definición &amp;quot;oficial&amp;quot; del lenguaje nos dice que C++ es un lenguaje de propósito general basado en el C, al que se han añadido nuevos tipos de datos, clases, plantillas, mecanismo de excepciones, sistema de espacios de nombres, funciones inline, sobrecarga de [[Operadores|operadores]], referencias, operadores para manejo de memoria persistente, y algunas utilidades adicionales de librería (en realidad la [[Librería|librería]] Estándar C es un subconjunto de la librería C++) &amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
== Un Poco de historia  ==&lt;br /&gt;
&lt;br /&gt;
El comité para el estándar [[ANSI|ANSI]] [[C]] fue formado en [[1983]] con el objetivo de crear un lenguaje uniforme a partir del C original, desarrollado por Kernighan y Ritchie en 1972, en la ATT. Hasta entonces el estándar lo marcaba el libro escrito en 1978 por estos dos autores1. El lenguaje C++ se comenzó a desarrollar en 1980. Su autor fue [[Bjarne Stroustrup]], también de la ATT. Al comienzo era una extensión del lenguaje C que fue denominada C with classes. Este nuevo lenguaje comenzó a ser utilizado fuera de la ATT en [[1983]]. El nombre C++ es también de ese año, y hace referencia al carácter del operador incremento de C (++). Ante la gran difusión y éxito que iba obteniendo en el mundo de los programadores, la ATT comenzó a estandarizarlo internamente en [[1987]]. En [[1989]] se formó un comité ANSI (seguido algún tiempo después por un comité [[ISO|ISO]]) para estandarizarlo a nivel americano e internacional. En la actualidad, el C++ es un lenguaje versátil, potente y general. Su éxito entre los programadores profesionales le ha llevado a ocupar el primer puesto como herramienta de desarrollo de aplicaciones. El C++ mantiene las ventajas del C en cuanto a riqueza de [[Operadores|operadores]] y expresiones, flexibilidad, concisión y eficiencia. Además, ha eliminado algunas de las dificultades y limitaciones del C original. La evolución de C++ ha continuado con la aparición de [[Java]], un lenguaje creado simplificando algunas cosas de C++ y añadiendo otras, que se utiliza para realizar aplicaciones en Internet. Hay que señalar que el C++ ha influido en algunos puntos muy importantes del ANSI C, como por ejemplo en la forma de declarar las funciones, en los punteros a void, etc. En efecto, aunque el C++ es posterior al C, sus primeras versiones son anteriores al ANSI C, y algunas de las mejoras de éste fueron tomadas del C++. C++ es a la vez un lenguaje procedural (orientado a algoritmos) y orientado a objetos. Como lenguaje procedural se asemeja al C y es compatible con él, aunque ya se ha dicho que presenta ciertas ventajas. Como lenguaje orientado a objetos se basa en una filosofía completamente diferente, que exige del programador un completo cambio de mentalidad. Las características propias de la Programación Orientada a Objetos (Object Oriented Programming, u OOP) de C++ son modificaciones mayores que sí que cambian radicalmente su naturaleza.&lt;br /&gt;
&lt;br /&gt;
==Conceptos generales de la programación orientada a objetos== &lt;br /&gt;
&lt;br /&gt;
*Clase: Es una plantilla que define la      estructura  de un conjunto de objetos, que al ser creados se llamarán las       instancias de la clase. Esta estructura está compuesta por la definición       de los atributos y la implementación de las operaciones ( métodos  ). &lt;br /&gt;
&lt;br /&gt;
*Objeto: Es la      implementación de una instancia de  clase, es decir, una ocurrencia de      esta, que tiene los atributos  definidos por la clase, y sobre la que se      puede ejecutar las  operaciones definidas en ella. &lt;br /&gt;
&lt;br /&gt;
*Identidad:      Característica de cada objeto que lo  diferencia de los demás, incluyendo      de aquellos que pudieran  pertenecer a la misma clase y tener los mismos      valores en sus  atributos.&lt;br /&gt;
&lt;br /&gt;
*Herencia: Es      la capacidad que tienen las clases para heredar propiedades y métodos de      otras clases. &lt;br /&gt;
&lt;br /&gt;
== Acerca de la POO  ==&lt;br /&gt;
&lt;br /&gt;
La [[POO|POO]] es una nueva filosofía de programación que se basa en la utilización de objetos. El objetivo de la POO no es sino la meta de cualquier modelo de programación estructurada convencional: &amp;quot;imponer&amp;quot; una serie de normas de desarrollo que aseguren y faciliten la mantenibilidad y reusabilidad del código. Los mecanismos básicos de la POO son: objetos, mensajes, métodos y clases. &lt;br /&gt;
&lt;br /&gt;
*Objetos. Un objeto es una entidad que tiene unos atributos particulares (datos) y unas formas de operar sobre ellos (los métodos o funciones miembro). Es decir, un objeto incluye, por una parte una serie de operaciones que definen su comportamiento, y una serie de variables manipuladas por esas funciones que definen su estado. Por ejemplo, una ventana Windows contendrá operaciones como &amp;quot;maximizar&amp;quot; y variables como &amp;quot;ancho&amp;quot; y &amp;quot;alto&amp;quot; de la ventana. &lt;br /&gt;
*Mensajes. En C++, un mensaje se corresponde con el nombre de uno de los métodos de un objeto. Cuando se pasa un mensaje a un objeto, este responde ejecutando el código de la función asociada. &lt;br /&gt;
*[[Método|Método]]. Un método (función miembro) se implementa dentro de un objeto y determina como tiene que actuar el objeto cuando se produce el mensaje asociado. En C++ un método se corresponde con la definición de la función miembro del objeto. La estructura más interna de un objeto está oculta, de tal manera que la única conexión con el exterior son los mensajes &lt;br /&gt;
*Clases. Una clase es la definición de un tipo de objetos. De esta manera, una clase &amp;quot;Empleado&amp;quot; representaría todos los empleados de una empresa, mientras que un objeto de esa clase (también denominado instancia) representaría a uno de esos empleados en particular.&lt;br /&gt;
&lt;br /&gt;
Las principales características de la POO son: abstracción, encapsulamiento, herencia y polimorfismo: &lt;br /&gt;
&lt;br /&gt;
*[[Abstracción|Abstracción]]. Es el mecanismo de diseño en la POO. Nos permite extraer de un conjunto de entidades datos y comportamientos comunes para almacenarlos en clases. &lt;br /&gt;
*Encapsulamiento. Mediante esta técnica conseguiremos que cada clase sea una caja negra, de tal manera que los objetos de esa clase se puedan manipular como unidades básicas. Los detalles de la implementación se encuentran dentro de la clase, mientras que desde el exterior, un objeto será simplemente una entidad que responde a una serie de mensajes públicos (también denominados interfaz de la clase). &lt;br /&gt;
*Herencia. Es el mecanismo que nos permite crear clases derivadas (especialización) a partir de clases bases (generalización). Es decir, podríamos tener la clase &amp;quot;Empleado&amp;quot; (clase base) y la clase &amp;quot;Vendedor&amp;quot; derivando de la anterior. Una librería de clases (como la MFC) no es más que un conjunto de definiciones de clases interconectadas por múltiples relaciones de herencia. &lt;br /&gt;
*Polimorfismo. Esta característica nos permite disponer de múltiples implementaciones de un mismo método de clase, dependiendo de la clase en la que se realice. Es decir, podemos acceder a una variedad de métodos distintos (con el mismo nombre) mediante el mismo mecanismo de acceso. En C++ el polimorfismo se consigue mediante la definición de clases derivadas, funciones virtuales y el uso de punteros a objetos.&lt;br /&gt;
&lt;br /&gt;
Otros dos conceptos muy importantes en la POO son relativos a la creación y destrucción de objetos. En lenguajes estructurados convencionales, cuando se define una variable se le reserva espacio en memoria y, si no se inicializa expresamente, se hace por defecto (por ejemplo, en C una variable global siempre se inicializa a 0, pero una automática no, por lo que si no se inicializa expresamente su contenido inicial será basura); por otra parte, cuando se destruye una variable (por que se abandona el ámbito de su definición - scope -) se libera la memoria que estaba ocupando. Si ahora hacemos el paralelismo obligado entre variables y objetos para los lenguajes POO nos daremos cuenta de que deben existir procedimientos especiales de construcción y destrucción de objetos. En concreto, cada clase tiene dos funciones miembro especiales denominadas constructor y destructor. &lt;br /&gt;
&lt;br /&gt;
*[[Constructor (C++)|Constructor]] -&amp;amp;gt; Función miembro que es automáticamente invocada cada vez que se define un objeto, su objetivo es la inicialización del mismo. Toma el mismo nombre que la clase, puede recibir parámetros y podemos tener varios constructores definidos. &lt;br /&gt;
*[[Destructor|Destructor]] -&amp;amp;gt; Función miembro invocada automáticamente cada vez que se destruye un objeto. Su objetivo es realizar operaciones como liberación de memoria, cerrar ficheros abiertos, etc. Toma el mismo nombre de la clase comenzado primero por el carácter &amp;quot;~&amp;quot;, no toma parámetros y no admite la sobrecarga (sólo puede existir uno en cada clase).&lt;br /&gt;
&lt;br /&gt;
En muchos casos, para las clases mas sencillas, podemos encontrar clases que no tiene constructor o destructor, ó ninguno de los dos. En C++, siempre existen constructores y destructores por defecto que realizan una inicialización/liberación estándar.&lt;br /&gt;
&lt;br /&gt;
== Acerca de Intérprete y compiladores  ==&lt;br /&gt;
&lt;br /&gt;
Antes, mencionar que tanto C como C++ son lenguajes compilados, y no interpretados. Esta diferencia es muy importante, ya que afecta mucho a muchos aspectos relacionados con la ejecución del programa. En un lenguaje interpretado, el programa está escrito en forma de texto, es el propio programa fuente. Este programa fuente es procesado por un programa externo, el intérprete, que traduce el programa, instrucción a instrucción, al tiempo que lo ejecuta. En los lenguajes interpretados no existen programas ejecutables directamente por el ordenador. El intérprete traduce, en tiempo real, cada línea del programa fuente, cada vez que se quiere ejecutar el programa. El los lenguajes compilados el proceso de traducción sólo se hace una vez. El programa compilador toma como entrada el código fuente del programa, y da como salida un fichero que puede ser ejecutado por el ordenador directamente. Una vez compilado, el programa ejecutable es autónomo, y ya no es necesario disponer del programa original ni del compilador para ejecutarlo. Cada opción tiene sus ventajas e inconvenientes, y algunas características que son consideradas una ventaja, pueden ser un inconveniente en ciertas circunstancias, y viceversa. &lt;br /&gt;
&lt;br /&gt;
*Los lenguajes interpretados son fácilmente modificables, ya que necesitamos tener el el código fuente disponible en el ordenador. En los compilados, estos ficheros no son necesarios, una vez compilados. &lt;br /&gt;
*Los lenguajes interpretados necesitan un programa externo, llamado intérprete o a veces máquina virtual, o framework. Este programa actua como intermediario entre el fuente y el sistema operativo. En los compilados ese papel lo desempeña el compilador, pero al contrario que con el intérprete, una vez ha hecho su trabajo, no es necesario que esté presente para ejecutar el programa. &lt;br /&gt;
*Estas dos características, lógicamente, hacen que los programas compilados requieran menos espacio de memoria que los interpretados (si contamos el espacio usado por el intérprete), y en general, los compilados son más rápidos, ya que sólo se compilan una vez, y el tiempo dedicado a esa tarea no se suma al de ejecución.&lt;br /&gt;
&lt;br /&gt;
Entre los lenguajes interpretados están: [[BASIC|BASIC]] (Código de instrucciones de propósito general para principiantes), Java, [[PHP|PHP]]. Muchos lenguajes de script, etc. Entre los lenguajes compilados están: C, C++, Pascal. &lt;br /&gt;
&lt;br /&gt;
== Qué se puede hacer con C++  ==&lt;br /&gt;
&lt;br /&gt;
¿Qué clase de programas y aplicaciones se pueden crear usando C y C++? La respuesta es muy sencilla: TODOS. Tanto C como C++ son lenguajes de programación de propósito general. Todo puede programarse con ellos, desde sistemas operativos y compiladores hasta aplicaciones de bases de datos y procesadores de texto, pasando por juegos, aplicaciones a medida, etc. &lt;br /&gt;
&lt;br /&gt;
=== Un ejemplo de código  ===&lt;br /&gt;
&lt;br /&gt;
Este es el clásico programa hola mundo, la idea está centrada en el nacimiento de un nuevo programa de manos de su creador. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Hola mundo&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ¿Qué se ha hecho en C o en C++?  ==&lt;br /&gt;
&lt;br /&gt;
=== Sistemas Operativos y otros programas ===&lt;br /&gt;
&lt;br /&gt;
*Así como Unix el antecesor de este sistema operativo, [[GNU/Linux]] -a menudo denominado tan sólo como [[Linux]], que es el nombre del núcleo del SO- hace uso de un buen número de lenguajes de programación en sus distintos componentes. ¿Cuáles son esos lenguajes? Cada tipo de recurso parece tener ciertas preferencias, y es que hay lenguajes más adecuados para unas cosas. Obviamente el lenguaje de programación C sigue siendo la base, pero hay mucho más implicados. &lt;br /&gt;
*Kernel y drivers de dispositivos: Tanto los drivers como el kernel funcionan en un nivel realmente bajo de operaciones en el ordenador. Para escribir el kernel del sistema operativo y acceder a las propiedades del hardware tales como los ciclos de la memoria, buses de entrada/salida, etc., se necesita un lenguaje que pueda comunicarse con el hardware con potencia. El kernel Linux hace uso del lenguaje C (aunque en realidad no se trate de un lenguaje de bajo nivel) con una pequeña parte en lenguaje ensamblador. &lt;br /&gt;
&lt;br /&gt;
*Librerías y utilidades: Las librerías y utilidades básicas del sistema tales como mkdir, chmod, chown, head, tail, chroot, uptime, users también están escritas en lenguaje C.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
*Gestores de paquetes y programas de configuración: Los gestores de paquetes tales como yum, apt, dpkg, etcétera, también están escritos en C, que como veis es la estrella absoluta de los componentes &amp;quot;base&amp;quot; de un sistema [[GNU/Linux]].&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
*Entornos de Escritorio y gestores de ventanas: La mayoría de gente usa un entorno de escritorio, y es que a día de hoy poco queda sólo en interfaz de línea de comandos. Los gestores de ventanas tales como metacity, kwin están desarrollados en C y requieren gcc para ser compilados. El entorno de escritorio, iconos, ventanas, barras de herramientas, etc, están basados en librerías específicas (Qt para KDE, GTK+ para GNOME) y hacen uso del lenguaje mayoritario, C.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
*Aplicaciones gráficas de usuario: Este es el punto donde entran en juego una gran cantidad de lenguajes de programación, dado que básicamente es la capa más alta. Tenemos una gran variedad: C, Python, Java, Perl y otros. Hay librerías GTK+, Tcl/Tk, Qt que son un frontend gráfico a tareas que corren por detrás en línea de comando.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*El Sistema operativo [[Windows]] está hecho básicamente en C, C tiene la ventaja de que puede escalarse con ensamblador, lo cual es buena opción para optimizar ciertos módulos.&lt;br /&gt;
&lt;br /&gt;
Las versiones anteriores de Windows estaban hechas en Basic (Basic NO visual Basic) que es un lenguaje de bajo nivel de hace unos cuantos años ya. Es un lenguaje que se usa mucho en la electrónica aun. &lt;br /&gt;
&lt;br /&gt;
*Actualmente Windows 7 Mac os x Leopard y [[Linux]] usan mas de una Tecnología ya se empezó a usar [[Lenguaje de Programación C Sharp|c#]] c++ y hasta java en el caso de linux se usa phytom c y tbn ensambladores y demás cosas, y Mac siempre basado en Unix con compilación en C++ para los últimos Sistemas Operativos.&lt;br /&gt;
&lt;br /&gt;
== Ver también ==&lt;br /&gt;
&lt;br /&gt;
*[[Ciencia de la Información]]&lt;br /&gt;
*[[Puntero (C++)]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Contenedores C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
&lt;br /&gt;
== Fuentes  ==&lt;br /&gt;
&lt;br /&gt;
*[http://mat21.etsii.upm.es/ayudainf/aprendainf/Cpp/manualcpp.pdf Manual C++]&lt;br /&gt;
*[http://www.monografias.com/trabajos5/visualcurso/visualcurso.shtml Curso Visual]&lt;br /&gt;
*[http://www.zator.com/Cpp/E1_2.htm C++]&lt;br /&gt;
*[http://es.wikipedia.org/wiki/C%2B%2B C++ en Wikipedia]&lt;br /&gt;
*[http://www.programacionfacil.com/cpp:informacion_y_conocimiento C++ en ProgramacionFacil.com]&lt;br /&gt;
*[http://www.somoslibres.org/modules.php?name=News&amp;amp;file=article&amp;amp;sid=2708 C++ en SomosLibres.org]&lt;br /&gt;
*[http://www.psicofxp.com/forums/programacion.313/374200-c-y-sistemas-operativos.html El C++ y los Sistemas Operativos]&lt;br /&gt;
*[http://es.kioskea.net/forum/affich-101630-lenguaje-en-que-fue-escrito-windows Windows está escrito en C++]&lt;br /&gt;
&lt;br /&gt;
[[Category:Programación]][[Category:Informática]]&lt;br /&gt;
[[Category:Lenguajes_de_programación_orientada_a_objetos]]&lt;br /&gt;
[[Category:Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Librer%C3%ADa_Est%C3%A1ndar_C%2B%2B&amp;diff=3234236</id>
		<title>Librería Estándar C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Librer%C3%ADa_Est%C3%A1ndar_C%2B%2B&amp;diff=3234236"/>
		<updated>2018-11-29T18:26:36Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Librería Estándar C++ |imagen=  |concepto= Una librería es un conjunto de recursos (algoritmos) prefabricados, que pueden ser utilizados por el programador para realizar determinadas operaciones }}''' Librería Estándar C++ '''. [[C++|C++]] no llega al nivel de simplicidad de su antecesor C, pero al igual que aquél, tampoco dispone de utilidades o funciones para entrada o salida implementadas en el propio lenguaje, de modo que estas y otras muchas, como manejo de cadenas de caracteres (strings), manejo de ficheros, funciones matemáticas. son implementadas en forma de librerías externas.&lt;br /&gt;
== Sinopsis ==&lt;br /&gt;
Una librería es un conjunto de recursos (algoritmos) prefabricados, que pueden ser utilizados por el programador para realizar determinadas operaciones. Las declaraciones de las funciones (prototipos) utilizadas en estas librerías, junto con algunas macros y constantes predefinidas que facilitan su utilización, se agrupan en ficheros de nombres conocidos que suelen encontrarse en sitios predefinidos. Por ejemplo, en los sistemas UNIX, en  /usr/include. Estos ficheros se suelen llamar &amp;quot;de cabecera&amp;quot;, porque es tradición utilizar las primeras líneas del programa para poner las directivas #include que los incluirá en el fuente durante la fase de preprocesado.&lt;br /&gt;
== Clases de librerías ==&lt;br /&gt;
Los [[Compilador|compiladores]] [[C++|C++]] incluyen un amplio repertorio de clases, funciones y macros que permiten realizar una amplia variedad de tareas, incluyendo entradas/salidas de bajo y alto nivel; manipulación de cadenas alfanuméricas y ficheros; control de procesos (incluyendo multiproceso); manejo de memoria; cálculos matemáticos y un largo etcétera.&lt;br /&gt;
Este repertorio de recursos es denominado colectivamente como &amp;quot;Rutinas de librería&amp;quot;; &amp;quot;Librerías de ejecución&amp;quot; RTL (&amp;quot;Runtime Librarys&amp;quot;) o simplemente &amp;quot;Librerías&amp;quot;.   Puede decirse que el lenguaje aislado (tal cual) no tiene prácticamente ninguna utilidad sin la concurrencia de estas utilidades. El Estándar C++ las clasifica según su utilidad:&lt;br /&gt;
•	Soporte del lenguaje&lt;br /&gt;
•	Diagnóstico&lt;br /&gt;
•	Utilidades generales&lt;br /&gt;
•	Cadenas alfanuméricas (&amp;quot;Strings&amp;quot;)&lt;br /&gt;
•	Localización&lt;br /&gt;
•	Contenedores&lt;br /&gt;
•	Iteradores&lt;br /&gt;
•	Algoritmos&lt;br /&gt;
•	Cálculo numérico&lt;br /&gt;
•	Entrada/Salida&lt;br /&gt;
=== Librería Estándar C++ ===&lt;br /&gt;
Para poner un poco de orden, el Estándar C++ define la denominada Librería Estándar que debe acompañar a cada implementación del compilador que se adhiera al estándar. Es decir: la norma determina cuales son, como se llaman y como se utiliza este conjunto de algoritmos que deben acompañar (como mínimo) a cada implementación del compilador que quiera llamarse &amp;quot;Estándar&amp;quot;. La última versión, ISO/IEC 14882 del año 1998, especifica que se compone de 32 ficheros de cabecera de nombres fijos y conocidos agrupados según la funcionalidad de los algoritmos. Son los siguientes:&lt;br /&gt;
 &lt;br /&gt;
Ficheros	Funcionalidad/funciones&lt;br /&gt;
&lt;br /&gt;
&amp;lt;algorithm&amp;gt;	Parte de la STL que describe los algoritmos&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bitset&amp;gt;	Parte de la STL relativa a contenedores tipo bitset. Set de valores booleanos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;complex&amp;gt;	Parte de la librería numérica de la STL relativa a los complejos .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;deque&amp;gt;	Parte de la STL relativa a contenedores tipo deque;  un tipo de colas: &amp;quot;Double-ended-queue&amp;quot; .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;exception&amp;gt;	Parte de la librería de diagnóstico relativa al manejo de excepciones&lt;br /&gt;
&lt;br /&gt;
&amp;lt;fstream&amp;gt;	Flujos hacia/desde ficheros.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;functional&amp;gt;	Parte de la STL relativa a Objetos-función&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iomanip&amp;gt;	Manipuladores.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ios&amp;gt;	Supreclases para manejo de flujos de E/S.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iosfwd&amp;gt;	Contiene declaraciones adelantadas de todas las plantillas de flujos y sus typedefs estándar. Por ejemplo ostream.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iostream&amp;gt;	Parte del a STL que contiene los algoritmos estándar de E/S.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;istream&amp;gt;	Algoritmos estándar de flujos de entrada.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iterator&amp;gt;	Parte de la STL relacionada con iteradores, un tipo de puntero que permite utilizar los algoritmos de la Librería con las estructuras de datos representadas por los contenedores.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;limits&amp;gt;	Descripción de propiedades dependientes de la implementación que afectan a los tipos fundamentales.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;list&amp;gt;	Parte de la STL relativa a contenedores tipo list;  listas doblemente enlazadas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;locale&amp;gt;	Parte de la STL relativa a la internacionalización.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;map&amp;gt;	Parte de la STL relativa a contenedores tipo map.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;memory&amp;gt;	Utilidades relativas a la gestión de memoria, incluyendo asignadores  y punteros inteligentes (auto_ptr).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;new&amp;gt;	Manejo de memoria dinámica.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;numeric&amp;gt;	Parte de la librería numérica de la STL relativa a operaciones numéricas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ostream&amp;gt;	Algoritmos estándar para los flujos de salida.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;queue&amp;gt;	Parte de la STL relativa a contenedores tipo queue;  colas de objetos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;set&amp;gt;	Parte de la STL relativa a contenedores tipo set.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sstream&amp;gt;	Flujos hacia/desde cadenas alfanuméricas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;stack&amp;gt;	Parte de la STL relativa a contenedores tipo stack;  pilas de objetos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;stdexcept&amp;gt;	Parte de la STL relativa a las clases de las que derivan los objetos lanzados por las excepciones ocasionadas en los algoritmos de la propia STL y otras expresiones.  Estas clases son utilizadas para reportar errores detectados durante runtime.  Los usuarios también pueden utilizar excepciones para reportar errores en sus propios programas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;streambuf&amp;gt;	Parte de la STL relativa al Almacenamiento de flujos de E/S (&amp;quot;Stream buffers&amp;quot;).  Define los tipos que controlan la capa de transporte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;string&amp;gt;	Parte de la STL relativa a contenedores tipo string;  una generalización de las cadenas alfanuméricas para albergar cadenas de objetos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;typeinfo&amp;gt;	Mecanismo de identificación de tipos en tiempo de ejecución.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;utility&amp;gt;	Parte de la STL que contiene elementos auxiliares como [[Operadores|operadores]] y pares (pairs).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;valarray&amp;gt;	Parte de la librería numérica de la STL relativa a manejo de matrices numéricas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vector&amp;gt;	Parte de la STL relativa a los contenedores tipo vector; una generalización de las matrices unidimensionales C/C++.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Aunque generalmente las librerías no aportan ninguna característica al lenguaje (se supone que son utilidades auxiliares que no forman parte del lenguaje propiamente dicho), una pequeña porción de la Librería Estándar C++ sí aporta características que se consideran pertenecientes a este, de forma que deben estar presentes los ficheros de cabecera correspondientes si se desea usarlas. En concreto se refieren a los siguientes elementos:&lt;br /&gt;
&lt;br /&gt;
•	[[Operadores|operadores]] new, new[], delete y delete[].&lt;br /&gt;
&lt;br /&gt;
•	Clase type_info que corresponde al mecanismo RTTI de identificación de tipos en tiempo de ejecución representado por el operador typeid &lt;br /&gt;
&lt;br /&gt;
•	Rutinas de inicio y terminación.&lt;br /&gt;
&lt;br /&gt;
•	Las excepciones estándar lanzadas por los algoritmos anteriores&lt;br /&gt;
&lt;br /&gt;
=== Librería C ===&lt;br /&gt;
Además de otras nuevas, cuyo diseño e importancia cambian drásticamente la filosofía del lenguaje, C++ incluye prácticamente la totalidad de [[Función_(programación)| funciones]] de la primitiva librería estándar C. A esta librería, mantenida por compatibilidad, la denominamos Librería clásica.&lt;br /&gt;
=== Otras librerías ===&lt;br /&gt;
Además de las que proporciona el estándar y las complementarias que pueda incluir por su cuenta el fabricante del compilador, en los proyectos reales se suelen utilizar infinidad de otras librerías, comerciales o públicas, que facilitan el trabajo en áreas particulares, y en este sentido, recordar que uno de los pecados que el programador novel debe evitar, es la tendencia a querer reinventar constantemente la rueda. De forma que el consejo es utilizar en lo posible librerías que estén probadas y sean fácilmente accesibles. Aunque hay que tener cuidado, porque determinados proyectos exigen que las librerías utilizadas estén perfectamente documentadas y en ciertos casos, que se cuente con los fuentes correspondientes.&lt;br /&gt;
== Componentes ==&lt;br /&gt;
Al referirnos a las librerías C++ utilizamos la terminología siguiente:&lt;br /&gt;
&lt;br /&gt;
•	RTL  Conjunto de librerías que acompañan a un compilador (&amp;quot;Runtime Library&amp;quot;), sean o no estándar.&lt;br /&gt;
&lt;br /&gt;
•	Librería Estándar. Conjunto de librerías cuyo contenido está definido por el Estándar C++ (abreviadamente LE).&lt;br /&gt;
&lt;br /&gt;
•	Libería clásica. Parte de la Librería Estándar correspondiente al C clásico.&lt;br /&gt;
&lt;br /&gt;
•	STL (&amp;quot;Standard Templete Library&amp;quot;). Parte de la LE genuina de C++ (que no es heredada de C) y que responde a la forma &amp;quot;++&amp;quot; de hacer las cosas.&lt;br /&gt;
&lt;br /&gt;
La calidad de un compilador C++ viene determinada en gran medida por la calidad y cantidad de su RTL; por su grado de adherencia al Estándar  y por el grado de soporte que proporciona para la plataforma concreta a que se destina.&lt;br /&gt;
&lt;br /&gt;
En lo que concierne a la programación para MS Windows (las referencias a la plataforma Wintel surgen de forma constante e inevitable), los [[Compilador|compiladores]] Borland C++ y MS Visual C++ son quizás los más conocidos y utilizados.  El primero incluye una completa librería denominada VCL (Visual Component Library. La del segundo es conocida como MFC (Microsoft Foundation Classes).&lt;br /&gt;
&lt;br /&gt;
Linux dispone de su propio compilador: GNU Cpp, que comenzó siendo un compilador C y ha evolucionado a un producto que es en realidad un superconjunto de compiladores. No solo puede compilar código C y C++;  también otros lenguajes como Ada o Fortran;  de forma que es común referirse a ellos como GCC (&amp;quot;GNU Compiler Collection&amp;quot;).  La buena noticia es que existen versiones de este compilador para plataformas Windows, de forma que incluso en este ambiente &amp;quot;Propietario&amp;quot; pueden realizarse desarrollos utilizando herramientas &amp;quot;Open source&amp;quot; &lt;br /&gt;
A grandes rasgos la librería Estándar C++ comprende los siguientes módulos:&lt;br /&gt;
&lt;br /&gt;
•	La denominada Librería Estándar de Plantillas, abreviadamente STL (&amp;quot;Standard Templete Library&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
•	Librería numérica. Parte de la STL que contiene algoritmos especialmente concebidos para computación numérica. Por ejemplo, una clase valarray optimizada para matrices numéricas y una clase complex para manejo y representación estandarizada de números complejos (en realidad una plantilla con especializaciones para los tipos float, double y long double.&lt;br /&gt;
&lt;br /&gt;
•	Utilidades. Parte de la STL dedicada a elementos auxiliares tales como adaptadores y la clase auto_ptr.&lt;br /&gt;
&lt;br /&gt;
•	Unas utilidades de entrada/salida de flujos, denominadas genéricamente iostreams.&lt;br /&gt;
&lt;br /&gt;
•	Una utilidad locale para manejo de localismos.&lt;br /&gt;
&lt;br /&gt;
•	Una clase string para manejo estandarizado de cadenas de caracteres.  En realidad es una instanciación (especialización) de la plantilla basic_string para cadenas de caracteres.&lt;br /&gt;
 &lt;br /&gt;
•	Un esquema para describir de modo uniforme el entorno de ejecución mediante la utilización de una clase estándar denominada numeric_limits y especialización para cada uno de los tipos de datos fundamentales.&lt;br /&gt;
&lt;br /&gt;
•	Utilidades para manejo de memoria.&lt;br /&gt;
&lt;br /&gt;
•	Soporte para utilización de juegos de caracteres y signos de diversos idiomas.&lt;br /&gt;
&lt;br /&gt;
•	Utilidades de diagnóstico y manejo de errores. Incluyen manejo de excepciones y la macro assert.&lt;br /&gt;
&lt;br /&gt;
== Funcionalidad ==&lt;br /&gt;
Si atendemos a su funcionalidad,  las utilidades ofrecidas por la Librería Estándar pueden agruparse en:&lt;br /&gt;
&lt;br /&gt;
•	Clasificación: Clasifican caracteres ASCII, como letras, caracteres de control (no imprimibles), Mayúsculas/minúsculas etc. Se definen en la cabecera &amp;lt;ctype.h&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
•	Entradas/Salidas de Consola: Estas son las denominadas entrada/salida estándar. Por defecto se refieren al teclado y a la pantalla (no pueden utilizarse directamente en aplicaciones de interfaz gráfica).&lt;br /&gt;
&lt;br /&gt;
•	Conversión: Convierten caracteres y cadenas de caracteres desde formato alfabético a numérico de diversos tipos (float, int, long).  También realizan la conversión inversa: de formatos numéricos a representaciones alfabéticas y de mayúsculas a minúsculas y viceversa.&lt;br /&gt;
&lt;br /&gt;
•	Diagnóstico: Son rutinas destinadas a comprobaciones; a descubrir y corregir posibles errores.&lt;br /&gt;
&lt;br /&gt;
•	Directorio: Rutinas para manejo de directorios y sus direcciones (path names).&lt;br /&gt;
&lt;br /&gt;
•	En linea (Inline): Rutinas para versiones inline de funciones. El compilador genera el código correspondiente para las versiones inline cuando se utiliza #pragma intrinsic o si se solicita optimización al compilador (optimización de tiempo de ejecución).&lt;br /&gt;
&lt;br /&gt;
•	Entrada/Salida. Son rutinas que proporcionan manejo de flujos y operaciones de Entrada/Salida a bajo nivel (de Sistema Operativo).&lt;br /&gt;
&lt;br /&gt;
•	Manipulación. Manejo de cadenas y bloques de memoria: copiar, comparar, convertir y buscar.&lt;br /&gt;
&lt;br /&gt;
•	Matemáticas: Para realizar cálculos matemáticos.&lt;br /&gt;
&lt;br /&gt;
•	De Memoria: Proporcionan asignación de memoria dinámica.&lt;br /&gt;
&lt;br /&gt;
•	Miscelánea. Se agrupan aquí rutinas varias, como las que posibilitan saltos (goto) no locales y las que manejan diferencias de tipo cultural o de lenguaje. Por ejemplo representación de números, de moneda, formatos de fecha y hora, clasificación de tipo alfabético.&lt;br /&gt;
&lt;br /&gt;
•	Control de proceso. Rutinas que permiten invocar y terminar nuevos procesos desde otra rutina.&lt;br /&gt;
&lt;br /&gt;
•	Fecha y hora. Incluyen rutinas para conversión y manipulación de variables de medida del tiempo (fecha y hora).&lt;br /&gt;
&lt;br /&gt;
•	Argumentos variables. Rutinas utilizadas cuando se usan listas variables de argumentos, como en los casos de printf(), vscanf().&lt;br /&gt;
== Utilización ==&lt;br /&gt;
La utilización de la Librería Estándar C++ requiere de dos tipos de condiciones que podríamos describir como formales y conceptuales.&lt;br /&gt;
&lt;br /&gt;
1. En cuanto a las primeras (condiciones formales) y habida cuenta que las utilidades aparecen en forma de funciones, resulta evidente que su utilización exige incluirlas en nuestro programa. Para ello se necesitan tres pasos (en realidad las exigencias son las mismas que con cualquier otra función, la diferencia estriba en la forma en que se realizan los pasos b y c):&lt;br /&gt;
&lt;br /&gt;
a:  Incluir en el código fuente las invocaciones a las [[Función_(programación)| funciones]] que estamos utilizando. Ejemplo:&lt;br /&gt;
printf(&amp;quot;Esto es una llamada a la función \&amp;quot;printf\&amp;quot; de librería\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
 b:  Incluir en el código fuente los prototipos de dichas funciones.&lt;br /&gt;
&lt;br /&gt;
Puesto que los prototipos ya están incluidos en los ficheros estándar de cabecera, hay que indicar al compilador que los incluya. Esto se realiza poniendo en nuestro fuente (normalmente al principio) una directiva de preprocesado #include que señala el fichero de cabecera que se debe añadir. Por ejemplo, si el manual indica que la función printf está definida en el fichero de cabecera stdio.h ponemos en nuestro código:&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  c:  Incluir en el fuente las definiciones de las funciones utilizadas. Como alternativa se puede indicar al compilador que tales definiciones están en ficheros compilados previamente.&lt;br /&gt;
&lt;br /&gt;
En este último caso se dice que las definiciones de las funciones están en librerías de las que existen dos tipos: estáticas (.LIB, .OBJ y .BPI) y dinámicas (.DLL). Toda la información que necesita el compilador está contenida en los ficheros de cabecera, por lo que las operaciones correspondientes son realizadas de forma automática; con la sola condición de que los ficheros y librerías correspondientes sean accesibles al enlazador.&lt;br /&gt;
&lt;br /&gt;
Las entidades de la Librería Estándar C++ (que no están en ficheros de cabecera .h), se han definido en un espacio de nombres denominado std, por lo que es preciso referirse a él específicamente cuando se quieran utilizar estos recursos.&lt;br /&gt;
&lt;br /&gt;
2. Respecto a las que hemos denominado &amp;quot;condiciones conceptuales&amp;quot;, damos por sentado que la utilización de algoritmos de la Librería exige conocerlos. Pero debemos advertir que existe una gran diferencia entre las rutinas de la que hemos denominado librería clásica y los recursos de la nueva Librería Estándar de Plantillas STL.&lt;br /&gt;
&lt;br /&gt;
En general los algoritmos contenidos en la librería clásica realizan tareas muy sencillas bajo la forma de funciones que, con un cierto número de argumentos, realizan la tarea encomendada. A veces devolviendo un objeto (que puede ser una estructura). Su utilización exige poco más que repasar esta colección de funciones (209 en la última versión del Estándar) hasta encontrar la que mejor se ajusta a nuestras necesidades. Para esto lo mejor es recurrir a la clasificación temática ofrecida en la documentación que acompaña a los compiladores antes que a la lista alfabética de las mismas. A continuación estudiamos atentamente su prototipo y la explicación de funcionamiento que acompaña el manual (eventualmente incluso con un ejemplo) y ya estamos listos para utilizarla. En el peor de los casos suelen bastar un par de pruebas hasta que conseguimos ajustar los argumentos de forma que se consiga el resultado esperado.&lt;br /&gt;
&lt;br /&gt;
Como última recomendación al respecto, sobre todo si pensamos que nuestro programa tendrá una larga vida y/o pensamos portarlo a otras plataformas, aconsejaría echar un vistazo a la sección de &amp;quot;compatibilidad&amp;quot; que acompaña a la descripción de cada función en la documentación de la mayoría de compiladores. Suele ocurrir que el compilador ofrezca muchas más funciones que las estrictamente Estándar C++, y que estas no estén claramente separadas del resto, de forma que es posible que elijamos una función que resuelve nuestro problema pero no es portable, en cuyo caso aconsejaría evitarlas dentro de lo posible.&lt;br /&gt;
&lt;br /&gt;
La utilización de la nueva Librería de Plantillas (STL) exige la asimilación de un nuevo paradigma;  una nueva forma de pensar que, si se tiene experiencia en programación tradicional, exige incluso un &amp;quot;cambio de chip&amp;quot;, ya que estas herramientas conforman un mundo enteramente nuevo y singular.&lt;br /&gt;
&lt;br /&gt;
La STL ofrece un conjunto de recursos flexible, potente y altamente optimizado para resolver una gran variedad de situaciones de programación. Pero esta versatilidad y potencia tributan un precio: su alto grado de parametrización supone algo más que utilizar herramientas aisladas. Es necesario saber ensamblar entre sí los recursos disponibles, que no trabajan aisladamente y que son básicamente de tres tipos: contenedores, iteradores y algoritmos. El resultado es que el proceso de utilizar la STL es algo más complicado que la simple búsqueda de una función que resuelva nuestras necesidades;  que la curva de aprendizaje es ciertamente más ardua que en el caso de la librería clásica, y  que los conceptos involucrados son más abstractos y requieren un conocimiento más extenso de sus fundamentos para utilizarlos. Desde luego, la descripción detallada de todos sus elementos exige un libro completo, y de hecho son muchos los que se han publicado con el objeto exclusivo de describir la STL y/o sus técnicas de uso. En compensación, las contrapartidas obtenidas justifican sin duda el esfuerzo. El programador puede concentrarse más en el problema que en los detalles de su implementación en el fuente, se incremente la productividad y se gana en claridad conceptual.&lt;br /&gt;
== Funciones y macros ==&lt;br /&gt;
Algunas [[Función_(programación)| funciones]] pueden venir implementadas de dos formas: como macro y como función. Por ejemplo, la función isalnum, contenida en &amp;lt;ctype.h&amp;gt;.  Esto significa que además de estar implementada como una función en la correspondiente librería (que se utiliza con los argumentos señalados en el manual), está definida como una macro de preprocesado en &amp;lt;ctype.h&amp;gt;, de forma que salvo indicación contraria al compilador, el preprocesador transforma la llamada del programador en otra serie de sentencias equivalentes que utilizan los mismos argumentos. El resultado es que en el código resultante, que luego pasa al compilador y al enlazador, no existe nada parecido a una llamada a una función isalnum (técnicamente el proceso es una sustitución inline de la función de librería.&lt;br /&gt;
&lt;br /&gt;
Para evitar que esto ocurra y por consiguiente que la llamada a islanum nunca llegue a producirse, basta con indefinir la correspondiente directiva. Esto se hace incluyendo al principio del código, y debajo de la línea #include &amp;lt;ctype.h&amp;gt;, una línea de preprocesado adecuada, en este caso:  #undef isalnum, con lo que el #define del preprocesador quedará sin efecto, con el resultado de que todas las invocaciones a isalnum de nuestro código serán respetadas por el preprocesador. Más tarde el enlazador cargará el código de isalnum (que extrae de la librería) con el resto de nuestro programa, y colocará en cada punto de nuestro código donde aparezca una invocación a isalnum, un salto a la dirección adecuada.&lt;br /&gt;
&lt;br /&gt;
En estos casos, el resultado es el mismo en ambas modalidades: como macro (por defecto) o como función de librería. La elección de una u otra es cuestión de optimización. Para tomar una decisión es necesario comprobar y valorar dos aspectos:&lt;br /&gt;
&lt;br /&gt;
•	El tamaño del ejecutable que resulta en uno y otro caso. Posiblemente mayor si se utiliza la función muchas veces y se adopta la macro.&lt;br /&gt;
&lt;br /&gt;
•	La velocidad de ejecución. Posiblemente mayor si se utiliza la función muchas veces (en bucles muy largos) y se utiliza la macro.&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[Ciencia de la Información]]&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Contenedores C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http://www.zator.com/Cpp/E5.htm  Librería Estándar C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Librería Estándar en C.conclase.net]&lt;br /&gt;
* [https://uvadoc.uva.es/bitstream/10324/17502/1/PID_15_156_Anexo4.pdf  Elementos de la librería estándar C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Librer%C3%ADa_Est%C3%A1ndar_C%2B%2B&amp;diff=3234234</id>
		<title>Librería Estándar C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Librer%C3%ADa_Est%C3%A1ndar_C%2B%2B&amp;diff=3234234"/>
		<updated>2018-11-29T18:26:08Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Librería Estándar C++ |imagen=  |concepto= Una librería es un conjunto de recursos (algoritmos) prefabricados, que pueden ser utilizados por el programador para realizar determinadas operaciones }}''' Librería Estándar C++ '''. [[C++|C++]] no llega al nivel de simplicidad de su antecesor C, pero al igual que aquél, tampoco dispone de utilidades o funciones para entrada o salida implementadas en el propio lenguaje, de modo que estas y otras muchas, como manejo de cadenas de caracteres (strings), manejo de ficheros, funciones matemáticas. son implementadas en forma de librerías externas.&lt;br /&gt;
== Sinopsis ==&lt;br /&gt;
Una librería es un conjunto de recursos (algoritmos) prefabricados, que pueden ser utilizados por el programador para realizar determinadas operaciones. Las declaraciones de las funciones (prototipos) utilizadas en estas librerías, junto con algunas macros y constantes predefinidas que facilitan su utilización, se agrupan en ficheros de nombres conocidos que suelen encontrarse en sitios predefinidos. Por ejemplo, en los sistemas UNIX, en  /usr/include. Estos ficheros se suelen llamar &amp;quot;de cabecera&amp;quot;, porque es tradición utilizar las primeras líneas del programa para poner las directivas #include que los incluirá en el fuente durante la fase de preprocesado.&lt;br /&gt;
== Clases de librerías ==&lt;br /&gt;
Los [[Compilador|compiladores]] [[C++|C++]] incluyen un amplio repertorio de clases, funciones y macros que permiten realizar una amplia variedad de tareas, incluyendo entradas/salidas de bajo y alto nivel; manipulación de cadenas alfanuméricas y ficheros; control de procesos (incluyendo multiproceso); manejo de memoria; cálculos matemáticos y un largo etcétera.&lt;br /&gt;
Este repertorio de recursos es denominado colectivamente como &amp;quot;Rutinas de librería&amp;quot;; &amp;quot;Librerías de ejecución&amp;quot; RTL (&amp;quot;Runtime Librarys&amp;quot;) o simplemente &amp;quot;Librerías&amp;quot;.   Puede decirse que el lenguaje aislado (tal cual) no tiene prácticamente ninguna utilidad sin la concurrencia de estas utilidades. El Estándar C++ las clasifica según su utilidad:&lt;br /&gt;
•	Soporte del lenguaje&lt;br /&gt;
•	Diagnóstico&lt;br /&gt;
•	Utilidades generales&lt;br /&gt;
•	Cadenas alfanuméricas (&amp;quot;Strings&amp;quot;)&lt;br /&gt;
•	Localización&lt;br /&gt;
•	Contenedores&lt;br /&gt;
•	Iteradores&lt;br /&gt;
•	Algoritmos&lt;br /&gt;
•	Cálculo numérico&lt;br /&gt;
•	Entrada/Salida&lt;br /&gt;
=== Librería Estándar C++ ===&lt;br /&gt;
Para poner un poco de orden, el Estándar C++ define la denominada Librería Estándar que debe acompañar a cada implementación del compilador que se adhiera al estándar. Es decir: la norma determina cuales son, como se llaman y como se utiliza este conjunto de algoritmos que deben acompañar (como mínimo) a cada implementación del compilador que quiera llamarse &amp;quot;Estándar&amp;quot;. La última versión, ISO/IEC 14882 del año 1998, especifica que se compone de 32 ficheros de cabecera de nombres fijos y conocidos agrupados según la funcionalidad de los algoritmos. Son los siguientes:&lt;br /&gt;
 &lt;br /&gt;
Ficheros	Funcionalidad/funciones&lt;br /&gt;
&lt;br /&gt;
&amp;lt;algorithm&amp;gt;	Parte de la STL que describe los algoritmos&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bitset&amp;gt;	Parte de la STL relativa a contenedores tipo bitset. Set de valores booleanos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;complex&amp;gt;	Parte de la librería numérica de la STL relativa a los complejos .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;deque&amp;gt;	Parte de la STL relativa a contenedores tipo deque;  un tipo de colas: &amp;quot;Double-ended-queue&amp;quot; .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;exception&amp;gt;	Parte de la librería de diagnóstico relativa al manejo de excepciones&lt;br /&gt;
&lt;br /&gt;
&amp;lt;fstream&amp;gt;	Flujos hacia/desde ficheros.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;functional&amp;gt;	Parte de la STL relativa a Objetos-función&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iomanip&amp;gt;	Manipuladores.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ios&amp;gt;	Supreclases para manejo de flujos de E/S.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iosfwd&amp;gt;	Contiene declaraciones adelantadas de todas las plantillas de flujos y sus typedefs estándar. Por ejemplo ostream.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iostream&amp;gt;	Parte del a STL que contiene los algoritmos estándar de E/S.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;istream&amp;gt;	Algoritmos estándar de flujos de entrada.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iterator&amp;gt;	Parte de la STL relacionada con iteradores, un tipo de puntero que permite utilizar los algoritmos de la Librería con las estructuras de datos representadas por los contenedores.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;limits&amp;gt;	Descripción de propiedades dependientes de la implementación que afectan a los tipos fundamentales.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;list&amp;gt;	Parte de la STL relativa a contenedores tipo list;  listas doblemente enlazadas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;locale&amp;gt;	Parte de la STL relativa a la internacionalización.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;map&amp;gt;	Parte de la STL relativa a contenedores tipo map.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;memory&amp;gt;	Utilidades relativas a la gestión de memoria, incluyendo asignadores  y punteros inteligentes (auto_ptr).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;new&amp;gt;	Manejo de memoria dinámica.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;numeric&amp;gt;	Parte de la librería numérica de la STL relativa a operaciones numéricas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ostream&amp;gt;	Algoritmos estándar para los flujos de salida.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;queue&amp;gt;	Parte de la STL relativa a contenedores tipo queue;  colas de objetos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;set&amp;gt;	Parte de la STL relativa a contenedores tipo set.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sstream&amp;gt;	Flujos hacia/desde cadenas alfanuméricas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;stack&amp;gt;	Parte de la STL relativa a contenedores tipo stack;  pilas de objetos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;stdexcept&amp;gt;	Parte de la STL relativa a las clases de las que derivan los objetos lanzados por las excepciones ocasionadas en los algoritmos de la propia STL y otras expresiones.  Estas clases son utilizadas para reportar errores detectados durante runtime.  Los usuarios también pueden utilizar excepciones para reportar errores en sus propios programas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;streambuf&amp;gt;	Parte de la STL relativa al Almacenamiento de flujos de E/S (&amp;quot;Stream buffers&amp;quot;).  Define los tipos que controlan la capa de transporte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;string&amp;gt;	Parte de la STL relativa a contenedores tipo string;  una generalización de las cadenas alfanuméricas para albergar cadenas de objetos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;typeinfo&amp;gt;	Mecanismo de identificación de tipos en tiempo de ejecución.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;utility&amp;gt;	Parte de la STL que contiene elementos auxiliares como [[Operadores|operadores]] y pares (pairs).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;valarray&amp;gt;	Parte de la librería numérica de la STL relativa a manejo de matrices numéricas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vector&amp;gt;	Parte de la STL relativa a los contenedores tipo vector; una generalización de las matrices unidimensionales C/C++.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Aunque generalmente las librerías no aportan ninguna característica al lenguaje (se supone que son utilidades auxiliares que no forman parte del lenguaje propiamente dicho), una pequeña porción de la Librería Estándar C++ sí aporta características que se consideran pertenecientes a este, de forma que deben estar presentes los ficheros de cabecera correspondientes si se desea usarlas. En concreto se refieren a los siguientes elementos:&lt;br /&gt;
&lt;br /&gt;
•	[[Operadores|operadores]] new, new[], delete y delete[].&lt;br /&gt;
&lt;br /&gt;
•	Clase type_info que corresponde al mecanismo RTTI de identificación de tipos en tiempo de ejecución representado por el operador typeid &lt;br /&gt;
&lt;br /&gt;
•	Rutinas de inicio y terminación.&lt;br /&gt;
&lt;br /&gt;
•	Las excepciones estándar lanzadas por los algoritmos anteriores&lt;br /&gt;
&lt;br /&gt;
=== Librería C ===&lt;br /&gt;
Además de otras nuevas, cuyo diseño e importancia cambian drásticamente la filosofía del lenguaje, C++ incluye prácticamente la totalidad de [[Función_(programación)| funciones]] de la primitiva librería estándar C. A esta librería, mantenida por compatibilidad, la denominamos Librería clásica.&lt;br /&gt;
=== Otras librerías ===&lt;br /&gt;
Además de las que proporciona el estándar y las complementarias que pueda incluir por su cuenta el fabricante del compilador, en los proyectos reales se suelen utilizar infinidad de otras librerías, comerciales o públicas, que facilitan el trabajo en áreas particulares, y en este sentido, recordar que uno de los pecados que el programador novel debe evitar, es la tendencia a querer reinventar constantemente la rueda. De forma que el consejo es utilizar en lo posible librerías que estén probadas y sean fácilmente accesibles. Aunque hay que tener cuidado, porque determinados proyectos exigen que las librerías utilizadas estén perfectamente documentadas y en ciertos casos, que se cuente con los fuentes correspondientes.&lt;br /&gt;
== Componentes ==&lt;br /&gt;
Al referirnos a las librerías C++ utilizamos la terminología siguiente:&lt;br /&gt;
&lt;br /&gt;
•	RTL  Conjunto de librerías que acompañan a un compilador (&amp;quot;Runtime Library&amp;quot;), sean o no estándar.&lt;br /&gt;
&lt;br /&gt;
•	Librería Estándar. Conjunto de librerías cuyo contenido está definido por el Estándar C++ (abreviadamente LE).&lt;br /&gt;
&lt;br /&gt;
•	Libería clásica. Parte de la Librería Estándar correspondiente al C clásico.&lt;br /&gt;
&lt;br /&gt;
•	STL (&amp;quot;Standard Templete Library&amp;quot;). Parte de la LE genuina de C++ (que no es heredada de C) y que responde a la forma &amp;quot;++&amp;quot; de hacer las cosas.&lt;br /&gt;
&lt;br /&gt;
La calidad de un compilador C++ viene determinada en gran medida por la calidad y cantidad de su RTL; por su grado de adherencia al Estándar  y por el grado de soporte que proporciona para la plataforma concreta a que se destina.&lt;br /&gt;
&lt;br /&gt;
En lo que concierne a la programación para MS Windows (las referencias a la plataforma Wintel surgen de forma constante e inevitable), los [[Compilador|compiladores]] Borland C++ y MS Visual C++ son quizás los más conocidos y utilizados.  El primero incluye una completa librería denominada VCL (Visual Component Library. La del segundo es conocida como MFC (Microsoft Foundation Classes).&lt;br /&gt;
&lt;br /&gt;
Linux dispone de su propio compilador: GNU Cpp, que comenzó siendo un compilador C y ha evolucionado a un producto que es en realidad un superconjunto de compiladores. No solo puede compilar código C y C++;  también otros lenguajes como Ada o Fortran;  de forma que es común referirse a ellos como GCC (&amp;quot;GNU Compiler Collection&amp;quot;).  La buena noticia es que existen versiones de este compilador para plataformas Windows, de forma que incluso en este ambiente &amp;quot;Propietario&amp;quot; pueden realizarse desarrollos utilizando herramientas &amp;quot;Open source&amp;quot; &lt;br /&gt;
A grandes rasgos la librería Estándar C++ comprende los siguientes módulos:&lt;br /&gt;
&lt;br /&gt;
•	La denominada Librería Estándar de Plantillas, abreviadamente STL (&amp;quot;Standard Templete Library&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
•	Librería numérica. Parte de la STL que contiene algoritmos especialmente concebidos para computación numérica. Por ejemplo, una clase valarray optimizada para matrices numéricas y una clase complex para manejo y representación estandarizada de números complejos (en realidad una plantilla con especializaciones para los tipos float, double y long double.&lt;br /&gt;
&lt;br /&gt;
•	Utilidades. Parte de la STL dedicada a elementos auxiliares tales como adaptadores y la clase auto_ptr.&lt;br /&gt;
&lt;br /&gt;
•	Unas utilidades de entrada/salida de flujos, denominadas genéricamente iostreams.&lt;br /&gt;
&lt;br /&gt;
•	Una utilidad locale para manejo de localismos.&lt;br /&gt;
&lt;br /&gt;
•	Una clase string para manejo estandarizado de cadenas de caracteres.  En realidad es una instanciación (especialización) de la plantilla basic_string para cadenas de caracteres.&lt;br /&gt;
 &lt;br /&gt;
•	Un esquema para describir de modo uniforme el entorno de ejecución mediante la utilización de una clase estándar denominada numeric_limits y especialización para cada uno de los tipos de datos fundamentales.&lt;br /&gt;
&lt;br /&gt;
•	Utilidades para manejo de memoria.&lt;br /&gt;
&lt;br /&gt;
•	Soporte para utilización de juegos de caracteres y signos de diversos idiomas.&lt;br /&gt;
&lt;br /&gt;
•	Utilidades de diagnóstico y manejo de errores. Incluyen manejo de excepciones y la macro assert.&lt;br /&gt;
&lt;br /&gt;
== Funcionalidad ==&lt;br /&gt;
Si atendemos a su funcionalidad,  las utilidades ofrecidas por la Librería Estándar pueden agruparse en:&lt;br /&gt;
&lt;br /&gt;
•	Clasificación: Clasifican caracteres ASCII, como letras, caracteres de control (no imprimibles), Mayúsculas/minúsculas etc. Se definen en la cabecera &amp;lt;ctype.h&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
•	Entradas/Salidas de Consola: Estas son las denominadas entrada/salida estándar. Por defecto se refieren al teclado y a la pantalla (no pueden utilizarse directamente en aplicaciones de interfaz gráfica).&lt;br /&gt;
&lt;br /&gt;
•	Conversión: Convierten caracteres y cadenas de caracteres desde formato alfabético a numérico de diversos tipos (float, int, long).  También realizan la conversión inversa: de formatos numéricos a representaciones alfabéticas y de mayúsculas a minúsculas y viceversa.&lt;br /&gt;
&lt;br /&gt;
•	Diagnóstico: Son rutinas destinadas a comprobaciones; a descubrir y corregir posibles errores.&lt;br /&gt;
&lt;br /&gt;
•	Directorio: Rutinas para manejo de directorios y sus direcciones (path names).&lt;br /&gt;
&lt;br /&gt;
•	En linea (Inline): Rutinas para versiones inline de funciones. El compilador genera el código correspondiente para las versiones inline cuando se utiliza #pragma intrinsic o si se solicita optimización al compilador (optimización de tiempo de ejecución).&lt;br /&gt;
&lt;br /&gt;
•	Entrada/Salida. Son rutinas que proporcionan manejo de flujos y operaciones de Entrada/Salida a bajo nivel (de Sistema Operativo).&lt;br /&gt;
&lt;br /&gt;
•	Manipulación. Manejo de cadenas y bloques de memoria: copiar, comparar, convertir y buscar.&lt;br /&gt;
&lt;br /&gt;
•	Matemáticas: Para realizar cálculos matemáticos.&lt;br /&gt;
&lt;br /&gt;
•	De Memoria: Proporcionan asignación de memoria dinámica.&lt;br /&gt;
&lt;br /&gt;
•	Miscelánea. Se agrupan aquí rutinas varias, como las que posibilitan saltos (goto) no locales y las que manejan diferencias de tipo cultural o de lenguaje. Por ejemplo representación de números, de moneda, formatos de fecha y hora, clasificación de tipo alfabético.&lt;br /&gt;
&lt;br /&gt;
•	Control de proceso. Rutinas que permiten invocar y terminar nuevos procesos desde otra rutina.&lt;br /&gt;
&lt;br /&gt;
•	Fecha y hora. Incluyen rutinas para conversión y manipulación de variables de medida del tiempo (fecha y hora).&lt;br /&gt;
&lt;br /&gt;
•	Argumentos variables. Rutinas utilizadas cuando se usan listas variables de argumentos, como en los casos de printf(), vscanf().&lt;br /&gt;
== Utilización ==&lt;br /&gt;
La utilización de la Librería Estándar C++ requiere de dos tipos de condiciones que podríamos describir como formales y conceptuales.&lt;br /&gt;
&lt;br /&gt;
1. En cuanto a las primeras (condiciones formales) y habida cuenta que las utilidades aparecen en forma de funciones, resulta evidente que su utilización exige incluirlas en nuestro programa. Para ello se necesitan tres pasos (en realidad las exigencias son las mismas que con cualquier otra función, la diferencia estriba en la forma en que se realizan los pasos b y c):&lt;br /&gt;
&lt;br /&gt;
a:  Incluir en el código fuente las invocaciones a las [[Función_(programación)| funciones]] que estamos utilizando. Ejemplo:&lt;br /&gt;
printf(&amp;quot;Esto es una llamada a la función \&amp;quot;printf\&amp;quot; de librería\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
 b:  Incluir en el código fuente los prototipos de dichas funciones.&lt;br /&gt;
&lt;br /&gt;
Puesto que los prototipos ya están incluidos en los ficheros estándar de cabecera, hay que indicar al compilador que los incluya. Esto se realiza poniendo en nuestro fuente (normalmente al principio) una directiva de preprocesado #include que señala el fichero de cabecera que se debe añadir. Por ejemplo, si el manual indica que la función printf está definida en el fichero de cabecera stdio.h ponemos en nuestro código:&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  c:  Incluir en el fuente las definiciones de las funciones utilizadas. Como alternativa se puede indicar al compilador que tales definiciones están en ficheros compilados previamente.&lt;br /&gt;
&lt;br /&gt;
En este último caso se dice que las definiciones de las funciones están en librerías de las que existen dos tipos: estáticas (.LIB, .OBJ y .BPI) y dinámicas (.DLL). Toda la información que necesita el compilador está contenida en los ficheros de cabecera, por lo que las operaciones correspondientes son realizadas de forma automática; con la sola condición de que los ficheros y librerías correspondientes sean accesibles al enlazador.&lt;br /&gt;
&lt;br /&gt;
Las entidades de la Librería Estándar C++ (que no están en ficheros de cabecera .h), se han definido en un espacio de nombres denominado std, por lo que es preciso referirse a él específicamente cuando se quieran utilizar estos recursos.&lt;br /&gt;
&lt;br /&gt;
2. Respecto a las que hemos denominado &amp;quot;condiciones conceptuales&amp;quot;, damos por sentado que la utilización de algoritmos de la Librería exige conocerlos. Pero debemos advertir que existe una gran diferencia entre las rutinas de la que hemos denominado librería clásica y los recursos de la nueva Librería Estándar de Plantillas STL.&lt;br /&gt;
&lt;br /&gt;
En general los algoritmos contenidos en la librería clásica realizan tareas muy sencillas bajo la forma de funciones que, con un cierto número de argumentos, realizan la tarea encomendada. A veces devolviendo un objeto (que puede ser una estructura). Su utilización exige poco más que repasar esta colección de funciones (209 en la última versión del Estándar) hasta encontrar la que mejor se ajusta a nuestras necesidades. Para esto lo mejor es recurrir a la clasificación temática ofrecida en la documentación que acompaña a los compiladores antes que a la lista alfabética de las mismas. A continuación estudiamos atentamente su prototipo y la explicación de funcionamiento que acompaña el manual (eventualmente incluso con un ejemplo) y ya estamos listos para utilizarla. En el peor de los casos suelen bastar un par de pruebas hasta que conseguimos ajustar los argumentos de forma que se consiga el resultado esperado.&lt;br /&gt;
&lt;br /&gt;
Como última recomendación al respecto, sobre todo si pensamos que nuestro programa tendrá una larga vida y/o pensamos portarlo a otras plataformas, aconsejaría echar un vistazo a la sección de &amp;quot;compatibilidad&amp;quot; que acompaña a la descripción de cada función en la documentación de la mayoría de compiladores. Suele ocurrir que el compilador ofrezca muchas más funciones que las estrictamente Estándar C++, y que estas no estén claramente separadas del resto, de forma que es posible que elijamos una función que resuelve nuestro problema pero no es portable, en cuyo caso aconsejaría evitarlas dentro de lo posible.&lt;br /&gt;
&lt;br /&gt;
La utilización de la nueva Librería de Plantillas (STL) exige la asimilación de un nuevo paradigma;  una nueva forma de pensar que, si se tiene experiencia en programación tradicional, exige incluso un &amp;quot;cambio de chip&amp;quot;, ya que estas herramientas conforman un mundo enteramente nuevo y singular.&lt;br /&gt;
&lt;br /&gt;
La STL ofrece un conjunto de recursos flexible, potente y altamente optimizado para resolver una gran variedad de situaciones de programación. Pero esta versatilidad y potencia tributan un precio: su alto grado de parametrización supone algo más que utilizar herramientas aisladas. Es necesario saber ensamblar entre sí los recursos disponibles, que no trabajan aisladamente y que son básicamente de tres tipos: contenedores, iteradores y algoritmos. El resultado es que el proceso de utilizar la STL es algo más complicado que la simple búsqueda de una función que resuelva nuestras necesidades;  que la curva de aprendizaje es ciertamente más ardua que en el caso de la librería clásica, y  que los conceptos involucrados son más abstractos y requieren un conocimiento más extenso de sus fundamentos para utilizarlos. Desde luego, la descripción detallada de todos sus elementos exige un libro completo, y de hecho son muchos los que se han publicado con el objeto exclusivo de describir la STL y/o sus técnicas de uso. En compensación, las contrapartidas obtenidas justifican sin duda el esfuerzo. El programador puede concentrarse más en el problema que en los detalles de su implementación en el fuente, se incremente la productividad y se gana en claridad conceptual.&lt;br /&gt;
== Funciones y macros ==&lt;br /&gt;
Algunas [[Función_(programación)| funciones]] pueden venir implementadas de dos formas: como macro y como función. Por ejemplo, la función isalnum, contenida en &amp;lt;ctype.h&amp;gt;.  Esto significa que además de estar implementada como una función en la correspondiente librería (que se utiliza con los argumentos señalados en el manual), está definida como una macro de preprocesado en &amp;lt;ctype.h&amp;gt;, de forma que salvo indicación contraria al compilador, el preprocesador transforma la llamada del programador en otra serie de sentencias equivalentes que utilizan los mismos argumentos. El resultado es que en el código resultante, que luego pasa al compilador y al enlazador, no existe nada parecido a una llamada a una función isalnum (técnicamente el proceso es una sustitución inline de la función de librería.&lt;br /&gt;
&lt;br /&gt;
Para evitar que esto ocurra y por consiguiente que la llamada a islanum nunca llegue a producirse, basta con indefinir la correspondiente directiva. Esto se hace incluyendo al principio del código, y debajo de la línea #include &amp;lt;ctype.h&amp;gt;, una línea de preprocesado adecuada, en este caso:  #undef isalnum, con lo que el #define del preprocesador quedará sin efecto, con el resultado de que todas las invocaciones a isalnum de nuestro código serán respetadas por el preprocesador. Más tarde el enlazador cargará el código de isalnum (que extrae de la librería) con el resto de nuestro programa, y colocará en cada punto de nuestro código donde aparezca una invocación a isalnum, un salto a la dirección adecuada.&lt;br /&gt;
&lt;br /&gt;
En estos casos, el resultado es el mismo en ambas modalidades: como macro (por defecto) o como función de librería. La elección de una u otra es cuestión de optimización. Para tomar una decisión es necesario comprobar y valorar dos aspectos:&lt;br /&gt;
&lt;br /&gt;
•	El tamaño del ejecutable que resulta en uno y otro caso. Posiblemente mayor si se utiliza la función muchas veces y se adopta la macro.&lt;br /&gt;
&lt;br /&gt;
•	La velocidad de ejecución. Posiblemente mayor si se utiliza la función muchas veces (en bucles muy largos) y se utiliza la macro.&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[Ciencia de la Información]]&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Contenedor C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http://www.zator.com/Cpp/E5.htm  Librería Estándar C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Librería Estándar en C.conclase.net]&lt;br /&gt;
* [https://uvadoc.uva.es/bitstream/10324/17502/1/PID_15_156_Anexo4.pdf  Elementos de la librería estándar C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234232</id>
		<title>Contenedores C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234232"/>
		<updated>2018-11-29T18:25:05Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Contenedores C++ |imagen=  |concepto= En sentido C++ estricto, un contenedor de la STL es una clase genérica que puede instanciarse para representar diversos tipos de objetos. Esta clase incluye ciertas operaciones  sobre los objetos de su tipo; estas operaciones están representadas por funciones-miembro, incluyendo constructores y funciones-operador, que son a su vez funciones genéricas}}''' Contenedores C++ '''. Al mismo tiempo, desde el punto de vista de las teorías de la información, podemos considerarlos estructuras de datos más o menos adecuadas (según el caso) para aplicarles ciertos algoritmos.&lt;br /&gt;
De su propio nombre (&amp;quot;Containers&amp;quot;) podemos deducir que su misión principal, y razón de su existencia, es su función como estructuras de datos, y en este sentido podemos adelantar que entre sus funcionalidades más destacadas se encuentran la gestión del espacio de almacenamiento necesario.&lt;br /&gt;
Una de las primerísimas ventajas de la utilización de contenedores es que el programador no tiene que enredarse con las cuestiones siempre espinosas de asignar o liberar memoria para los objetos creados, de forma que queda liberado de los [[Operadores|operadores]] [[Operador new|new]] y [[Operador delete|delete]].&lt;br /&gt;
== Filosofía de uso ==&lt;br /&gt;
Una primera pincelada sobre la filosofía de uso de los contenedores mediante un sencillo ejemplo: si tenemos que manejar un conjunto de enteros, puede utilizarse una matriz de enteros, pero ya hemos señalado  que esta estructura nos obliga a conocer de antemano la cantidad de datos a almacenar (el tamaño de la matriz). En consecuencia, si el número de datos puede variar, esta opción no es muy adecuada. Además, si es importante mantener los datos ordenados, la utilización de una matriz nos obligaría a ingeniar por nuestra cuenta la forma de hacerlo; seguramente mediante complicadas rutinas de &amp;quot;sort&amp;quot; hechas manualmente.&lt;br /&gt;
&lt;br /&gt;
Una alternativa es utilizar como &amp;quot;contenedor&amp;quot; para nuestros enteros una clase genérica de la STL denominada vector. En este caso, serían posibles expresiones como las siguientes:&lt;br /&gt;
&lt;br /&gt;
  vector&amp;lt;int&amp;gt; v(3);         // L1:&lt;br /&gt;
  v[0] = 7;                 // L2:&lt;br /&gt;
  v[1] = v[0] + 1;          // L3:&lt;br /&gt;
  v[2] = v[0] + v[1];       // L4:&lt;br /&gt;
&lt;br /&gt;
Al encontrar la primera sentencia, el compilador crea una instancia (especialidad) anónima de la plantilla vector para alojar enteros; a continuación una instancia de ella para alojar tres enteros, a la que denominamos v.&lt;br /&gt;
&lt;br /&gt;
Una primera inspección de las sentencias L2 a L3, nos muestra que la clase ofrece la posibilidad de utilizar con sus miembros el operador subíndice de matriz [ ]. Deducimos por tanto, que dispone de una versión sobrecargada de este operador para los miembros de la clase, lo que nos permite utilizar el objeto v como una matriz, aunque con algunas funcionalidades no incluidas en aquellas.&lt;br /&gt;
&lt;br /&gt;
Después de L4 los valores finales para los miembros de nuestra &amp;quot;matriz&amp;quot; serian:&lt;br /&gt;
 v[0] == 7, v[1] == 8, v[2] == 15&lt;br /&gt;
&lt;br /&gt;
Si deseamos invertir el orden de los elementos de nuestra matriz. Para ello utilizamos una [[Función (programación)|función]] especial:&lt;br /&gt;
&lt;br /&gt;
 reverse(v.begin(), v.end());&lt;br /&gt;
&lt;br /&gt;
después de lo cual, el orden de miembros sería:&lt;br /&gt;
&lt;br /&gt;
 v[0] == 15, v[1] == 8, v[2] == 7&lt;br /&gt;
&lt;br /&gt;
La primera observación es que la función reverse utiliza dos argumentos, que son a su vez el valor devuelto por sendos métodos de clase (los aplicamos sobre nuestro objeto v).  El valor devuelto por estos métodos es lo que se conoce como un [[Iteradores (Programación)|iterador]]; una especie de puntero que señalan al interior de la estructura de datos representada por el contenedor v. En este caso, el primer iterador señala al primer miembro y el segundo a una posición después del último; de esta forma se indican los miembros inicial y final entre los que se realizará la operación de inversión efectuada por reverse.&lt;br /&gt;
&lt;br /&gt;
La segunda observación es que la función reverse no es un método de clase, sino una función global; es lo que denominamos un [[Algoritmo|algoritmo]]. Esta función tiene la peculiaridad de que puede ser aplicado sobre el contenedor vector (y algún otro); que opera sobre un rango de los elementos del contenedor, en nuestro caso sobre la totalidad (esta capacidad de operar sobre una parte de un contenedor es característica de los algoritmos). También que pueden operar sobre otros contenedores produciendo un efecto similar. Por ejemplo, el algoritmo reverse puede operar incluso sobre una simple matriz:&lt;br /&gt;
 char Ch[5] = { 'A', 'E', 'I', 'O', 'U' };&lt;br /&gt;
 reverse(Ch, Ch + 5);&lt;br /&gt;
 for (int i = 0; i &amp;lt; 5; ++i) cout &amp;lt;&amp;lt; &amp;quot;Ch[&amp;quot; &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &amp;quot;] = &amp;quot; &amp;lt;&amp;lt; Ch[i];&lt;br /&gt;
 Salida:&lt;br /&gt;
 Ch[0] = U Ch[1] = O Ch[2] = I Ch[3] = E Ch[4] = A&lt;br /&gt;
&lt;br /&gt;
Es significativo que el objeto v es una estructura de datos que permite acceder individualmente a sus miembros &amp;quot;como si&amp;quot; fuesen elementos de una matriz. También que se pueden aplicar ciertas operaciones sobre la totalidad, o parte, de esta estructura considerada como una unidad.&lt;br /&gt;
== Clasificación ==&lt;br /&gt;
Existen dos tipos de contenedores: secuencias y asociativos; a su vez se subdividen según el tipo de [[Iteradores (Programación)|iterador]] que soportan.&lt;br /&gt;
&lt;br /&gt;
Las secuencias almacenan los elementos en orden secuencial (de ahí su nombre). El contenedor agrupa a todos sus miembros como una sucesión lineal, y en consecuencia son adecuadas para accesos directos y secuenciales. Un ejemplo de secuencia es una matriz. De hecho, los algoritmos que pueden aplicarse a las secuencias pueden aplicarse también a las matrices.&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, por lo que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.  La STL proporciona cinco tipos distintos.&lt;br /&gt;
&lt;br /&gt;
La existencia de índices supone una ordenación según los valores de un conjunto de elementos (denominado &amp;quot;de claves&amp;quot;) para el que debe existir un criterio de ordenación. Dicho en otras palabras, los objetos &amp;quot;de clave&amp;quot; deben ser de un tipo para el que estén definidos los operadores relacionales. El árbol es mantenido ordenado de forma automática por los algoritmos de inserción y borrado del contenedor.&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave y para recorrer el conjunto (ordenado) de los elementos.&lt;br /&gt;
&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] contiene diez formas de contenedores y tres adaptadores de contenedor (denominados simplemente [[Adapter|adaptadores]]). En esta sección se expondrán brevemente cuales son estas formas; sus características, y cuál es la más adecuada para cada tipo de problema específico. En secciones sucesivas se comentarán individualmente con mayor detalle.&lt;br /&gt;
Relación siguiendo la clasificación utilizada en el Estándar:&lt;br /&gt;
  • Secuencias&lt;br /&gt;
      o	deque&lt;br /&gt;
      o	list&lt;br /&gt;
      o	stack&lt;br /&gt;
      o	vector&lt;br /&gt;
      o	vector &amp;lt;bool&amp;gt;&lt;br /&gt;
  • adaptadores&lt;br /&gt;
      o	queue&lt;br /&gt;
      o	priority_queue&lt;br /&gt;
  • Contenedores asociativos&lt;br /&gt;
      o	map&lt;br /&gt;
      o	multimap&lt;br /&gt;
      o	set&lt;br /&gt;
      o	multiset&lt;br /&gt;
      o	bitset&lt;br /&gt;
== Características ==&lt;br /&gt;
Las características más significativas de las diversas formas de contenedor son:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Contenedor&lt;br /&gt;
! Características&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;big&amp;gt;Secuencias&amp;lt;/big&amp;gt;&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| vector&lt;br /&gt;
| Este contenedor es una estructura de datos de tamaño fijo preferentemente. Aunque la STL proporciona herramientas para cambiar el tamaño de un vector de forma dinámica, esta operación es costosa y debe ser evitada dentro de lo posible (en este sentido el vector se comporta como una matriz ordinaria).&lt;br /&gt;
&lt;br /&gt;
Disponen de un buén mecanismo de acceso aleatorio a elementos y de un mecanismo de inserción al final muy eficiente.&lt;br /&gt;
&lt;br /&gt;
Generalmente es preferible utilizar un vector que un deque o un list, a menos que sea frecuentemente necesario insertar datos al comienzo o al final, en cuyo caso es mejor utilizar un deque.  Si por el contrario es frecuente la inserción de elementos en el centro, entonces es preferible un list.&lt;br /&gt;
|-&lt;br /&gt;
| vector&amp;lt;bool&amp;gt;&lt;br /&gt;
| Es una versión de la anterior especial para valores binarios (bits).&lt;br /&gt;
|-&lt;br /&gt;
| list&lt;br /&gt;
| Este contenedor responde a la idéa intuitiva de &amp;quot;lista&amp;quot;, el almacenamiento de objetos en una secuencia lineal que no está necesariamente ordenada (aunque sus miembros pueden ser ordenados fácilmente mediante la función-miembro sort() ). Estos contenedores suelen ser implementados como listas doblemente enlazadas. &lt;br /&gt;
&lt;br /&gt;
Dispone de mecanismos eficientes para insertar elementos al principio, al final o en cualquier posición (utilizando iteradores que denoten posición). Estas operaciones consumen un tiempo constante con independencia del número de elmentos albergados en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Dado que son estructuras lineales, en general los elementos no pueden ser accedidos por subíndices como en un vector.  Es necesario realizar un recorrido lineal por todos los valores, por lo que en las operaciones de acceso se utilizan tiempos proporcionales al número de elementos.&lt;br /&gt;
|-&lt;br /&gt;
| stack&lt;br /&gt;
| Contenedor de elementos tipo pila LIFO que permite inserciones y eliminaciones solo en la parte superior.&lt;br /&gt;
|-&lt;br /&gt;
| deque&lt;br /&gt;
| Los deques o colas de doble terminación (&amp;quot;Double-ended queue&amp;quot;) son un tipo de estructura de datos que comparte las características de las colas (&amp;quot;Queues&amp;quot;) y las pilas (&amp;quot;Stacks&amp;quot;). Como en las colas , los elementos pueden ser empujados por un extremo al interior del contenedor, y el primer elemento introducido puede ser extraído por el extremo opuesto. Al mismo tiempo, el último elemento introducido por el principio puede ser extraído en ese mismo extremo como si fuese una pila.&lt;br /&gt;
 &lt;br /&gt;
Estos contenedores suelen ser implementados bajo la forma de matrices bidimensionales.&lt;br /&gt;
&lt;br /&gt;
Las características de los deques implementados en la STL pueden resumirse en: Acceso aleatorio; mecanismo eficiente de inserción al principio o al final.&lt;br /&gt;
|-&lt;br /&gt;
| string&lt;br /&gt;
| Contenedor de caracteres adaptado a operaciones con cadenas de caracteres.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;big&amp;gt;Asociaciones&amp;lt;/big&amp;gt;&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| set&lt;br /&gt;
| Como el resto de contenedores asociativos, esta forma de contenedor mantiene los elementos en orden. Dispone de mecanismos eficientes para inclusión, inserción y eliminación de elementos, y soporta claves únicas (solo puede existir un miembro con una clave determinada).&lt;br /&gt;
|-&lt;br /&gt;
| multiset&lt;br /&gt;
| Versión del anterior que permite la existencia de claves duplicadas. Es decir, distintos elementos dentro del conjunto pueden responder a la misma clave.&lt;br /&gt;
|-&lt;br /&gt;
| bitset&lt;br /&gt;
| Contenedor de bit más orientado al tamaño que hacia el tipo de contenido. Permite almacenar secuencias de bits de tamaño fijo. No existen iteradores para reccorrerlas, y sus elementos se acceden utilizando el operador subíndice.&lt;br /&gt;
 &lt;br /&gt;
Se dispone de varias funciones para realizar con ellos operaciones de bits &lt;br /&gt;
|-&lt;br /&gt;
| map&lt;br /&gt;
| Como el resto de estructuras asociativas, el map mantiene sus elementos ordenados. Se caracteriza porque sus miembros son pares de valores que pueden ser de tipos distintos. Uno de ellos, el que actúa como clave para el índice (&amp;quot;Key-value&amp;quot;), puede ser de cualquier tipo, a condición de que sus elementos puedan ser ordenados según un criterio (por defecto se utiliza el operador &amp;lt;).&lt;br /&gt;
 &lt;br /&gt;
Permite claves únicas. Es decir, que solo puede existir un miembro para cada clave. Dispone de mecanismos de inserción y borrado muy eficientes y no existe límite de tamaño. La estructura se encarga de crecer y disminuir en concordancia con las necesidades de sus miembros. Permite el operador [ ] subíndice para los elementos de la clave así como otras técnicas de acceso.&lt;br /&gt;
&lt;br /&gt;
Estas estructuras de datos recibe también los nombres de diccionarios, tablas y matrices asociativas, en referencia a que pueden considerarse como dos matrices del mismo número de elementos, en las que existe una relación entre cada miembro de una con otro miembro de la otra.  Una de las matrices (que actúa de índice) estaría ordenada según su contenido&lt;br /&gt;
|-&lt;br /&gt;
| multimap&lt;br /&gt;
| En todo igual que el anterior pero permitiendo además claves duplicadas. Es decir, que una misma clave pueda estar asociada a dos &amp;quot;valores&amp;quot; distintos.&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Adaptador&lt;br /&gt;
! Características&lt;br /&gt;
|-&lt;br /&gt;
| queue&lt;br /&gt;
| Contenedor tipo cola FIFO que permite inserciones al final y eliminaciones al principio.&lt;br /&gt;
|-&lt;br /&gt;
| priority queue&lt;br /&gt;
| Este contenedor dispone de mecanismos eficientes para acceso y eliminación de grandes valores.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Seleccionar un contenedor ==&lt;br /&gt;
El binomio contendor-iterador conforma una herramienta que se adapta a circunstancias muy variadas. Es posible que un determinado problema pueda ser abordado de varias formas, en estos casos la selección de la forma de contenedor más adecuado depende de las circunstancias. En ciertas ocasiones puede resultar bastante obvia; en otras puede no estar tan claro cuál es la mejor opción, pues &amp;quot;a priori&amp;quot;, pueden adaptarse varias formas al caso concreto. Puede utilizarse el sistema de prueba y comparación. Por ejemplo, cronometrando los resultados obtenidos en un modo u otro. También será de gran ayuda la experiencia, pero como una guía o criterio general puede utilizarse el principio de selección que se indica a continuación.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Como se accederá a los datos?.&lt;br /&gt;
| Si es importante un acceso aleatorio, pueden utilizarse un vector o un deque. Si basta con un acceso secuencial cualquiera de los dos puede ser el elegido.&lt;br /&gt;
|-&lt;br /&gt;
| Es importante el orden en que serán mantenidos los valores dentro de la colección de datos?&lt;br /&gt;
| Existen muchas formas de secuenciar los valores. Si es importante un orden estricto a lo largo de toda la vida del contenedor, la elección obvia es un set, dado que las inserciones en una de estas estructuras se realizan automáticamente en orden.&lt;br /&gt;
 &lt;br /&gt;
Si este orden es importante solo en algún momento, por ejemplo al final de una serie de inserciones, puede ser más sencillo colocar los valores en un list o vector para ordenar más tarde el resultado en el momento necesario.&lt;br /&gt;
&lt;br /&gt;
Si el orden en que se almacenan los valores en la estructura está relacionado con el orden de su inserción, entonces un stack, un queue o un list pueden ser la mejor elección.&lt;br /&gt;
|-&lt;br /&gt;
| Puede variar mucho el tamaño de la estructura de datos durante el curso de la ejecución del programa?&lt;br /&gt;
| Si es así, entonces puede ser que la mejor opción sean un list o un set. Un vector o un deque pueden conducir a mantener un gran almacenamiento intermedio (buffer); incluso después que los elementos hayan sido eliminados de la colección de datos. Estos dos contenedores no son adecuados para cambios de tamaño, aunque vector dispone de un mecanismo de inserción al final eficiente.&lt;br /&gt;
 &lt;br /&gt;
Recíprocamente: si el tamaño de la colección se mantiene relativamente estable, entonces un vector o un deque pueden utilizar menos memoria que un list o un set que almacenen el mismo número de elementos.&lt;br /&gt;
|-&lt;br /&gt;
| Es posible determinar el tamaño de la colección?&lt;br /&gt;
| La estructura de datos vector proporciona un medio para pre-seleccionar un bloque de memoria de un tamaño específico con la función miembro reserve, posibilidad que no existe en otros contenedores.&lt;br /&gt;
|-&lt;br /&gt;
| Es frecuente tener que comprobar si un valor cualquiera está incluido en la colección?&lt;br /&gt;
| En este caso, un contenedor set o map pueden ser buena elección. En estos casos comprobar si un determinado valor está incluido puede ser realizado con un pequeño número de pasos (logarítmicos con el tamaño del contenedor). Mientras que la misma verificación en cualquiera de los otros tipos puede requerir comparar el valor con cada elemento almacenado en el contenedor.&lt;br /&gt;
|-&lt;br /&gt;
| Está indexada la colección de datos? &lt;br /&gt;
| Si las claves son enteros entre 0 y un límite superior, pueden utilizarse un vector o un deque. &lt;br /&gt;
|-&lt;br /&gt;
| Si es así, puede ser vista la colección como una serie de pares clave/valor?&lt;br /&gt;
| Si la clave es algún otro valor, como cadenas de caracteres o tipos definidos por el usuario, puede utilizarse un contenedor map.&lt;br /&gt;
|-&lt;br /&gt;
| Pueden los valores estar relacionados unos con otros?&lt;br /&gt;
| Todos los valores almacenados en cualquier contenedor de la STL debe ser capaz de comprobar la igualdad con cualquier otro valor similar, pero recuerde que no todos son capaces de reconocer el operador de relación menor-que; sin embargo, si los valores no pueden ser ordenados utilizando el operador menor-que, no pueden ser almacenados en un set o en un map.&lt;br /&gt;
|-&lt;br /&gt;
| Es una operación frecuente tener que encontrar y eliminar el valor mayor de la colección?&lt;br /&gt;
| En caso afirmativo, la estructura de datos más idónea es el priority queue.&lt;br /&gt;
|-&lt;br /&gt;
| En que posiciones son insertados o eliminados los elementos de la estructura?&lt;br /&gt;
| Si los valores son añadidos o eliminados en la zona interior, entonces la mejor opción es un list.&lt;br /&gt;
 &lt;br /&gt;
Si los valores son insertados solo al comienzo, un deque o un list pueden ser lo más adecuado.&lt;br /&gt;
&lt;br /&gt;
Si los valores son insertados y eliminados solo al final, un stack o un queue pueden ser elecciones lógicas.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| Es frecuente tener que refundir dos o más secuencias en una sola?&lt;br /&gt;
| En caso afirmativo, puede considerarse que las mejores opciones son un set o un list, dependiendo que la colección deba o no ser mantenida en orden.&lt;br /&gt;
 &lt;br /&gt;
Refundir dos set es una operación muy eficiente.  Si la colección de datos no está ordenada, pero puede utilizarse la función miembro splice() de las list (que es muy eficiente), entonces es preferible este último tipo de contenedor, dado que esta operación no está contemplada en las demás formas.&lt;br /&gt;
|}&lt;br /&gt;
=== Tipos no incluidos ===&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] incluye contenedores adecuados para la mayoría de los casos prácticos, aunque quizás existen una serie de estructuras de datos clásicas que no han sido incluidas. En la mayoría de los casos, la causa es que los contenedores proporcionados pueden ser fácilmente adaptados para suplir los usos facilitados por los tipos omitidos.&lt;br /&gt;
&lt;br /&gt;
Tipos clásicos no incluidos y la sustitución más fácil.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Contenedor omitido&lt;br /&gt;
! Sustitución utilizando elementos de STL&lt;br /&gt;
|-&lt;br /&gt;
| tree&lt;br /&gt;
| El modo set está implementado internamente como un árbol de búsqueda binaria. &lt;br /&gt;
&lt;br /&gt;
Para la mayoría de los casos prácticos que pueden ser resueltos utilizando árboles este modo es un sustituto adecuado.&lt;br /&gt;
|-&lt;br /&gt;
| matrices multidimensionales&lt;br /&gt;
| Puesto que los vectores pueden almacenar elementos que sean otros vectores, estas estructuras pueden ser construidas fácilmente.&lt;br /&gt;
|-&lt;br /&gt;
| graph&lt;br /&gt;
| La representación de un gráfico puede ser fácilmente construida como un map que contiene otros map. Un map cuyos elementos son a su vez maps, es la representación natural de un gráfico directo. &lt;br /&gt;
|-&lt;br /&gt;
| sparse array&lt;br /&gt;
| Una novedosa sustitución es la representación de un gráfico&lt;br /&gt;
|-&lt;br /&gt;
| hash table&lt;br /&gt;
| Las tablas hash proporcionan un tiempo de acceso constante, así como inserción y borrado de elementos, convirtiendo estas operaciones en operaciones de índice.&lt;br /&gt;
 &lt;br /&gt;
Una tabla hash puede ser construida fácilmente como un vector (o deque) cuyos elementos son lists (o incluso sets).  En el ejemplo de la ordenación raíz (  xxx) se describe una de estas estructuras (un vector de deques), aunque en este ejemplo no incluye invocación la función hash para convertir un valor en un índice.&lt;br /&gt;
|-&lt;br /&gt;
| Funcionalidad set&lt;br /&gt;
| En la STL, los tipos set están específicamente ordenados, y sus operaciones (como la unión intersección, etc.) no pueden ser realizadas sobre colecciones de valores no ordenados (por ejemplo un conjunto de números complejos).&lt;br /&gt;
 &lt;br /&gt;
Una list puede ser utilizada como sustituto, aunque es necesario escribir funciones de operación especiales, dado que los algoritmos genéricos no pueden ser utilizados con listas.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Gestión de memoria ==&lt;br /&gt;
La gestión de memoria realizada por los contenedores comprende tanto la asignación y liberación de espacio para sus miembros, como para las claves que constituyen el sistema de índice de algunos tipos de contenedor. En general los algoritmos de la STL están muy optimizados y el sistema de asignación de memoria intenta compaginar rapidez y eficacia. La primera exige asignar y desasignar espacio cada vez que se introduce o elimina un miembro del contenedor. La eficacia, e incluso la disminución de la fragmentación inherentes al manejo del montón, exige asignar y rehusar trozos de memoria lo más grandes posible cada vez. El abordaje a este problema se ha realizado de dos formas básicas: (a) Contenedores que no pueden alterar su tamaño, de forma que la asignación de espacio para sus elementos debe realizarse en el momento de su declaración. (b) Contenedores que pueden crecer y/o disminuir en consonancia con los elementos a albergar.&lt;br /&gt;
&lt;br /&gt;
Refiriéndonos al caso (b), para balancear estas exigencias contrapuestas, algunas implementaciones utilizan el siguiente esquema de trabajo: inicialmente el sistema asigna al contenedor un trozo de memoria de tamaño adecuado para contener cierto número de elementos; espacio que es utilizando hasta que se agota. A partir de aquí, cada nueva demanda origina la asignación una zona de doble tamaño que la anterior. Por ejemplo, supongamos que para gestionar un vector de enteros, el compilador asigna inicialmente espacio para un máximo de 16 miembros.  Cuando se agotara, se realizaría una nueva asignación de espacio para 32 miembros, e inmediatamente se efectuaría una recolocación del contenido actual en el nuevo espacio y la liberación del primitivo. Si el nuevo contenedor quedara lleno de nuevo, la siguiente asignación sería capaz de 64 miembros y así sucesivamente.&lt;br /&gt;
&lt;br /&gt;
El factor de aumento de tamaño puede ser cualquiera. Muchos compiladores utilizan un factor 1.5 cada vez que deben ampliar el espacio necesario.&lt;br /&gt;
&lt;br /&gt;
Cada nueva recolocación implica varios pasos:&lt;br /&gt;
  •	Asignación de memoria al estilo malloc() de la librería clásica en cantidad suficiente para el nuevo tamaño.&lt;br /&gt;
  •	Copia de los elementos actuales en la nueva localización. Los elementos son colocados en la nueva situación utilizando el constructor copia.&lt;br /&gt;
  •	Actualización de las estructuras internas del nuevo contenedor (sistema de índices).&lt;br /&gt;
  •	Eliminación de los elementos originales mediante invocación sucesiva de sus correspondientes destructores.&lt;br /&gt;
  •	Liberación de la memoria utilizada por las estructuras internas.&lt;br /&gt;
  •	Liberación de la zona original mediante una invocación al estilo free de la librería clásica.&lt;br /&gt;
&lt;br /&gt;
En general, al referirse al tamaño de un contenedor existen tres magnitudes distintas aunque relacionadas, cuyos valores pueden obtenerse mediante tres métodos:&lt;br /&gt;
&lt;br /&gt;
  •	El número de elementos contenidos actualmente. size()&lt;br /&gt;
  •	El máximo número de elementos que pueden alcanzarse actualmente sin necesidad de una nueva recolocación. capacity()&lt;br /&gt;
  •	El máximo número de elementos que pueden alcanzarse en cualquier caso. max_size().&lt;br /&gt;
&lt;br /&gt;
 Ejemplo:&lt;br /&gt;
   #include &amp;lt;iostream&amp;gt;&lt;br /&gt;
   using namespace std;&lt;br /&gt;
   #include &amp;lt;vector&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   int main() {         // ================&lt;br /&gt;
   vector&amp;lt;int&amp;gt; vInt;&lt;br /&gt;
   for (int i=0; i &amp;lt; 100; i++) vInt.push_back(i);&lt;br /&gt;
&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Tamaño actual:   &amp;quot; &amp;lt;&amp;lt; vInt.size()     &amp;lt;&amp;lt; endl;&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Capacidad actual: &amp;quot; &amp;lt;&amp;lt; vInt.capacity() &amp;lt;&amp;lt; endl;&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Tamano maximo:   &amp;quot; &amp;lt;&amp;lt; vInt.max_size() &amp;lt;&amp;lt; endl;&lt;br /&gt;
   return 0;&lt;br /&gt;
   }&lt;br /&gt;
   Salida:&lt;br /&gt;
   Tamaño actual: 100&lt;br /&gt;
   Capacidad actual: 256&lt;br /&gt;
   Tamano maximo: 1073741823&lt;br /&gt;
&lt;br /&gt;
En todos los casos: size() &amp;lt;= capacity()&lt;br /&gt;
&lt;br /&gt;
Es posible comprobar si un contenedor está vacío, comparando su tamaño actual size() con cero, aunque es más rápido utilizar el método empty(), que devuelve true si realmente size() == 0.&lt;br /&gt;
&lt;br /&gt;
=== Reserva de espacio ===&lt;br /&gt;
Como puede suponer, cada recolocación supone un proceso considerable, sobre todo en contenedores muy grandes. Para evitar sus inconvenientes si se conoce de antemano el tamaño máximo a utilizar, la STL ofrece la posibilidad de preasignar un espacio arbitrario. Para esto se dispone del método reserve(n), que garantiza la asignación de espacio inicial suficiente para alojar n miembros en el contenedor. Si el argumento n es mayor que la capacidad actual, se produce una recolocación y el nuevo argumento determina la nueva capacidad. Si es menor no se produce ninguna acción.&lt;br /&gt;
&lt;br /&gt;
Ejemplo, para crear un vector de enteros capaz para al menos 1000 miembros:&lt;br /&gt;
  vector &amp;lt;int&amp;gt; v;&lt;br /&gt;
  v.reserve(1000);&lt;br /&gt;
&lt;br /&gt;
En el siguiente ejemplo se muestran los resultados compilado con Borland C++ 5.5 para Win32; con MS Visual C++ 6.0 y con GNU gcc 2.95.3 para Linux:&lt;br /&gt;
  // resultados con:         BC++   VC++   GNU   &lt;br /&gt;
  vector&amp;lt;int&amp;gt; v;&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 0      0      0   &lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 0      0      0&lt;br /&gt;
  v.push_back(3);&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    1      1&lt;br /&gt;
  v.reserve(100);&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    100    100&lt;br /&gt;
&lt;br /&gt;
=== Operaciones sobre contenedores ===&lt;br /&gt;
Los elementos de un contenedor son colocados en él utilizando el constructor copia, aunque algunas operaciones requieren la existencia de un constructor por defecto. A su vez, los algoritmos genéricos, como copy(), que copian a un contenedor, utilizan el operador de asignación.&lt;br /&gt;
&lt;br /&gt;
Cuando se duplica todo un contenedor de tipos T por invocación del [[Constructor (C++)|constructor]] copia o por asignación, cada miembro es copiado en la nueva estructura utilizando el constructor copia o el operador de asignación. Tanto si una copia profunda o una copia somera, el resultado es controlado por el programador, que puede proporcionar el operador de asignación para el tipo T con cualquier significado que desee. Si se ha definido un destructor para el tipo T, este destructor es invocado cada vez que deba ser eliminado un elemento del contenedor. Cuando se destruye toda la colección, el destructor es invocado por cada elemento que permaneciera almacenado.&lt;br /&gt;
&lt;br /&gt;
En estos casos, el contenedor es solamente responsable de mantener los propios punteros, siendo responsabilidad del programador manejar la memoria de los valores referenciados por estos, lo que supone que los espacios de memoria son asignados correctamente; por lo general mediante el operador new; que no son desasignados mientras el contenedor albergue referencias a ellos, y que sean adecuadamente desasignados una vez que han sido eliminados del contenedor.&lt;br /&gt;
&lt;br /&gt;
===  Secuencias ===&lt;br /&gt;
Las secuencias son estructuras de datos de tipo lineal, con posibilidad de que su tamaño puede ser alterado insertando elementos al principio, al final o en cualquier posición, si bien la idoneidad en este sentido es distinta entre los diversos tipos.&lt;br /&gt;
&lt;br /&gt;
La STL ofrece los siguientes:&lt;br /&gt;
  • deque&lt;br /&gt;
  • list&lt;br /&gt;
  • stack&lt;br /&gt;
  • vector&lt;br /&gt;
  • vector&amp;lt;bool&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La estructura lineal implica que sus datos son lógicamente contiguos, aunque su disposición física puede que no lo sea. Los elementos pueden ser accedidos por un índice numérico, aunque en algunos tipos de secuencia el acceso a un elemento implica un recorrido por la lista.&lt;br /&gt;
&lt;br /&gt;
== Contenedores asociativos ==&lt;br /&gt;
Los contenedores asociativos son una extensión de las secuencias. Mientras que en estas para acceder a los elementos solo pueden utilizarse claves numéricas, que señalan el número de orden del elemento dentro de la secuencia (al estilo de los índices en las matrices). Los contenedores asociativos admiten cualquier tipo de clave de acceso. Las más frecuentes son las cadenas alfanuméricas (stings).&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, razón por la que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.&lt;br /&gt;
&lt;br /&gt;
La ordenación se realiza según los valores de ciertos miembros del contenedor. Estos elementos son denominados &amp;quot;de claves&amp;quot; (&amp;quot;Key values&amp;quot;). Lo que exige que los objetos &amp;quot;de clave&amp;quot; sean de un tipo para el que estén definidos los operadores relacionales. El contenedor es mantenido ordenado de forma automática por los algoritmos de inserción y borrado.&lt;br /&gt;
&lt;br /&gt;
La STL proporciona cinco tipo distintos, aunque en realidad son tres clases; dos de ellas en dos variedades (permitiendo o no claves duplicadas). Uno de los tipos (bitset) sirve para almacenar campos de bits de longitud constante. Los otros dos permiten elementos ordenados de cualquier tipo (set y multiset), mientras que map y multimap permiten alojar pares de elementos. Uno que actúa como &amp;quot;Key value&amp;quot; y otro que puede ser un tipo cualquiera al que llamaremos valor-dato.&lt;br /&gt;
&lt;br /&gt;
  • bitset&lt;br /&gt;
  • set&lt;br /&gt;
  • multiset&lt;br /&gt;
  • map&lt;br /&gt;
  • multimap&lt;br /&gt;
&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave, y para recorrer el conjunto (ordenado) de las claves.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http://www.zator.com/Cpp/E5_1_1.htm Contenerores C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Contenedores en C.conclase.net]&lt;br /&gt;
* [https://docs.microsoft.com/es-es/cpp/standard-library/stl-containers?view=vs-2017  Contenedores de la biblioteca estándar de C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234218</id>
		<title>Contenedores C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234218"/>
		<updated>2018-11-29T18:14:39Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Contenedores C++ |imagen=  |concepto= En sentido C++ estricto, un contenedor de la STL es una clase genérica que puede instanciarse para representar diversos tipos de objetos. Esta clase incluye ciertas operaciones  sobre los objetos de su tipo; estas operaciones están representadas por funciones-miembro, incluyendo constructores y funciones-operador, que son a su vez funciones genéricas}}''' Contenedores C++ '''. Al mismo tiempo, desde el punto de vista de las teorías de la información, podemos considerarlos estructuras de datos más o menos adecuadas (según el caso) para aplicarles ciertos algoritmos.&lt;br /&gt;
De su propio nombre (&amp;quot;Containers&amp;quot;) podemos deducir que su misión principal, y razón de su existencia, es su función como estructuras de datos, y en este sentido podemos adelantar que entre sus funcionalidades más destacadas se encuentran la gestión del espacio de almacenamiento necesario.&lt;br /&gt;
Una de las primerísimas ventajas de la utilización de contenedores es que el programador no tiene que enredarse con las cuestiones siempre espinosas de asignar o liberar memoria para los objetos creados, de forma que queda liberado de los [[Operadores|operadores]] [[Operador new|new]] y [[Operador delete|delete]].&lt;br /&gt;
== Filosofía de uso ==&lt;br /&gt;
Una primera pincelada sobre la filosofía de uso de los contenedores mediante un sencillo ejemplo: si tenemos que manejar un conjunto de enteros, puede utilizarse una matriz de enteros, pero ya hemos señalado  que esta estructura nos obliga a conocer de antemano la cantidad de datos a almacenar (el tamaño de la matriz). En consecuencia, si el número de datos puede variar, esta opción no es muy adecuada. Además, si es importante mantener los datos ordenados, la utilización de una matriz nos obligaría a ingeniar por nuestra cuenta la forma de hacerlo; seguramente mediante complicadas rutinas de &amp;quot;sort&amp;quot; hechas manualmente.&lt;br /&gt;
&lt;br /&gt;
Una alternativa es utilizar como &amp;quot;contenedor&amp;quot; para nuestros enteros una clase genérica de la STL denominada vector. En este caso, serían posibles expresiones como las siguientes:&lt;br /&gt;
&lt;br /&gt;
  vector&amp;lt;int&amp;gt; v(3);         // L1:&lt;br /&gt;
  v[0] = 7;                 // L2:&lt;br /&gt;
  v[1] = v[0] + 1;          // L3:&lt;br /&gt;
  v[2] = v[0] + v[1];       // L4:&lt;br /&gt;
&lt;br /&gt;
Al encontrar la primera sentencia, el compilador crea una instancia (especialidad) anónima de la plantilla vector para alojar enteros; a continuación una instancia de ella para alojar tres enteros, a la que denominamos v.&lt;br /&gt;
&lt;br /&gt;
Una primera inspección de las sentencias L2 a L3, nos muestra que la clase ofrece la posibilidad de utilizar con sus miembros el operador subíndice de matriz [ ]. Deducimos por tanto, que dispone de una versión sobrecargada de este operador para los miembros de la clase, lo que nos permite utilizar el objeto v como una matriz, aunque con algunas funcionalidades no incluidas en aquellas.&lt;br /&gt;
&lt;br /&gt;
Después de L4 los valores finales para los miembros de nuestra &amp;quot;matriz&amp;quot; serian:&lt;br /&gt;
 v[0] == 7, v[1] == 8, v[2] == 15&lt;br /&gt;
&lt;br /&gt;
Si deseamos invertir el orden de los elementos de nuestra matriz. Para ello utilizamos una [[Función (programación)|función]] especial:&lt;br /&gt;
&lt;br /&gt;
 reverse(v.begin(), v.end());&lt;br /&gt;
&lt;br /&gt;
después de lo cual, el orden de miembros sería:&lt;br /&gt;
&lt;br /&gt;
 v[0] == 15, v[1] == 8, v[2] == 7&lt;br /&gt;
&lt;br /&gt;
La primera observación es que la función reverse utiliza dos argumentos, que son a su vez el valor devuelto por sendos métodos de clase (los aplicamos sobre nuestro objeto v).  El valor devuelto por estos métodos es lo que se conoce como un [[Iteradores (Programación)|iterador]]; una especie de puntero que señalan al interior de la estructura de datos representada por el contenedor v. En este caso, el primer iterador señala al primer miembro y el segundo a una posición después del último; de esta forma se indican los miembros inicial y final entre los que se realizará la operación de inversión efectuada por reverse.&lt;br /&gt;
&lt;br /&gt;
La segunda observación es que la función reverse no es un método de clase, sino una función global; es lo que denominamos un [[Algoritmo|algoritmo]]. Esta función tiene la peculiaridad de que puede ser aplicado sobre el contenedor vector (y algún otro); que opera sobre un rango de los elementos del contenedor, en nuestro caso sobre la totalidad (esta capacidad de operar sobre una parte de un contenedor es característica de los algoritmos). También que pueden operar sobre otros contenedores produciendo un efecto similar. Por ejemplo, el algoritmo reverse puede operar incluso sobre una simple matriz:&lt;br /&gt;
 char Ch[5] = { 'A', 'E', 'I', 'O', 'U' };&lt;br /&gt;
 reverse(Ch, Ch + 5);&lt;br /&gt;
 for (int i = 0; i &amp;lt; 5; ++i) cout &amp;lt;&amp;lt; &amp;quot;Ch[&amp;quot; &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &amp;quot;] = &amp;quot; &amp;lt;&amp;lt; Ch[i];&lt;br /&gt;
 Salida:&lt;br /&gt;
 Ch[0] = U Ch[1] = O Ch[2] = I Ch[3] = E Ch[4] = A&lt;br /&gt;
&lt;br /&gt;
Es significativo que el objeto v es una estructura de datos que permite acceder individualmente a sus miembros &amp;quot;como si&amp;quot; fuesen elementos de una matriz. También que se pueden aplicar ciertas operaciones sobre la totalidad, o parte, de esta estructura considerada como una unidad.&lt;br /&gt;
== Clasificación ==&lt;br /&gt;
Existen dos tipos de contenedores: secuencias y asociativos; a su vez se subdividen según el tipo de [[Iteradores (Programación)|iterador]] que soportan.&lt;br /&gt;
&lt;br /&gt;
Las secuencias almacenan los elementos en orden secuencial (de ahí su nombre). El contenedor agrupa a todos sus miembros como una sucesión lineal, y en consecuencia son adecuadas para accesos directos y secuenciales. Un ejemplo de secuencia es una matriz. De hecho, los algoritmos que pueden aplicarse a las secuencias pueden aplicarse también a las matrices.&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, por lo que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.  La STL proporciona cinco tipos distintos.&lt;br /&gt;
&lt;br /&gt;
La existencia de índices supone una ordenación según los valores de un conjunto de elementos (denominado &amp;quot;de claves&amp;quot;) para el que debe existir un criterio de ordenación. Dicho en otras palabras, los objetos &amp;quot;de clave&amp;quot; deben ser de un tipo para el que estén definidos los operadores relacionales. El árbol es mantenido ordenado de forma automática por los algoritmos de inserción y borrado del contenedor.&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave y para recorrer el conjunto (ordenado) de los elementos.&lt;br /&gt;
&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] contiene diez formas de contenedores y tres adaptadores de contenedor (denominados simplemente [[Adapter|adaptadores]]). En esta sección se expondrán brevemente cuales son estas formas; sus características, y cuál es la más adecuada para cada tipo de problema específico. En secciones sucesivas se comentarán individualmente con mayor detalle.&lt;br /&gt;
Relación siguiendo la clasificación utilizada en el Estándar:&lt;br /&gt;
  • Secuencias&lt;br /&gt;
      o	deque&lt;br /&gt;
      o	list&lt;br /&gt;
      o	stack&lt;br /&gt;
      o	vector&lt;br /&gt;
      o	vector &amp;lt;bool&amp;gt;&lt;br /&gt;
  • adaptadores&lt;br /&gt;
      o	queue&lt;br /&gt;
      o	priority_queue&lt;br /&gt;
  • Contenedores asociativos&lt;br /&gt;
      o	map&lt;br /&gt;
      o	multimap&lt;br /&gt;
      o	set&lt;br /&gt;
      o	multiset&lt;br /&gt;
      o	bitset&lt;br /&gt;
== Características ==&lt;br /&gt;
Las características más significativas de las diversas formas de contenedor son:&lt;br /&gt;
&lt;br /&gt;
Contenedor	Características&lt;br /&gt;
&lt;br /&gt;
Secuencias&lt;br /&gt;
&lt;br /&gt;
 vector: Este contenedor es una estructura de datos de tamaño fijo preferentemente. Aunque la STL proporciona herramientas para cambiar el tamaño de un vector de forma dinámica, esta operación es costosa y debe ser evitada dentro de lo posible (en este sentido el vector se comporta como una matriz ordinaria). &lt;br /&gt;
&lt;br /&gt;
Disponen de un buén mecanismo de acceso aleatorio a elementos y de un mecanismo de inserción al final muy eficiente.&lt;br /&gt;
Generalmente es preferible utilizar un vector que un deque o un list, a menos que sea frecuentemente necesario insertar datos al comienzo o al final, en cuyo caso es mejor utilizar un deque.  Si por el contrario es frecuente la inserción de elementos en el centro, entonces es preferible un list.&lt;br /&gt;
&lt;br /&gt;
 vector&amp;lt;bool&amp;gt;:	Es una versión de la anterior especial para valores binarios (bits).&lt;br /&gt;
&lt;br /&gt;
 list: Este contenedor responde a la idéa intuitiva de &amp;quot;lista&amp;quot;, el almacenamiento de objetos en una secuencia lineal que no está necesariamente ordenada (aunque sus miembros pueden ser ordenados fácilmente mediante la función-miembro sort() ). Estos contenedores suelen ser implementados como listas doblemente enlazadas. &lt;br /&gt;
&lt;br /&gt;
Dispone de mecanismos eficientes para insertar elementos al principio, al final o en cualquier posición (utilizando iteradores que denoten posición). Estas operaciones consumen un tiempo constante con independencia del número de elmentos albergados en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Dado que son estructuras lineales, en general los elementos no pueden ser accedidos por subíndices como en un vector.  Es necesario realizar un recorrido lineal por todos los valores, por lo que en las operaciones de acceso se utilizan tiempos proporcionales al número de elementos.&lt;br /&gt;
&lt;br /&gt;
 stack: Contenedor de elementos tipo pila LIFO que permite inserciones y eliminaciones solo en la parte superior.&lt;br /&gt;
&lt;br /&gt;
 deque: Los deques o colas de doble terminación (&amp;quot;Double-ended queue&amp;quot;) son un tipo de estructura de datos que comparte las características de las colas (&amp;quot;Queues&amp;quot;) y las pilas (&amp;quot;Stacks&amp;quot;). Como en las colas , los elementos pueden ser empujados por un extremo al interior del contenedor, y el primer elemento introducido puede ser extraído por el extremo opuesto. Al mismo tiempo, el último elemento introducido por el principio puede ser extraído en ese mismo extremo como si fuese una pila.&lt;br /&gt;
 &lt;br /&gt;
Estos contenedores suelen ser implementados bajo la forma de matrices bidimensionales.&lt;br /&gt;
&lt;br /&gt;
Las características de los deques implementados en la STL pueden resumirse en: Acceso aleatorio; mecanismo eficiente de inserción al principio o al final.&lt;br /&gt;
&lt;br /&gt;
 string: Contenedor de caracteres adaptado a operaciones con cadenas de caracteres.&lt;br /&gt;
&lt;br /&gt;
Asociaciones&lt;br /&gt;
&lt;br /&gt;
 set: Como el resto de contenedores asociativos, esta forma de contenedor mantiene los elementos en orden. Dispone de mecanismos eficientes para inclusión, inserción y eliminación de elementos, y soporta claves únicas (solo puede existir un miembro con una clave determinada).&lt;br /&gt;
&lt;br /&gt;
 multiset: Versión del anterior que permite la existencia de claves duplicadas. Es decir, distintos elementos dentro del conjunto pueden responder a la misma clave.&lt;br /&gt;
&lt;br /&gt;
 bitset: Contenedor de bit más orientado al tamaño que hacia el tipo de contenido. Permite almacenar secuencias de bits de tamaño fijo. No existen iteradores para reccorrerlas, y sus elementos se acceden utilizando el operador subíndice.&lt;br /&gt;
 &lt;br /&gt;
Se dispone de varias funciones para realizar con ellos operaciones de bits.&lt;br /&gt;
 &lt;br /&gt;
 map: Como el resto de estructuras asociativas, el map mantiene sus elementos ordenados. Se caracteriza porque sus miembros son pares de valores que pueden ser de tipos distintos. Uno de ellos, el que actúa como clave para el índice (&amp;quot;Key-value&amp;quot;), puede ser de cualquier tipo, a condición de que sus elementos puedan ser ordenados según un criterio (por defecto se utiliza el operador &amp;lt;).&lt;br /&gt;
 &lt;br /&gt;
Permite claves únicas. Es decir, que solo puede existir un miembro para cada clave. Dispone de mecanismos de inserción y borrado muy eficientes y no existe límite de tamaño. La estructura se encarga de crecer y disminuir en concordancia con las necesidades de sus miembros. Permite el operador [ ] subíndice para los elementos de la clave así como otras técnicas de acceso.&lt;br /&gt;
&lt;br /&gt;
Estas estructuras de datos recibe también los nombres de diccionarios, tablas y matrices asociativas, en referencia a que pueden considerarse como dos matrices del mismo número de elementos, en las que existe una relación entre cada miembro de una con otro miembro de la otra.  Una de las matrices (que actúa de índice) estaría ordenada según su contenido.&lt;br /&gt;
&lt;br /&gt;
 multimap: En todo igual que el anterior pero permitiendo además claves duplicadas. Es decir, que una misma clave pueda estar asociada a dos &amp;quot;valores&amp;quot; distintos.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Adaptador	Características&lt;br /&gt;
&lt;br /&gt;
 queue: Contenedor tipo cola FIFO que permite inserciones al final y eliminaciones al principio.&lt;br /&gt;
&lt;br /&gt;
 priority queue: Este contenedor dispone de mecanismos eficientes para acceso y eliminación de grandes valores.&lt;br /&gt;
&lt;br /&gt;
== Seleccionar un contenedor ==&lt;br /&gt;
El binomio contendor-iterador conforma una herramienta que se adapta a circunstancias muy variadas. Es posible que un determinado problema pueda ser abordado de varias formas, en estos casos la selección de la forma de contenedor más adecuado depende de las circunstancias. En ciertas ocasiones puede resultar bastante obvia; en otras puede no estar tan claro cuál es la mejor opción, pues &amp;quot;a priori&amp;quot;, pueden adaptarse varias formas al caso concreto. Puede utilizarse el sistema de prueba y comparación. Por ejemplo, cronometrando los resultados obtenidos en un modo u otro. También será de gran ayuda la experiencia, pero como una guía o criterio general puede utilizarse el principio de selección que se indica a continuación.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Como se accederá a los datos?.&lt;br /&gt;
| Si es importante un acceso aleatorio, pueden utilizarse un vector o un deque. Si basta con un acceso secuencial cualquiera de los dos puede ser el elegido.&lt;br /&gt;
|-&lt;br /&gt;
| Es importante el orden en que serán mantenidos los valores dentro de la colección de datos?&lt;br /&gt;
| Existen muchas formas de secuenciar los valores. Si es importante un orden estricto a lo largo de toda la vida del contenedor, la elección obvia es un set, dado que las inserciones en una de estas estructuras se realizan automáticamente en orden.&lt;br /&gt;
 &lt;br /&gt;
Si este orden es importante solo en algún momento, por ejemplo al final de una serie de inserciones, puede ser más sencillo colocar los valores en un list o vector para ordenar más tarde el resultado en el momento necesario.&lt;br /&gt;
&lt;br /&gt;
Si el orden en que se almacenan los valores en la estructura está relacionado con el orden de su inserción, entonces un stack, un queue o un list pueden ser la mejor elección.&lt;br /&gt;
|-&lt;br /&gt;
| Puede variar mucho el tamaño de la estructura de datos durante el curso de la ejecución del programa?&lt;br /&gt;
| Si es así, entonces puede ser que la mejor opción sean un list o un set. Un vector o un deque pueden conducir a mantener un gran almacenamiento intermedio (buffer); incluso después que los elementos hayan sido eliminados de la colección de datos. Estos dos contenedores no son adecuados para cambios de tamaño, aunque vector dispone de un mecanismo de inserción al final eficiente.&lt;br /&gt;
 &lt;br /&gt;
Recíprocamente: si el tamaño de la colección se mantiene relativamente estable, entonces un vector o un deque pueden utilizar menos memoria que un list o un set que almacenen el mismo número de elementos.&lt;br /&gt;
|-&lt;br /&gt;
| Es posible determinar el tamaño de la colección?&lt;br /&gt;
| La estructura de datos vector proporciona un medio para pre-seleccionar un bloque de memoria de un tamaño específico con la función miembro reserve, posibilidad que no existe en otros contenedores.&lt;br /&gt;
|-&lt;br /&gt;
| Es frecuente tener que comprobar si un valor cualquiera está incluido en la colección?&lt;br /&gt;
| En este caso, un contenedor set o map pueden ser buena elección. En estos casos comprobar si un determinado valor está incluido puede ser realizado con un pequeño número de pasos (logarítmicos con el tamaño del contenedor). Mientras que la misma verificación en cualquiera de los otros tipos puede requerir comparar el valor con cada elemento almacenado en el contenedor.&lt;br /&gt;
|-&lt;br /&gt;
| Está indexada la colección de datos? &lt;br /&gt;
| Si las claves son enteros entre 0 y un límite superior, pueden utilizarse un vector o un deque. &lt;br /&gt;
|-&lt;br /&gt;
| Si es así, puede ser vista la colección como una serie de pares clave/valor?&lt;br /&gt;
| Si la clave es algún otro valor, como cadenas de caracteres o tipos definidos por el usuario, puede utilizarse un contenedor map.&lt;br /&gt;
|-&lt;br /&gt;
| Pueden los valores estar relacionados unos con otros?&lt;br /&gt;
| Todos los valores almacenados en cualquier contenedor de la STL debe ser capaz de comprobar la igualdad con cualquier otro valor similar, pero recuerde que no todos son capaces de reconocer el operador de relación menor-que; sin embargo, si los valores no pueden ser ordenados utilizando el operador menor-que, no pueden ser almacenados en un set o en un map.&lt;br /&gt;
|-&lt;br /&gt;
| Es una operación frecuente tener que encontrar y eliminar el valor mayor de la colección?&lt;br /&gt;
| En caso afirmativo, la estructura de datos más idónea es el priority queue.&lt;br /&gt;
|-&lt;br /&gt;
| En que posiciones son insertados o eliminados los elementos de la estructura?&lt;br /&gt;
| Si los valores son añadidos o eliminados en la zona interior, entonces la mejor opción es un list.&lt;br /&gt;
 &lt;br /&gt;
Si los valores son insertados solo al comienzo, un deque o un list pueden ser lo más adecuado.&lt;br /&gt;
&lt;br /&gt;
Si los valores son insertados y eliminados solo al final, un stack o un queue pueden ser elecciones lógicas.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| Es frecuente tener que refundir dos o más secuencias en una sola?&lt;br /&gt;
| En caso afirmativo, puede considerarse que las mejores opciones son un set o un list, dependiendo que la colección deba o no ser mantenida en orden.&lt;br /&gt;
 &lt;br /&gt;
Refundir dos set es una operación muy eficiente.  Si la colección de datos no está ordenada, pero puede utilizarse la función miembro splice() de las list (que es muy eficiente), entonces es preferible este último tipo de contenedor, dado que esta operación no está contemplada en las demás formas.&lt;br /&gt;
|}&lt;br /&gt;
=== Tipos no incluidos ===&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] incluye contenedores adecuados para la mayoría de los casos prácticos, aunque quizás existen una serie de estructuras de datos clásicas que no han sido incluidas. En la mayoría de los casos, la causa es que los contenedores proporcionados pueden ser fácilmente adaptados para suplir los usos facilitados por los tipos omitidos.&lt;br /&gt;
&lt;br /&gt;
Tipos clásicos no incluidos y la sustitución más fácil.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Contenedor omitido&lt;br /&gt;
! Sustitución utilizando elementos de STL&lt;br /&gt;
|-&lt;br /&gt;
| tree&lt;br /&gt;
| El modo set está implementado internamente como un árbol de búsqueda binaria. &lt;br /&gt;
&lt;br /&gt;
Para la mayoría de los casos prácticos que pueden ser resueltos utilizando árboles este modo es un sustituto adecuado.&lt;br /&gt;
|-&lt;br /&gt;
| matrices multidimensionales&lt;br /&gt;
| Puesto que los vectores pueden almacenar elementos que sean otros vectores, estas estructuras pueden ser construidas fácilmente.&lt;br /&gt;
|-&lt;br /&gt;
| graph&lt;br /&gt;
| La representación de un gráfico puede ser fácilmente construida como un map que contiene otros map. Un map cuyos elementos son a su vez maps, es la representación natural de un gráfico directo. &lt;br /&gt;
|-&lt;br /&gt;
| sparse array&lt;br /&gt;
| Una novedosa sustitución es la representación de un gráfico&lt;br /&gt;
|-&lt;br /&gt;
| hash table&lt;br /&gt;
| Las tablas hash proporcionan un tiempo de acceso constante, así como inserción y borrado de elementos, convirtiendo estas operaciones en operaciones de índice.&lt;br /&gt;
 &lt;br /&gt;
Una tabla hash puede ser construida fácilmente como un vector (o deque) cuyos elementos son lists (o incluso sets).  En el ejemplo de la ordenación raíz (  xxx) se describe una de estas estructuras (un vector de deques), aunque en este ejemplo no incluye invocación la función hash para convertir un valor en un índice.&lt;br /&gt;
|-&lt;br /&gt;
| Funcionalidad set&lt;br /&gt;
| En la STL, los tipos set están específicamente ordenados, y sus operaciones (como la unión intersección, etc.) no pueden ser realizadas sobre colecciones de valores no ordenados (por ejemplo un conjunto de números complejos).&lt;br /&gt;
 &lt;br /&gt;
Una list puede ser utilizada como sustituto, aunque es necesario escribir funciones de operación especiales, dado que los algoritmos genéricos no pueden ser utilizados con listas.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Gestión de memoria ==&lt;br /&gt;
La gestión de memoria realizada por los contenedores comprende tanto la asignación y liberación de espacio para sus miembros, como para las claves que constituyen el sistema de índice de algunos tipos de contenedor. En general los algoritmos de la STL están muy optimizados y el sistema de asignación de memoria intenta compaginar rapidez y eficacia. La primera exige asignar y desasignar espacio cada vez que se introduce o elimina un miembro del contenedor. La eficacia, e incluso la disminución de la fragmentación inherentes al manejo del montón, exige asignar y rehusar trozos de memoria lo más grandes posible cada vez. El abordaje a este problema se ha realizado de dos formas básicas: (a) Contenedores que no pueden alterar su tamaño, de forma que la asignación de espacio para sus elementos debe realizarse en el momento de su declaración. (b) Contenedores que pueden crecer y/o disminuir en consonancia con los elementos a albergar.&lt;br /&gt;
&lt;br /&gt;
Refiriéndonos al caso (b), para balancear estas exigencias contrapuestas, algunas implementaciones utilizan el siguiente esquema de trabajo: inicialmente el sistema asigna al contenedor un trozo de memoria de tamaño adecuado para contener cierto número de elementos; espacio que es utilizando hasta que se agota. A partir de aquí, cada nueva demanda origina la asignación una zona de doble tamaño que la anterior. Por ejemplo, supongamos que para gestionar un vector de enteros, el compilador asigna inicialmente espacio para un máximo de 16 miembros.  Cuando se agotara, se realizaría una nueva asignación de espacio para 32 miembros, e inmediatamente se efectuaría una recolocación del contenido actual en el nuevo espacio y la liberación del primitivo. Si el nuevo contenedor quedara lleno de nuevo, la siguiente asignación sería capaz de 64 miembros y así sucesivamente.&lt;br /&gt;
&lt;br /&gt;
El factor de aumento de tamaño puede ser cualquiera. Muchos compiladores utilizan un factor 1.5 cada vez que deben ampliar el espacio necesario.&lt;br /&gt;
&lt;br /&gt;
Cada nueva recolocación implica varios pasos:&lt;br /&gt;
  •	Asignación de memoria al estilo malloc() de la librería clásica en cantidad suficiente para el nuevo tamaño.&lt;br /&gt;
  •	Copia de los elementos actuales en la nueva localización. Los elementos son colocados en la nueva situación utilizando el constructor copia.&lt;br /&gt;
  •	Actualización de las estructuras internas del nuevo contenedor (sistema de índices).&lt;br /&gt;
  •	Eliminación de los elementos originales mediante invocación sucesiva de sus correspondientes destructores.&lt;br /&gt;
  •	Liberación de la memoria utilizada por las estructuras internas.&lt;br /&gt;
  •	Liberación de la zona original mediante una invocación al estilo free de la librería clásica.&lt;br /&gt;
&lt;br /&gt;
En general, al referirse al tamaño de un contenedor existen tres magnitudes distintas aunque relacionadas, cuyos valores pueden obtenerse mediante tres métodos:&lt;br /&gt;
&lt;br /&gt;
  •	El número de elementos contenidos actualmente. size()&lt;br /&gt;
  •	El máximo número de elementos que pueden alcanzarse actualmente sin necesidad de una nueva recolocación. capacity()&lt;br /&gt;
  •	El máximo número de elementos que pueden alcanzarse en cualquier caso. max_size().&lt;br /&gt;
&lt;br /&gt;
 Ejemplo:&lt;br /&gt;
   #include &amp;lt;iostream&amp;gt;&lt;br /&gt;
   using namespace std;&lt;br /&gt;
   #include &amp;lt;vector&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   int main() {         // ================&lt;br /&gt;
   vector&amp;lt;int&amp;gt; vInt;&lt;br /&gt;
   for (int i=0; i &amp;lt; 100; i++) vInt.push_back(i);&lt;br /&gt;
&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Tamaño actual:   &amp;quot; &amp;lt;&amp;lt; vInt.size()     &amp;lt;&amp;lt; endl;&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Capacidad actual: &amp;quot; &amp;lt;&amp;lt; vInt.capacity() &amp;lt;&amp;lt; endl;&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Tamano maximo:   &amp;quot; &amp;lt;&amp;lt; vInt.max_size() &amp;lt;&amp;lt; endl;&lt;br /&gt;
   return 0;&lt;br /&gt;
   }&lt;br /&gt;
   Salida:&lt;br /&gt;
   Tamaño actual: 100&lt;br /&gt;
   Capacidad actual: 256&lt;br /&gt;
   Tamano maximo: 1073741823&lt;br /&gt;
&lt;br /&gt;
En todos los casos: size() &amp;lt;= capacity()&lt;br /&gt;
&lt;br /&gt;
Es posible comprobar si un contenedor está vacío, comparando su tamaño actual size() con cero, aunque es más rápido utilizar el método empty(), que devuelve true si realmente size() == 0.&lt;br /&gt;
&lt;br /&gt;
=== Reserva de espacio ===&lt;br /&gt;
Como puede suponer, cada recolocación supone un proceso considerable, sobre todo en contenedores muy grandes. Para evitar sus inconvenientes si se conoce de antemano el tamaño máximo a utilizar, la STL ofrece la posibilidad de preasignar un espacio arbitrario. Para esto se dispone del método reserve(n), que garantiza la asignación de espacio inicial suficiente para alojar n miembros en el contenedor. Si el argumento n es mayor que la capacidad actual, se produce una recolocación y el nuevo argumento determina la nueva capacidad. Si es menor no se produce ninguna acción.&lt;br /&gt;
&lt;br /&gt;
Ejemplo, para crear un vector de enteros capaz para al menos 1000 miembros:&lt;br /&gt;
  vector &amp;lt;int&amp;gt; v;&lt;br /&gt;
  v.reserve(1000);&lt;br /&gt;
&lt;br /&gt;
En el siguiente ejemplo se muestran los resultados compilado con Borland C++ 5.5 para Win32; con MS Visual C++ 6.0 y con GNU gcc 2.95.3 para Linux:&lt;br /&gt;
  // resultados con:         BC++   VC++   GNU   &lt;br /&gt;
  vector&amp;lt;int&amp;gt; v;&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 0      0      0   &lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 0      0      0&lt;br /&gt;
  v.push_back(3);&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    1      1&lt;br /&gt;
  v.reserve(100);&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    100    100&lt;br /&gt;
&lt;br /&gt;
=== Operaciones sobre contenedores ===&lt;br /&gt;
Los elementos de un contenedor son colocados en él utilizando el constructor copia, aunque algunas operaciones requieren la existencia de un constructor por defecto. A su vez, los algoritmos genéricos, como copy(), que copian a un contenedor, utilizan el operador de asignación.&lt;br /&gt;
&lt;br /&gt;
Cuando se duplica todo un contenedor de tipos T por invocación del [[Constructor (C++)|constructor]] copia o por asignación, cada miembro es copiado en la nueva estructura utilizando el constructor copia o el operador de asignación. Tanto si una copia profunda o una copia somera, el resultado es controlado por el programador, que puede proporcionar el operador de asignación para el tipo T con cualquier significado que desee. Si se ha definido un destructor para el tipo T, este destructor es invocado cada vez que deba ser eliminado un elemento del contenedor. Cuando se destruye toda la colección, el destructor es invocado por cada elemento que permaneciera almacenado.&lt;br /&gt;
&lt;br /&gt;
En estos casos, el contenedor es solamente responsable de mantener los propios punteros, siendo responsabilidad del programador manejar la memoria de los valores referenciados por estos, lo que supone que los espacios de memoria son asignados correctamente; por lo general mediante el operador new; que no son desasignados mientras el contenedor albergue referencias a ellos, y que sean adecuadamente desasignados una vez que han sido eliminados del contenedor.&lt;br /&gt;
&lt;br /&gt;
===  Secuencias ===&lt;br /&gt;
Las secuencias son estructuras de datos de tipo lineal, con posibilidad de que su tamaño puede ser alterado insertando elementos al principio, al final o en cualquier posición, si bien la idoneidad en este sentido es distinta entre los diversos tipos.&lt;br /&gt;
&lt;br /&gt;
La STL ofrece los siguientes:&lt;br /&gt;
  • deque&lt;br /&gt;
  • list&lt;br /&gt;
  • stack&lt;br /&gt;
  • vector&lt;br /&gt;
  • vector&amp;lt;bool&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La estructura lineal implica que sus datos son lógicamente contiguos, aunque su disposición física puede que no lo sea. Los elementos pueden ser accedidos por un índice numérico, aunque en algunos tipos de secuencia el acceso a un elemento implica un recorrido por la lista.&lt;br /&gt;
&lt;br /&gt;
== Contenedores asociativos ==&lt;br /&gt;
Los contenedores asociativos son una extensión de las secuencias. Mientras que en estas para acceder a los elementos solo pueden utilizarse claves numéricas, que señalan el número de orden del elemento dentro de la secuencia (al estilo de los índices en las matrices). Los contenedores asociativos admiten cualquier tipo de clave de acceso. Las más frecuentes son las cadenas alfanuméricas (stings).&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, razón por la que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.&lt;br /&gt;
&lt;br /&gt;
La ordenación se realiza según los valores de ciertos miembros del contenedor. Estos elementos son denominados &amp;quot;de claves&amp;quot; (&amp;quot;Key values&amp;quot;). Lo que exige que los objetos &amp;quot;de clave&amp;quot; sean de un tipo para el que estén definidos los operadores relacionales. El contenedor es mantenido ordenado de forma automática por los algoritmos de inserción y borrado.&lt;br /&gt;
&lt;br /&gt;
La STL proporciona cinco tipo distintos, aunque en realidad son tres clases; dos de ellas en dos variedades (permitiendo o no claves duplicadas). Uno de los tipos (bitset) sirve para almacenar campos de bits de longitud constante. Los otros dos permiten elementos ordenados de cualquier tipo (set y multiset), mientras que map y multimap permiten alojar pares de elementos. Uno que actúa como &amp;quot;Key value&amp;quot; y otro que puede ser un tipo cualquiera al que llamaremos valor-dato.&lt;br /&gt;
&lt;br /&gt;
  • bitset&lt;br /&gt;
  • set&lt;br /&gt;
  • multiset&lt;br /&gt;
  • map&lt;br /&gt;
  • multimap&lt;br /&gt;
&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave, y para recorrer el conjunto (ordenado) de las claves.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http://www.zator.com/Cpp/E5_1_1.htm Contenerores C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Contenedores en C.conclase.net]&lt;br /&gt;
* [https://docs.microsoft.com/es-es/cpp/standard-library/stl-containers?view=vs-2017  Contenedores de la biblioteca estándar de C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234217</id>
		<title>Contenedores C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234217"/>
		<updated>2018-11-29T18:14:03Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Contenedores C++ |imagen=  |concepto= En sentido C++ estricto, un contenedor de la STL es una clase genérica que puede instanciarse para representar diversos tipos de objetos. Esta clase incluye ciertas operaciones  sobre los objetos de su tipo; estas operaciones están representadas por funciones-miembro, incluyendo constructores y funciones-operador, que son a su vez funciones genéricas}}''' Contenedores C++ '''. Al mismo tiempo, desde el punto de vista de las teorías de la información, podemos considerarlos estructuras de datos más o menos adecuadas (según el caso) para aplicarles ciertos algoritmos.&lt;br /&gt;
De su propio nombre (&amp;quot;Containers&amp;quot;) podemos deducir que su misión principal, y razón de su existencia, es su función como estructuras de datos, y en este sentido podemos adelantar que entre sus funcionalidades más destacadas se encuentran la gestión del espacio de almacenamiento necesario.&lt;br /&gt;
Una de las primerísimas ventajas de la utilización de contenedores es que el programador no tiene que enredarse con las cuestiones siempre espinosas de asignar o liberar memoria para los objetos creados, de forma que queda liberado de los [[Operadores|operadores]] [[Operador new|new]] y [[Operador delete|delete]].&lt;br /&gt;
== Filosofía de uso ==&lt;br /&gt;
Una primera pincelada sobre la filosofía de uso de los contenedores mediante un sencillo ejemplo: si tenemos que manejar un conjunto de enteros, puede utilizarse una matriz de enteros, pero ya hemos señalado  que esta estructura nos obliga a conocer de antemano la cantidad de datos a almacenar (el tamaño de la matriz). En consecuencia, si el número de datos puede variar, esta opción no es muy adecuada. Además, si es importante mantener los datos ordenados, la utilización de una matriz nos obligaría a ingeniar por nuestra cuenta la forma de hacerlo; seguramente mediante complicadas rutinas de &amp;quot;sort&amp;quot; hechas manualmente.&lt;br /&gt;
&lt;br /&gt;
Una alternativa es utilizar como &amp;quot;contenedor&amp;quot; para nuestros enteros una clase genérica de la STL denominada vector. En este caso, serían posibles expresiones como las siguientes:&lt;br /&gt;
&lt;br /&gt;
  vector&amp;lt;int&amp;gt; v(3);         // L1:&lt;br /&gt;
  v[0] = 7;                 // L2:&lt;br /&gt;
  v[1] = v[0] + 1;          // L3:&lt;br /&gt;
  v[2] = v[0] + v[1];       // L4:&lt;br /&gt;
&lt;br /&gt;
Al encontrar la primera sentencia, el compilador crea una instancia (especialidad) anónima de la plantilla vector para alojar enteros; a continuación una instancia de ella para alojar tres enteros, a la que denominamos v.&lt;br /&gt;
&lt;br /&gt;
Una primera inspección de las sentencias L2 a L3, nos muestra que la clase ofrece la posibilidad de utilizar con sus miembros el operador subíndice de matriz [ ]. Deducimos por tanto, que dispone de una versión sobrecargada de este operador para los miembros de la clase, lo que nos permite utilizar el objeto v como una matriz, aunque con algunas funcionalidades no incluidas en aquellas.&lt;br /&gt;
&lt;br /&gt;
Después de L4 los valores finales para los miembros de nuestra &amp;quot;matriz&amp;quot; serian:&lt;br /&gt;
 v[0] == 7, v[1] == 8, v[2] == 15&lt;br /&gt;
&lt;br /&gt;
Si deseamos invertir el orden de los elementos de nuestra matriz. Para ello utilizamos una [[Función (programación)|función]] especial:&lt;br /&gt;
&lt;br /&gt;
 reverse(v.begin(), v.end());&lt;br /&gt;
&lt;br /&gt;
después de lo cual, el orden de miembros sería:&lt;br /&gt;
&lt;br /&gt;
 v[0] == 15, v[1] == 8, v[2] == 7&lt;br /&gt;
&lt;br /&gt;
La primera observación es que la función reverse utiliza dos argumentos, que son a su vez el valor devuelto por sendos métodos de clase (los aplicamos sobre nuestro objeto v).  El valor devuelto por estos métodos es lo que se conoce como un [[Iteradores (Programación)|iterador]]; una especie de puntero que señalan al interior de la estructura de datos representada por el contenedor v. En este caso, el primer iterador señala al primer miembro y el segundo a una posición después del último; de esta forma se indican los miembros inicial y final entre los que se realizará la operación de inversión efectuada por reverse.&lt;br /&gt;
&lt;br /&gt;
La segunda observación es que la función reverse no es un método de clase, sino una función global; es lo que denominamos un [[Algoritmo|algoritmo]]. Esta función tiene la peculiaridad de que puede ser aplicado sobre el contenedor vector (y algún otro); que opera sobre un rango de los elementos del contenedor, en nuestro caso sobre la totalidad (esta capacidad de operar sobre una parte de un contenedor es característica de los algoritmos). También que pueden operar sobre otros contenedores produciendo un efecto similar. Por ejemplo, el algoritmo reverse puede operar incluso sobre una simple matriz:&lt;br /&gt;
 char Ch[5] = { 'A', 'E', 'I', 'O', 'U' };&lt;br /&gt;
 reverse(Ch, Ch + 5);&lt;br /&gt;
 for (int i = 0; i &amp;lt; 5; ++i) cout &amp;lt;&amp;lt; &amp;quot;Ch[&amp;quot; &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &amp;quot;] = &amp;quot; &amp;lt;&amp;lt; Ch[i];&lt;br /&gt;
 Salida:&lt;br /&gt;
 Ch[0] = U Ch[1] = O Ch[2] = I Ch[3] = E Ch[4] = A&lt;br /&gt;
&lt;br /&gt;
Es significativo que el objeto v es una estructura de datos que permite acceder individualmente a sus miembros &amp;quot;como si&amp;quot; fuesen elementos de una matriz. También que se pueden aplicar ciertas operaciones sobre la totalidad, o parte, de esta estructura considerada como una unidad.&lt;br /&gt;
== Clasificación ==&lt;br /&gt;
Existen dos tipos de contenedores: secuencias y asociativos; a su vez se subdividen según el tipo de [[Iteradores (Programación)|iterador]] que soportan.&lt;br /&gt;
&lt;br /&gt;
Las secuencias almacenan los elementos en orden secuencial (de ahí su nombre). El contenedor agrupa a todos sus miembros como una sucesión lineal, y en consecuencia son adecuadas para accesos directos y secuenciales. Un ejemplo de secuencia es una matriz. De hecho, los algoritmos que pueden aplicarse a las secuencias pueden aplicarse también a las matrices.&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, por lo que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.  La STL proporciona cinco tipos distintos.&lt;br /&gt;
&lt;br /&gt;
La existencia de índices supone una ordenación según los valores de un conjunto de elementos (denominado &amp;quot;de claves&amp;quot;) para el que debe existir un criterio de ordenación. Dicho en otras palabras, los objetos &amp;quot;de clave&amp;quot; deben ser de un tipo para el que estén definidos los operadores relacionales. El árbol es mantenido ordenado de forma automática por los algoritmos de inserción y borrado del contenedor.&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave y para recorrer el conjunto (ordenado) de los elementos.&lt;br /&gt;
&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] contiene diez formas de contenedores y tres adaptadores de contenedor (denominados simplemente [[Adapter|adaptadores]]). En esta sección se expondrán brevemente cuales son estas formas; sus características, y cuál es la más adecuada para cada tipo de problema específico. En secciones sucesivas se comentarán individualmente con mayor detalle.&lt;br /&gt;
Relación siguiendo la clasificación utilizada en el Estándar:&lt;br /&gt;
  •	Secuencias&lt;br /&gt;
      o	deque&lt;br /&gt;
      o	list&lt;br /&gt;
      o	stack&lt;br /&gt;
      o	vector&lt;br /&gt;
      o	vector &amp;lt;bool&amp;gt;&lt;br /&gt;
  •	adaptadores&lt;br /&gt;
      o	queue&lt;br /&gt;
      o	priority_queue&lt;br /&gt;
  •	Contenedores asociativos&lt;br /&gt;
      o	map&lt;br /&gt;
      o	multimap&lt;br /&gt;
      o	set&lt;br /&gt;
      o	multiset&lt;br /&gt;
      o	bitset&lt;br /&gt;
== Características ==&lt;br /&gt;
Las características más significativas de las diversas formas de contenedor son:&lt;br /&gt;
&lt;br /&gt;
Contenedor	Características&lt;br /&gt;
&lt;br /&gt;
Secuencias&lt;br /&gt;
&lt;br /&gt;
 vector: Este contenedor es una estructura de datos de tamaño fijo preferentemente. Aunque la STL proporciona herramientas para cambiar el tamaño de un vector de forma dinámica, esta operación es costosa y debe ser evitada dentro de lo posible (en este sentido el vector se comporta como una matriz ordinaria). &lt;br /&gt;
&lt;br /&gt;
Disponen de un buén mecanismo de acceso aleatorio a elementos y de un mecanismo de inserción al final muy eficiente.&lt;br /&gt;
Generalmente es preferible utilizar un vector que un deque o un list, a menos que sea frecuentemente necesario insertar datos al comienzo o al final, en cuyo caso es mejor utilizar un deque.  Si por el contrario es frecuente la inserción de elementos en el centro, entonces es preferible un list.&lt;br /&gt;
&lt;br /&gt;
 vector&amp;lt;bool&amp;gt;:	Es una versión de la anterior especial para valores binarios (bits).&lt;br /&gt;
&lt;br /&gt;
 list: Este contenedor responde a la idéa intuitiva de &amp;quot;lista&amp;quot;, el almacenamiento de objetos en una secuencia lineal que no está necesariamente ordenada (aunque sus miembros pueden ser ordenados fácilmente mediante la función-miembro sort() ). Estos contenedores suelen ser implementados como listas doblemente enlazadas. &lt;br /&gt;
&lt;br /&gt;
Dispone de mecanismos eficientes para insertar elementos al principio, al final o en cualquier posición (utilizando iteradores que denoten posición). Estas operaciones consumen un tiempo constante con independencia del número de elmentos albergados en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Dado que son estructuras lineales, en general los elementos no pueden ser accedidos por subíndices como en un vector.  Es necesario realizar un recorrido lineal por todos los valores, por lo que en las operaciones de acceso se utilizan tiempos proporcionales al número de elementos.&lt;br /&gt;
&lt;br /&gt;
 stack: Contenedor de elementos tipo pila LIFO que permite inserciones y eliminaciones solo en la parte superior.&lt;br /&gt;
&lt;br /&gt;
 deque: Los deques o colas de doble terminación (&amp;quot;Double-ended queue&amp;quot;) son un tipo de estructura de datos que comparte las características de las colas (&amp;quot;Queues&amp;quot;) y las pilas (&amp;quot;Stacks&amp;quot;). Como en las colas , los elementos pueden ser empujados por un extremo al interior del contenedor, y el primer elemento introducido puede ser extraído por el extremo opuesto. Al mismo tiempo, el último elemento introducido por el principio puede ser extraído en ese mismo extremo como si fuese una pila.&lt;br /&gt;
 &lt;br /&gt;
Estos contenedores suelen ser implementados bajo la forma de matrices bidimensionales.&lt;br /&gt;
&lt;br /&gt;
Las características de los deques implementados en la STL pueden resumirse en: Acceso aleatorio; mecanismo eficiente de inserción al principio o al final.&lt;br /&gt;
&lt;br /&gt;
 string: Contenedor de caracteres adaptado a operaciones con cadenas de caracteres.&lt;br /&gt;
&lt;br /&gt;
Asociaciones&lt;br /&gt;
&lt;br /&gt;
 set: Como el resto de contenedores asociativos, esta forma de contenedor mantiene los elementos en orden. Dispone de mecanismos eficientes para inclusión, inserción y eliminación de elementos, y soporta claves únicas (solo puede existir un miembro con una clave determinada).&lt;br /&gt;
&lt;br /&gt;
 multiset: Versión del anterior que permite la existencia de claves duplicadas. Es decir, distintos elementos dentro del conjunto pueden responder a la misma clave.&lt;br /&gt;
&lt;br /&gt;
 bitset: Contenedor de bit más orientado al tamaño que hacia el tipo de contenido. Permite almacenar secuencias de bits de tamaño fijo. No existen iteradores para reccorrerlas, y sus elementos se acceden utilizando el operador subíndice.&lt;br /&gt;
 &lt;br /&gt;
Se dispone de varias funciones para realizar con ellos operaciones de bits.&lt;br /&gt;
 &lt;br /&gt;
 map: Como el resto de estructuras asociativas, el map mantiene sus elementos ordenados. Se caracteriza porque sus miembros son pares de valores que pueden ser de tipos distintos. Uno de ellos, el que actúa como clave para el índice (&amp;quot;Key-value&amp;quot;), puede ser de cualquier tipo, a condición de que sus elementos puedan ser ordenados según un criterio (por defecto se utiliza el operador &amp;lt;).&lt;br /&gt;
 &lt;br /&gt;
Permite claves únicas. Es decir, que solo puede existir un miembro para cada clave. Dispone de mecanismos de inserción y borrado muy eficientes y no existe límite de tamaño. La estructura se encarga de crecer y disminuir en concordancia con las necesidades de sus miembros. Permite el operador [ ] subíndice para los elementos de la clave así como otras técnicas de acceso.&lt;br /&gt;
&lt;br /&gt;
Estas estructuras de datos recibe también los nombres de diccionarios, tablas y matrices asociativas, en referencia a que pueden considerarse como dos matrices del mismo número de elementos, en las que existe una relación entre cada miembro de una con otro miembro de la otra.  Una de las matrices (que actúa de índice) estaría ordenada según su contenido.&lt;br /&gt;
&lt;br /&gt;
 multimap: En todo igual que el anterior pero permitiendo además claves duplicadas. Es decir, que una misma clave pueda estar asociada a dos &amp;quot;valores&amp;quot; distintos.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Adaptador	Características&lt;br /&gt;
&lt;br /&gt;
 queue: Contenedor tipo cola FIFO que permite inserciones al final y eliminaciones al principio.&lt;br /&gt;
&lt;br /&gt;
 priority queue: Este contenedor dispone de mecanismos eficientes para acceso y eliminación de grandes valores.&lt;br /&gt;
&lt;br /&gt;
== Seleccionar un contenedor ==&lt;br /&gt;
El binomio contendor-iterador conforma una herramienta que se adapta a circunstancias muy variadas. Es posible que un determinado problema pueda ser abordado de varias formas, en estos casos la selección de la forma de contenedor más adecuado depende de las circunstancias. En ciertas ocasiones puede resultar bastante obvia; en otras puede no estar tan claro cuál es la mejor opción, pues &amp;quot;a priori&amp;quot;, pueden adaptarse varias formas al caso concreto. Puede utilizarse el sistema de prueba y comparación. Por ejemplo, cronometrando los resultados obtenidos en un modo u otro. También será de gran ayuda la experiencia, pero como una guía o criterio general puede utilizarse el principio de selección que se indica a continuación.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Como se accederá a los datos?.&lt;br /&gt;
| Si es importante un acceso aleatorio, pueden utilizarse un vector o un deque. Si basta con un acceso secuencial cualquiera de los dos puede ser el elegido.&lt;br /&gt;
|-&lt;br /&gt;
| Es importante el orden en que serán mantenidos los valores dentro de la colección de datos?&lt;br /&gt;
| Existen muchas formas de secuenciar los valores. Si es importante un orden estricto a lo largo de toda la vida del contenedor, la elección obvia es un set, dado que las inserciones en una de estas estructuras se realizan automáticamente en orden.&lt;br /&gt;
 &lt;br /&gt;
Si este orden es importante solo en algún momento, por ejemplo al final de una serie de inserciones, puede ser más sencillo colocar los valores en un list o vector para ordenar más tarde el resultado en el momento necesario.&lt;br /&gt;
&lt;br /&gt;
Si el orden en que se almacenan los valores en la estructura está relacionado con el orden de su inserción, entonces un stack, un queue o un list pueden ser la mejor elección.&lt;br /&gt;
|-&lt;br /&gt;
| Puede variar mucho el tamaño de la estructura de datos durante el curso de la ejecución del programa?&lt;br /&gt;
| Si es así, entonces puede ser que la mejor opción sean un list o un set. Un vector o un deque pueden conducir a mantener un gran almacenamiento intermedio (buffer); incluso después que los elementos hayan sido eliminados de la colección de datos. Estos dos contenedores no son adecuados para cambios de tamaño, aunque vector dispone de un mecanismo de inserción al final eficiente.&lt;br /&gt;
 &lt;br /&gt;
Recíprocamente: si el tamaño de la colección se mantiene relativamente estable, entonces un vector o un deque pueden utilizar menos memoria que un list o un set que almacenen el mismo número de elementos.&lt;br /&gt;
|-&lt;br /&gt;
| Es posible determinar el tamaño de la colección?&lt;br /&gt;
| La estructura de datos vector proporciona un medio para pre-seleccionar un bloque de memoria de un tamaño específico con la función miembro reserve, posibilidad que no existe en otros contenedores.&lt;br /&gt;
|-&lt;br /&gt;
| Es frecuente tener que comprobar si un valor cualquiera está incluido en la colección?&lt;br /&gt;
| En este caso, un contenedor set o map pueden ser buena elección. En estos casos comprobar si un determinado valor está incluido puede ser realizado con un pequeño número de pasos (logarítmicos con el tamaño del contenedor). Mientras que la misma verificación en cualquiera de los otros tipos puede requerir comparar el valor con cada elemento almacenado en el contenedor.&lt;br /&gt;
|-&lt;br /&gt;
| Está indexada la colección de datos? &lt;br /&gt;
| Si las claves son enteros entre 0 y un límite superior, pueden utilizarse un vector o un deque. &lt;br /&gt;
|-&lt;br /&gt;
| Si es así, puede ser vista la colección como una serie de pares clave/valor?&lt;br /&gt;
| Si la clave es algún otro valor, como cadenas de caracteres o tipos definidos por el usuario, puede utilizarse un contenedor map.&lt;br /&gt;
|-&lt;br /&gt;
| Pueden los valores estar relacionados unos con otros?&lt;br /&gt;
| Todos los valores almacenados en cualquier contenedor de la STL debe ser capaz de comprobar la igualdad con cualquier otro valor similar, pero recuerde que no todos son capaces de reconocer el operador de relación menor-que; sin embargo, si los valores no pueden ser ordenados utilizando el operador menor-que, no pueden ser almacenados en un set o en un map.&lt;br /&gt;
|-&lt;br /&gt;
| Es una operación frecuente tener que encontrar y eliminar el valor mayor de la colección?&lt;br /&gt;
| En caso afirmativo, la estructura de datos más idónea es el priority queue.&lt;br /&gt;
|-&lt;br /&gt;
| En que posiciones son insertados o eliminados los elementos de la estructura?&lt;br /&gt;
| Si los valores son añadidos o eliminados en la zona interior, entonces la mejor opción es un list.&lt;br /&gt;
 &lt;br /&gt;
Si los valores son insertados solo al comienzo, un deque o un list pueden ser lo más adecuado.&lt;br /&gt;
&lt;br /&gt;
Si los valores son insertados y eliminados solo al final, un stack o un queue pueden ser elecciones lógicas.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| Es frecuente tener que refundir dos o más secuencias en una sola?&lt;br /&gt;
| En caso afirmativo, puede considerarse que las mejores opciones son un set o un list, dependiendo que la colección deba o no ser mantenida en orden.&lt;br /&gt;
 &lt;br /&gt;
Refundir dos set es una operación muy eficiente.  Si la colección de datos no está ordenada, pero puede utilizarse la función miembro splice() de las list (que es muy eficiente), entonces es preferible este último tipo de contenedor, dado que esta operación no está contemplada en las demás formas.&lt;br /&gt;
|}&lt;br /&gt;
=== Tipos no incluidos ===&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] incluye contenedores adecuados para la mayoría de los casos prácticos, aunque quizás existen una serie de estructuras de datos clásicas que no han sido incluidas. En la mayoría de los casos, la causa es que los contenedores proporcionados pueden ser fácilmente adaptados para suplir los usos facilitados por los tipos omitidos.&lt;br /&gt;
&lt;br /&gt;
Tipos clásicos no incluidos y la sustitución más fácil.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Contenedor omitido&lt;br /&gt;
! Sustitución utilizando elementos de STL&lt;br /&gt;
|-&lt;br /&gt;
| tree&lt;br /&gt;
| El modo set está implementado internamente como un árbol de búsqueda binaria. &lt;br /&gt;
&lt;br /&gt;
Para la mayoría de los casos prácticos que pueden ser resueltos utilizando árboles este modo es un sustituto adecuado.&lt;br /&gt;
|-&lt;br /&gt;
| matrices multidimensionales&lt;br /&gt;
| Puesto que los vectores pueden almacenar elementos que sean otros vectores, estas estructuras pueden ser construidas fácilmente.&lt;br /&gt;
|-&lt;br /&gt;
| graph&lt;br /&gt;
| La representación de un gráfico puede ser fácilmente construida como un map que contiene otros map. Un map cuyos elementos son a su vez maps, es la representación natural de un gráfico directo. &lt;br /&gt;
|-&lt;br /&gt;
| sparse array&lt;br /&gt;
| Una novedosa sustitución es la representación de un gráfico&lt;br /&gt;
|-&lt;br /&gt;
| hash table&lt;br /&gt;
| Las tablas hash proporcionan un tiempo de acceso constante, así como inserción y borrado de elementos, convirtiendo estas operaciones en operaciones de índice.&lt;br /&gt;
 &lt;br /&gt;
Una tabla hash puede ser construida fácilmente como un vector (o deque) cuyos elementos son lists (o incluso sets).  En el ejemplo de la ordenación raíz (  xxx) se describe una de estas estructuras (un vector de deques), aunque en este ejemplo no incluye invocación la función hash para convertir un valor en un índice.&lt;br /&gt;
|-&lt;br /&gt;
| Funcionalidad set&lt;br /&gt;
| En la STL, los tipos set están específicamente ordenados, y sus operaciones (como la unión intersección, etc.) no pueden ser realizadas sobre colecciones de valores no ordenados (por ejemplo un conjunto de números complejos).&lt;br /&gt;
 &lt;br /&gt;
Una list puede ser utilizada como sustituto, aunque es necesario escribir funciones de operación especiales, dado que los algoritmos genéricos no pueden ser utilizados con listas.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Gestión de memoria ==&lt;br /&gt;
La gestión de memoria realizada por los contenedores comprende tanto la asignación y liberación de espacio para sus miembros, como para las claves que constituyen el sistema de índice de algunos tipos de contenedor. En general los algoritmos de la STL están muy optimizados y el sistema de asignación de memoria intenta compaginar rapidez y eficacia. La primera exige asignar y desasignar espacio cada vez que se introduce o elimina un miembro del contenedor. La eficacia, e incluso la disminución de la fragmentación inherentes al manejo del montón, exige asignar y rehusar trozos de memoria lo más grandes posible cada vez. El abordaje a este problema se ha realizado de dos formas básicas: (a) Contenedores que no pueden alterar su tamaño, de forma que la asignación de espacio para sus elementos debe realizarse en el momento de su declaración. (b) Contenedores que pueden crecer y/o disminuir en consonancia con los elementos a albergar.&lt;br /&gt;
&lt;br /&gt;
Refiriéndonos al caso (b), para balancear estas exigencias contrapuestas, algunas implementaciones utilizan el siguiente esquema de trabajo: inicialmente el sistema asigna al contenedor un trozo de memoria de tamaño adecuado para contener cierto número de elementos; espacio que es utilizando hasta que se agota. A partir de aquí, cada nueva demanda origina la asignación una zona de doble tamaño que la anterior. Por ejemplo, supongamos que para gestionar un vector de enteros, el compilador asigna inicialmente espacio para un máximo de 16 miembros.  Cuando se agotara, se realizaría una nueva asignación de espacio para 32 miembros, e inmediatamente se efectuaría una recolocación del contenido actual en el nuevo espacio y la liberación del primitivo. Si el nuevo contenedor quedara lleno de nuevo, la siguiente asignación sería capaz de 64 miembros y así sucesivamente.&lt;br /&gt;
&lt;br /&gt;
El factor de aumento de tamaño puede ser cualquiera. Muchos compiladores utilizan un factor 1.5 cada vez que deben ampliar el espacio necesario.&lt;br /&gt;
&lt;br /&gt;
Cada nueva recolocación implica varios pasos:&lt;br /&gt;
  •	Asignación de memoria al estilo malloc() de la librería clásica en cantidad suficiente para el nuevo tamaño.&lt;br /&gt;
  •	Copia de los elementos actuales en la nueva localización. Los elementos son colocados en la nueva situación utilizando el constructor copia.&lt;br /&gt;
  •	Actualización de las estructuras internas del nuevo contenedor (sistema de índices).&lt;br /&gt;
  •	Eliminación de los elementos originales mediante invocación sucesiva de sus correspondientes destructores.&lt;br /&gt;
  •	Liberación de la memoria utilizada por las estructuras internas.&lt;br /&gt;
  •	Liberación de la zona original mediante una invocación al estilo free de la librería clásica.&lt;br /&gt;
&lt;br /&gt;
En general, al referirse al tamaño de un contenedor existen tres magnitudes distintas aunque relacionadas, cuyos valores pueden obtenerse mediante tres métodos:&lt;br /&gt;
&lt;br /&gt;
  •	El número de elementos contenidos actualmente. size()&lt;br /&gt;
  •	El máximo número de elementos que pueden alcanzarse actualmente sin necesidad de una nueva recolocación. capacity()&lt;br /&gt;
  •	El máximo número de elementos que pueden alcanzarse en cualquier caso. max_size().&lt;br /&gt;
&lt;br /&gt;
 Ejemplo:&lt;br /&gt;
   #include &amp;lt;iostream&amp;gt;&lt;br /&gt;
   using namespace std;&lt;br /&gt;
   #include &amp;lt;vector&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   int main() {         // ================&lt;br /&gt;
   vector&amp;lt;int&amp;gt; vInt;&lt;br /&gt;
   for (int i=0; i &amp;lt; 100; i++) vInt.push_back(i);&lt;br /&gt;
&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Tamaño actual:   &amp;quot; &amp;lt;&amp;lt; vInt.size()     &amp;lt;&amp;lt; endl;&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Capacidad actual: &amp;quot; &amp;lt;&amp;lt; vInt.capacity() &amp;lt;&amp;lt; endl;&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Tamano maximo:   &amp;quot; &amp;lt;&amp;lt; vInt.max_size() &amp;lt;&amp;lt; endl;&lt;br /&gt;
   return 0;&lt;br /&gt;
   }&lt;br /&gt;
   Salida:&lt;br /&gt;
   Tamaño actual: 100&lt;br /&gt;
   Capacidad actual: 256&lt;br /&gt;
   Tamano maximo: 1073741823&lt;br /&gt;
&lt;br /&gt;
En todos los casos: size() &amp;lt;= capacity()&lt;br /&gt;
&lt;br /&gt;
Es posible comprobar si un contenedor está vacío, comparando su tamaño actual size() con cero, aunque es más rápido utilizar el método empty(), que devuelve true si realmente size() == 0.&lt;br /&gt;
&lt;br /&gt;
=== Reserva de espacio ===&lt;br /&gt;
Como puede suponer, cada recolocación supone un proceso considerable, sobre todo en contenedores muy grandes. Para evitar sus inconvenientes si se conoce de antemano el tamaño máximo a utilizar, la STL ofrece la posibilidad de preasignar un espacio arbitrario. Para esto se dispone del método reserve(n), que garantiza la asignación de espacio inicial suficiente para alojar n miembros en el contenedor. Si el argumento n es mayor que la capacidad actual, se produce una recolocación y el nuevo argumento determina la nueva capacidad. Si es menor no se produce ninguna acción.&lt;br /&gt;
&lt;br /&gt;
Ejemplo, para crear un vector de enteros capaz para al menos 1000 miembros:&lt;br /&gt;
  vector &amp;lt;int&amp;gt; v;&lt;br /&gt;
  v.reserve(1000);&lt;br /&gt;
&lt;br /&gt;
En el siguiente ejemplo se muestran los resultados compilado con Borland C++ 5.5 para Win32; con MS Visual C++ 6.0 y con GNU gcc 2.95.3 para Linux:&lt;br /&gt;
  // resultados con:         BC++   VC++   GNU   &lt;br /&gt;
  vector&amp;lt;int&amp;gt; v;&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 0      0      0   &lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 0      0      0&lt;br /&gt;
  v.push_back(3);&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    1      1&lt;br /&gt;
  v.reserve(100);&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    100    100&lt;br /&gt;
&lt;br /&gt;
=== Operaciones sobre contenedores ===&lt;br /&gt;
Los elementos de un contenedor son colocados en él utilizando el constructor copia, aunque algunas operaciones requieren la existencia de un constructor por defecto. A su vez, los algoritmos genéricos, como copy(), que copian a un contenedor, utilizan el operador de asignación.&lt;br /&gt;
&lt;br /&gt;
Cuando se duplica todo un contenedor de tipos T por invocación del [[Constructor (C++)|constructor]] copia o por asignación, cada miembro es copiado en la nueva estructura utilizando el constructor copia o el operador de asignación. Tanto si una copia profunda o una copia somera, el resultado es controlado por el programador, que puede proporcionar el operador de asignación para el tipo T con cualquier significado que desee. Si se ha definido un destructor para el tipo T, este destructor es invocado cada vez que deba ser eliminado un elemento del contenedor. Cuando se destruye toda la colección, el destructor es invocado por cada elemento que permaneciera almacenado.&lt;br /&gt;
&lt;br /&gt;
En estos casos, el contenedor es solamente responsable de mantener los propios punteros, siendo responsabilidad del programador manejar la memoria de los valores referenciados por estos, lo que supone que los espacios de memoria son asignados correctamente; por lo general mediante el operador new; que no son desasignados mientras el contenedor albergue referencias a ellos, y que sean adecuadamente desasignados una vez que han sido eliminados del contenedor.&lt;br /&gt;
&lt;br /&gt;
===  Secuencias ===&lt;br /&gt;
Las secuencias son estructuras de datos de tipo lineal, con posibilidad de que su tamaño puede ser alterado insertando elementos al principio, al final o en cualquier posición, si bien la idoneidad en este sentido es distinta entre los diversos tipos.&lt;br /&gt;
&lt;br /&gt;
La STL ofrece los siguientes:&lt;br /&gt;
  • deque&lt;br /&gt;
  • list&lt;br /&gt;
  • stack&lt;br /&gt;
  • vector&lt;br /&gt;
  • vector&amp;lt;bool&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La estructura lineal implica que sus datos son lógicamente contiguos, aunque su disposición física puede que no lo sea. Los elementos pueden ser accedidos por un índice numérico, aunque en algunos tipos de secuencia el acceso a un elemento implica un recorrido por la lista.&lt;br /&gt;
&lt;br /&gt;
== Contenedores asociativos ==&lt;br /&gt;
Los contenedores asociativos son una extensión de las secuencias. Mientras que en estas para acceder a los elementos solo pueden utilizarse claves numéricas, que señalan el número de orden del elemento dentro de la secuencia (al estilo de los índices en las matrices). Los contenedores asociativos admiten cualquier tipo de clave de acceso. Las más frecuentes son las cadenas alfanuméricas (stings).&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, razón por la que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.&lt;br /&gt;
&lt;br /&gt;
La ordenación se realiza según los valores de ciertos miembros del contenedor. Estos elementos son denominados &amp;quot;de claves&amp;quot; (&amp;quot;Key values&amp;quot;). Lo que exige que los objetos &amp;quot;de clave&amp;quot; sean de un tipo para el que estén definidos los operadores relacionales. El contenedor es mantenido ordenado de forma automática por los algoritmos de inserción y borrado.&lt;br /&gt;
&lt;br /&gt;
La STL proporciona cinco tipo distintos, aunque en realidad son tres clases; dos de ellas en dos variedades (permitiendo o no claves duplicadas). Uno de los tipos (bitset) sirve para almacenar campos de bits de longitud constante. Los otros dos permiten elementos ordenados de cualquier tipo (set y multiset), mientras que map y multimap permiten alojar pares de elementos. Uno que actúa como &amp;quot;Key value&amp;quot; y otro que puede ser un tipo cualquiera al que llamaremos valor-dato.&lt;br /&gt;
&lt;br /&gt;
  • bitset&lt;br /&gt;
  • set&lt;br /&gt;
  • multiset&lt;br /&gt;
  • map&lt;br /&gt;
  • multimap&lt;br /&gt;
&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave, y para recorrer el conjunto (ordenado) de las claves.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http://www.zator.com/Cpp/E5_1_1.htm Contenerores C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Contenedores en C.conclase.net]&lt;br /&gt;
* [https://docs.microsoft.com/es-es/cpp/standard-library/stl-containers?view=vs-2017  Contenedores de la biblioteca estándar de C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234216</id>
		<title>Contenedores C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234216"/>
		<updated>2018-11-29T18:12:39Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Contenedores C++ |imagen=  |concepto= En sentido C++ estricto, un contenedor de la STL es una clase genérica que puede instanciarse para representar diversos tipos de objetos. Esta clase incluye ciertas operaciones  sobre los objetos de su tipo; estas operaciones están representadas por funciones-miembro, incluyendo constructores y funciones-operador, que son a su vez funciones genéricas}}''' Contenedores C++ '''. Al mismo tiempo, desde el punto de vista de las teorías de la información, podemos considerarlos estructuras de datos más o menos adecuadas (según el caso) para aplicarles ciertos algoritmos.&lt;br /&gt;
De su propio nombre (&amp;quot;Containers&amp;quot;) podemos deducir que su misión principal, y razón de su existencia, es su función como estructuras de datos, y en este sentido podemos adelantar que entre sus funcionalidades más destacadas se encuentran la gestión del espacio de almacenamiento necesario.&lt;br /&gt;
Una de las primerísimas ventajas de la utilización de contenedores es que el programador no tiene que enredarse con las cuestiones siempre espinosas de asignar o liberar memoria para los objetos creados, de forma que queda liberado de los [[Operadores|operadores]] [[Operador new|new]] y [[Operador delete|delete]].&lt;br /&gt;
== Filosofía de uso ==&lt;br /&gt;
Una primera pincelada sobre la filosofía de uso de los contenedores mediante un sencillo ejemplo: si tenemos que manejar un conjunto de enteros, puede utilizarse una matriz de enteros, pero ya hemos señalado  que esta estructura nos obliga a conocer de antemano la cantidad de datos a almacenar (el tamaño de la matriz). En consecuencia, si el número de datos puede variar, esta opción no es muy adecuada. Además, si es importante mantener los datos ordenados, la utilización de una matriz nos obligaría a ingeniar por nuestra cuenta la forma de hacerlo; seguramente mediante complicadas rutinas de &amp;quot;sort&amp;quot; hechas manualmente.&lt;br /&gt;
&lt;br /&gt;
Una alternativa es utilizar como &amp;quot;contenedor&amp;quot; para nuestros enteros una clase genérica de la STL denominada vector. En este caso, serían posibles expresiones como las siguientes:&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;int&amp;gt; v(3);         // L1:&lt;br /&gt;
v[0] = 7;                 // L2:&lt;br /&gt;
v[1] = v[0] + 1;          // L3:&lt;br /&gt;
v[2] = v[0] + v[1];       // L4:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Al encontrar la primera sentencia, el compilador crea una instancia (especialidad) anónima de la plantilla vector para alojar enteros; a continuación una instancia de ella para alojar tres enteros, a la que denominamos v.&lt;br /&gt;
&lt;br /&gt;
Una primera inspección de las sentencias L2 a L3, nos muestra que la clase ofrece la posibilidad de utilizar con sus miembros el operador subíndice de matriz [ ]. Deducimos por tanto, que dispone de una versión sobrecargada de este operador para los miembros de la clase, lo que nos permite utilizar el objeto v como una matriz, aunque con algunas funcionalidades no incluidas en aquellas.&lt;br /&gt;
&lt;br /&gt;
Después de L4 los valores finales para los miembros de nuestra &amp;quot;matriz&amp;quot; serian:&lt;br /&gt;
 v[0] == 7, v[1] == 8, v[2] == 15&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Si deseamos invertir el orden de los elementos de nuestra matriz. Para ello utilizamos una [[Función (programación)|función]] especial:&lt;br /&gt;
 reverse(v.begin(), v.end());&lt;br /&gt;
después de lo cual, el orden de miembros sería:&lt;br /&gt;
 v[0] == 15, v[1] == 8, v[2] == 7&lt;br /&gt;
&lt;br /&gt;
La primera observación es que la función reverse utiliza dos argumentos, que son a su vez el valor devuelto por sendos métodos de clase (los aplicamos sobre nuestro objeto v).  El valor devuelto por estos métodos es lo que se conoce como un [[Iteradores (Programación)|iterador]]; una especie de puntero que señalan al interior de la estructura de datos representada por el contenedor v. En este caso, el primer iterador señala al primer miembro y el segundo a una posición después del último; de esta forma se indican los miembros inicial y final entre los que se realizará la operación de inversión efectuada por reverse.&lt;br /&gt;
&lt;br /&gt;
La segunda observación es que la función reverse no es un método de clase, sino una función global; es lo que denominamos un [[Algoritmo|algoritmo]]. Esta función tiene la peculiaridad de que puede ser aplicado sobre el contenedor vector (y algún otro); que opera sobre un rango de los elementos del contenedor, en nuestro caso sobre la totalidad (esta capacidad de operar sobre una parte de un contenedor es característica de los algoritmos). También que pueden operar sobre otros contenedores produciendo un efecto similar. Por ejemplo, el algoritmo reverse puede operar incluso sobre una simple matriz:&lt;br /&gt;
 char Ch[5] = { 'A', 'E', 'I', 'O', 'U' };&lt;br /&gt;
 reverse(Ch, Ch + 5);&lt;br /&gt;
 for (int i = 0; i &amp;lt; 5; ++i) cout &amp;lt;&amp;lt; &amp;quot;Ch[&amp;quot; &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &amp;quot;] = &amp;quot; &amp;lt;&amp;lt; Ch[i];&lt;br /&gt;
 Salida:&lt;br /&gt;
 Ch[0] = U Ch[1] = O Ch[2] = I Ch[3] = E Ch[4] = A&lt;br /&gt;
&lt;br /&gt;
Es significativo que el objeto v es una estructura de datos que permite acceder individualmente a sus miembros &amp;quot;como si&amp;quot; fuesen elementos de una matriz. También que se pueden aplicar ciertas operaciones sobre la totalidad, o parte, de esta estructura considerada como una unidad.&lt;br /&gt;
== Clasificación ==&lt;br /&gt;
Existen dos tipos de contenedores: secuencias y asociativos; a su vez se subdividen según el tipo de [[Iteradores (Programación)|iterador]] que soportan.&lt;br /&gt;
&lt;br /&gt;
Las secuencias almacenan los elementos en orden secuencial (de ahí su nombre). El contenedor agrupa a todos sus miembros como una sucesión lineal, y en consecuencia son adecuadas para accesos directos y secuenciales. Un ejemplo de secuencia es una matriz. De hecho, los algoritmos que pueden aplicarse a las secuencias pueden aplicarse también a las matrices.&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, por lo que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.  La STL proporciona cinco tipos distintos.&lt;br /&gt;
&lt;br /&gt;
La existencia de índices supone una ordenación según los valores de un conjunto de elementos (denominado &amp;quot;de claves&amp;quot;) para el que debe existir un criterio de ordenación. Dicho en otras palabras, los objetos &amp;quot;de clave&amp;quot; deben ser de un tipo para el que estén definidos los operadores relacionales. El árbol es mantenido ordenado de forma automática por los algoritmos de inserción y borrado del contenedor.&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave y para recorrer el conjunto (ordenado) de los elementos.&lt;br /&gt;
&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] contiene diez formas de contenedores y tres adaptadores de contenedor (denominados simplemente [[Adapter|adaptadores]]). En esta sección se expondrán brevemente cuales son estas formas; sus características, y cuál es la más adecuada para cada tipo de problema específico. En secciones sucesivas se comentarán individualmente con mayor detalle.&lt;br /&gt;
Relación siguiendo la clasificación utilizada en el Estándar:&lt;br /&gt;
  •	Secuencias&lt;br /&gt;
      o	deque&lt;br /&gt;
      o	list&lt;br /&gt;
      o	stack&lt;br /&gt;
      o	vector&lt;br /&gt;
      o	vector &amp;lt;bool&amp;gt;&lt;br /&gt;
  •	adaptadores&lt;br /&gt;
      o	queue&lt;br /&gt;
      o	priority_queue&lt;br /&gt;
  •	Contenedores asociativos&lt;br /&gt;
      o	map&lt;br /&gt;
      o	multimap&lt;br /&gt;
      o	set&lt;br /&gt;
      o	multiset&lt;br /&gt;
      o	bitset&lt;br /&gt;
== Características ==&lt;br /&gt;
Las características más significativas de las diversas formas de contenedor son:&lt;br /&gt;
&lt;br /&gt;
Contenedor	Características&lt;br /&gt;
&lt;br /&gt;
Secuencias&lt;br /&gt;
&lt;br /&gt;
 vector: Este contenedor es una estructura de datos de tamaño fijo preferentemente. Aunque la STL proporciona herramientas para cambiar el tamaño de un vector de forma dinámica, esta operación es costosa y debe ser evitada dentro de lo posible (en este sentido el vector se comporta como una matriz ordinaria). &lt;br /&gt;
&lt;br /&gt;
Disponen de un buén mecanismo de acceso aleatorio a elementos y de un mecanismo de inserción al final muy eficiente.&lt;br /&gt;
Generalmente es preferible utilizar un vector que un deque o un list, a menos que sea frecuentemente necesario insertar datos al comienzo o al final, en cuyo caso es mejor utilizar un deque.  Si por el contrario es frecuente la inserción de elementos en el centro, entonces es preferible un list.&lt;br /&gt;
&lt;br /&gt;
 vector&amp;lt;bool&amp;gt;:	Es una versión de la anterior especial para valores binarios (bits).&lt;br /&gt;
&lt;br /&gt;
 list: Este contenedor responde a la idéa intuitiva de &amp;quot;lista&amp;quot;, el almacenamiento de objetos en una secuencia lineal que no está necesariamente ordenada (aunque sus miembros pueden ser ordenados fácilmente mediante la función-miembro sort() ). Estos contenedores suelen ser implementados como listas doblemente enlazadas. &lt;br /&gt;
&lt;br /&gt;
Dispone de mecanismos eficientes para insertar elementos al principio, al final o en cualquier posición (utilizando iteradores que denoten posición). Estas operaciones consumen un tiempo constante con independencia del número de elmentos albergados en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Dado que son estructuras lineales, en general los elementos no pueden ser accedidos por subíndices como en un vector.  Es necesario realizar un recorrido lineal por todos los valores, por lo que en las operaciones de acceso se utilizan tiempos proporcionales al número de elementos.&lt;br /&gt;
&lt;br /&gt;
 stack: Contenedor de elementos tipo pila LIFO que permite inserciones y eliminaciones solo en la parte superior.&lt;br /&gt;
&lt;br /&gt;
 deque: Los deques o colas de doble terminación (&amp;quot;Double-ended queue&amp;quot;) son un tipo de estructura de datos que comparte las características de las colas (&amp;quot;Queues&amp;quot;) y las pilas (&amp;quot;Stacks&amp;quot;). Como en las colas , los elementos pueden ser empujados por un extremo al interior del contenedor, y el primer elemento introducido puede ser extraído por el extremo opuesto. Al mismo tiempo, el último elemento introducido por el principio puede ser extraído en ese mismo extremo como si fuese una pila.&lt;br /&gt;
 &lt;br /&gt;
Estos contenedores suelen ser implementados bajo la forma de matrices bidimensionales.&lt;br /&gt;
&lt;br /&gt;
Las características de los deques implementados en la STL pueden resumirse en: Acceso aleatorio; mecanismo eficiente de inserción al principio o al final.&lt;br /&gt;
&lt;br /&gt;
 string: Contenedor de caracteres adaptado a operaciones con cadenas de caracteres.&lt;br /&gt;
&lt;br /&gt;
Asociaciones&lt;br /&gt;
&lt;br /&gt;
 set: Como el resto de contenedores asociativos, esta forma de contenedor mantiene los elementos en orden. Dispone de mecanismos eficientes para inclusión, inserción y eliminación de elementos, y soporta claves únicas (solo puede existir un miembro con una clave determinada).&lt;br /&gt;
&lt;br /&gt;
 multiset: Versión del anterior que permite la existencia de claves duplicadas. Es decir, distintos elementos dentro del conjunto pueden responder a la misma clave.&lt;br /&gt;
&lt;br /&gt;
 bitset: Contenedor de bit más orientado al tamaño que hacia el tipo de contenido. Permite almacenar secuencias de bits de tamaño fijo. No existen iteradores para reccorrerlas, y sus elementos se acceden utilizando el operador subíndice.&lt;br /&gt;
 &lt;br /&gt;
Se dispone de varias funciones para realizar con ellos operaciones de bits.&lt;br /&gt;
 &lt;br /&gt;
 map: Como el resto de estructuras asociativas, el map mantiene sus elementos ordenados. Se caracteriza porque sus miembros son pares de valores que pueden ser de tipos distintos. Uno de ellos, el que actúa como clave para el índice (&amp;quot;Key-value&amp;quot;), puede ser de cualquier tipo, a condición de que sus elementos puedan ser ordenados según un criterio (por defecto se utiliza el operador &amp;lt;).&lt;br /&gt;
 &lt;br /&gt;
Permite claves únicas. Es decir, que solo puede existir un miembro para cada clave. Dispone de mecanismos de inserción y borrado muy eficientes y no existe límite de tamaño. La estructura se encarga de crecer y disminuir en concordancia con las necesidades de sus miembros. Permite el operador [ ] subíndice para los elementos de la clave así como otras técnicas de acceso.&lt;br /&gt;
&lt;br /&gt;
Estas estructuras de datos recibe también los nombres de diccionarios, tablas y matrices asociativas, en referencia a que pueden considerarse como dos matrices del mismo número de elementos, en las que existe una relación entre cada miembro de una con otro miembro de la otra.  Una de las matrices (que actúa de índice) estaría ordenada según su contenido.&lt;br /&gt;
&lt;br /&gt;
 multimap: En todo igual que el anterior pero permitiendo además claves duplicadas. Es decir, que una misma clave pueda estar asociada a dos &amp;quot;valores&amp;quot; distintos.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Adaptador	Características&lt;br /&gt;
&lt;br /&gt;
 queue: Contenedor tipo cola FIFO que permite inserciones al final y eliminaciones al principio.&lt;br /&gt;
&lt;br /&gt;
 priority queue: Este contenedor dispone de mecanismos eficientes para acceso y eliminación de grandes valores.&lt;br /&gt;
&lt;br /&gt;
== Seleccionar un contenedor ==&lt;br /&gt;
El binomio contendor-iterador conforma una herramienta que se adapta a circunstancias muy variadas. Es posible que un determinado problema pueda ser abordado de varias formas, en estos casos la selección de la forma de contenedor más adecuado depende de las circunstancias. En ciertas ocasiones puede resultar bastante obvia; en otras puede no estar tan claro cuál es la mejor opción, pues &amp;quot;a priori&amp;quot;, pueden adaptarse varias formas al caso concreto. Puede utilizarse el sistema de prueba y comparación. Por ejemplo, cronometrando los resultados obtenidos en un modo u otro. También será de gran ayuda la experiencia, pero como una guía o criterio general puede utilizarse el principio de selección que se indica a continuación.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Como se accederá a los datos?.&lt;br /&gt;
| Si es importante un acceso aleatorio, pueden utilizarse un vector o un deque. Si basta con un acceso secuencial cualquiera de los dos puede ser el elegido.&lt;br /&gt;
|-&lt;br /&gt;
| Es importante el orden en que serán mantenidos los valores dentro de la colección de datos?&lt;br /&gt;
| Existen muchas formas de secuenciar los valores. Si es importante un orden estricto a lo largo de toda la vida del contenedor, la elección obvia es un set, dado que las inserciones en una de estas estructuras se realizan automáticamente en orden.&lt;br /&gt;
 &lt;br /&gt;
Si este orden es importante solo en algún momento, por ejemplo al final de una serie de inserciones, puede ser más sencillo colocar los valores en un list o vector para ordenar más tarde el resultado en el momento necesario.&lt;br /&gt;
&lt;br /&gt;
Si el orden en que se almacenan los valores en la estructura está relacionado con el orden de su inserción, entonces un stack, un queue o un list pueden ser la mejor elección.&lt;br /&gt;
|-&lt;br /&gt;
| Puede variar mucho el tamaño de la estructura de datos durante el curso de la ejecución del programa?&lt;br /&gt;
| Si es así, entonces puede ser que la mejor opción sean un list o un set. Un vector o un deque pueden conducir a mantener un gran almacenamiento intermedio (buffer); incluso después que los elementos hayan sido eliminados de la colección de datos. Estos dos contenedores no son adecuados para cambios de tamaño, aunque vector dispone de un mecanismo de inserción al final eficiente.&lt;br /&gt;
 &lt;br /&gt;
Recíprocamente: si el tamaño de la colección se mantiene relativamente estable, entonces un vector o un deque pueden utilizar menos memoria que un list o un set que almacenen el mismo número de elementos.&lt;br /&gt;
|-&lt;br /&gt;
| Es posible determinar el tamaño de la colección?&lt;br /&gt;
| La estructura de datos vector proporciona un medio para pre-seleccionar un bloque de memoria de un tamaño específico con la función miembro reserve, posibilidad que no existe en otros contenedores.&lt;br /&gt;
|-&lt;br /&gt;
| Es frecuente tener que comprobar si un valor cualquiera está incluido en la colección?&lt;br /&gt;
| En este caso, un contenedor set o map pueden ser buena elección. En estos casos comprobar si un determinado valor está incluido puede ser realizado con un pequeño número de pasos (logarítmicos con el tamaño del contenedor). Mientras que la misma verificación en cualquiera de los otros tipos puede requerir comparar el valor con cada elemento almacenado en el contenedor.&lt;br /&gt;
|-&lt;br /&gt;
| Está indexada la colección de datos? &lt;br /&gt;
| Si las claves son enteros entre 0 y un límite superior, pueden utilizarse un vector o un deque. &lt;br /&gt;
|-&lt;br /&gt;
| Si es así, puede ser vista la colección como una serie de pares clave/valor?&lt;br /&gt;
| Si la clave es algún otro valor, como cadenas de caracteres o tipos definidos por el usuario, puede utilizarse un contenedor map.&lt;br /&gt;
|-&lt;br /&gt;
| Pueden los valores estar relacionados unos con otros?&lt;br /&gt;
| Todos los valores almacenados en cualquier contenedor de la STL debe ser capaz de comprobar la igualdad con cualquier otro valor similar, pero recuerde que no todos son capaces de reconocer el operador de relación menor-que; sin embargo, si los valores no pueden ser ordenados utilizando el operador menor-que, no pueden ser almacenados en un set o en un map.&lt;br /&gt;
|-&lt;br /&gt;
| Es una operación frecuente tener que encontrar y eliminar el valor mayor de la colección?&lt;br /&gt;
| En caso afirmativo, la estructura de datos más idónea es el priority queue.&lt;br /&gt;
|-&lt;br /&gt;
| En que posiciones son insertados o eliminados los elementos de la estructura?&lt;br /&gt;
| Si los valores son añadidos o eliminados en la zona interior, entonces la mejor opción es un list.&lt;br /&gt;
 &lt;br /&gt;
Si los valores son insertados solo al comienzo, un deque o un list pueden ser lo más adecuado.&lt;br /&gt;
&lt;br /&gt;
Si los valores son insertados y eliminados solo al final, un stack o un queue pueden ser elecciones lógicas.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| Es frecuente tener que refundir dos o más secuencias en una sola?&lt;br /&gt;
| En caso afirmativo, puede considerarse que las mejores opciones son un set o un list, dependiendo que la colección deba o no ser mantenida en orden.&lt;br /&gt;
 &lt;br /&gt;
Refundir dos set es una operación muy eficiente.  Si la colección de datos no está ordenada, pero puede utilizarse la función miembro splice() de las list (que es muy eficiente), entonces es preferible este último tipo de contenedor, dado que esta operación no está contemplada en las demás formas.&lt;br /&gt;
|}&lt;br /&gt;
=== Tipos no incluidos ===&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] incluye contenedores adecuados para la mayoría de los casos prácticos, aunque quizás existen una serie de estructuras de datos clásicas que no han sido incluidas. En la mayoría de los casos, la causa es que los contenedores proporcionados pueden ser fácilmente adaptados para suplir los usos facilitados por los tipos omitidos.&lt;br /&gt;
&lt;br /&gt;
Tipos clásicos no incluidos y la sustitución más fácil.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Contenedor omitido&lt;br /&gt;
! Sustitución utilizando elementos de STL&lt;br /&gt;
|-&lt;br /&gt;
| tree&lt;br /&gt;
| El modo set está implementado internamente como un árbol de búsqueda binaria. &lt;br /&gt;
&lt;br /&gt;
Para la mayoría de los casos prácticos que pueden ser resueltos utilizando árboles este modo es un sustituto adecuado.&lt;br /&gt;
|-&lt;br /&gt;
| matrices multidimensionales&lt;br /&gt;
| Puesto que los vectores pueden almacenar elementos que sean otros vectores, estas estructuras pueden ser construidas fácilmente.&lt;br /&gt;
|-&lt;br /&gt;
| graph&lt;br /&gt;
| La representación de un gráfico puede ser fácilmente construida como un map que contiene otros map. Un map cuyos elementos son a su vez maps, es la representación natural de un gráfico directo. &lt;br /&gt;
|-&lt;br /&gt;
| sparse array&lt;br /&gt;
| Una novedosa sustitución es la representación de un gráfico&lt;br /&gt;
|-&lt;br /&gt;
| hash table&lt;br /&gt;
| Las tablas hash proporcionan un tiempo de acceso constante, así como inserción y borrado de elementos, convirtiendo estas operaciones en operaciones de índice.&lt;br /&gt;
 &lt;br /&gt;
Una tabla hash puede ser construida fácilmente como un vector (o deque) cuyos elementos son lists (o incluso sets).  En el ejemplo de la ordenación raíz (  xxx) se describe una de estas estructuras (un vector de deques), aunque en este ejemplo no incluye invocación la función hash para convertir un valor en un índice.&lt;br /&gt;
|-&lt;br /&gt;
| Funcionalidad set&lt;br /&gt;
| En la STL, los tipos set están específicamente ordenados, y sus operaciones (como la unión intersección, etc.) no pueden ser realizadas sobre colecciones de valores no ordenados (por ejemplo un conjunto de números complejos).&lt;br /&gt;
 &lt;br /&gt;
Una list puede ser utilizada como sustituto, aunque es necesario escribir funciones de operación especiales, dado que los algoritmos genéricos no pueden ser utilizados con listas.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Gestión de memoria ==&lt;br /&gt;
La gestión de memoria realizada por los contenedores comprende tanto la asignación y liberación de espacio para sus miembros, como para las claves que constituyen el sistema de índice de algunos tipos de contenedor. En general los algoritmos de la STL están muy optimizados y el sistema de asignación de memoria intenta compaginar rapidez y eficacia. La primera exige asignar y desasignar espacio cada vez que se introduce o elimina un miembro del contenedor. La eficacia, e incluso la disminución de la fragmentación inherentes al manejo del montón, exige asignar y rehusar trozos de memoria lo más grandes posible cada vez. El abordaje a este problema se ha realizado de dos formas básicas: (a) Contenedores que no pueden alterar su tamaño, de forma que la asignación de espacio para sus elementos debe realizarse en el momento de su declaración. (b) Contenedores que pueden crecer y/o disminuir en consonancia con los elementos a albergar.&lt;br /&gt;
&lt;br /&gt;
Refiriéndonos al caso (b), para balancear estas exigencias contrapuestas, algunas implementaciones utilizan el siguiente esquema de trabajo: inicialmente el sistema asigna al contenedor un trozo de memoria de tamaño adecuado para contener cierto número de elementos; espacio que es utilizando hasta que se agota. A partir de aquí, cada nueva demanda origina la asignación una zona de doble tamaño que la anterior. Por ejemplo, supongamos que para gestionar un vector de enteros, el compilador asigna inicialmente espacio para un máximo de 16 miembros.  Cuando se agotara, se realizaría una nueva asignación de espacio para 32 miembros, e inmediatamente se efectuaría una recolocación del contenido actual en el nuevo espacio y la liberación del primitivo. Si el nuevo contenedor quedara lleno de nuevo, la siguiente asignación sería capaz de 64 miembros y así sucesivamente.&lt;br /&gt;
&lt;br /&gt;
El factor de aumento de tamaño puede ser cualquiera. Muchos compiladores utilizan un factor 1.5 cada vez que deben ampliar el espacio necesario.&lt;br /&gt;
&lt;br /&gt;
Cada nueva recolocación implica varios pasos:&lt;br /&gt;
  •	Asignación de memoria al estilo malloc() de la librería clásica en cantidad suficiente para el nuevo tamaño.&lt;br /&gt;
  •	Copia de los elementos actuales en la nueva localización. Los elementos son colocados en la nueva situación utilizando el constructor copia.&lt;br /&gt;
  •	Actualización de las estructuras internas del nuevo contenedor (sistema de índices).&lt;br /&gt;
  •	Eliminación de los elementos originales mediante invocación sucesiva de sus correspondientes destructores.&lt;br /&gt;
  •	Liberación de la memoria utilizada por las estructuras internas.&lt;br /&gt;
  •	Liberación de la zona original mediante una invocación al estilo free de la librería clásica.&lt;br /&gt;
&lt;br /&gt;
En general, al referirse al tamaño de un contenedor existen tres magnitudes distintas aunque relacionadas, cuyos valores pueden obtenerse mediante tres métodos:&lt;br /&gt;
&lt;br /&gt;
  •	El número de elementos contenidos actualmente. size()&lt;br /&gt;
  •	El máximo número de elementos que pueden alcanzarse actualmente sin necesidad de una nueva recolocación. capacity()&lt;br /&gt;
  •	El máximo número de elementos que pueden alcanzarse en cualquier caso. max_size().&lt;br /&gt;
&lt;br /&gt;
 Ejemplo:&lt;br /&gt;
   #include &amp;lt;iostream&amp;gt;&lt;br /&gt;
   using namespace std;&lt;br /&gt;
   #include &amp;lt;vector&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   int main() {         // ================&lt;br /&gt;
   vector&amp;lt;int&amp;gt; vInt;&lt;br /&gt;
   for (int i=0; i &amp;lt; 100; i++) vInt.push_back(i);&lt;br /&gt;
&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Tamaño actual:   &amp;quot; &amp;lt;&amp;lt; vInt.size()     &amp;lt;&amp;lt; endl;&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Capacidad actual: &amp;quot; &amp;lt;&amp;lt; vInt.capacity() &amp;lt;&amp;lt; endl;&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Tamano maximo:   &amp;quot; &amp;lt;&amp;lt; vInt.max_size() &amp;lt;&amp;lt; endl;&lt;br /&gt;
   return 0;&lt;br /&gt;
   }&lt;br /&gt;
   Salida:&lt;br /&gt;
   Tamaño actual: 100&lt;br /&gt;
   Capacidad actual: 256&lt;br /&gt;
   Tamano maximo: 1073741823&lt;br /&gt;
&lt;br /&gt;
En todos los casos: size() &amp;lt;= capacity()&lt;br /&gt;
&lt;br /&gt;
Es posible comprobar si un contenedor está vacío, comparando su tamaño actual size() con cero, aunque es más rápido utilizar el método empty(), que devuelve true si realmente size() == 0.&lt;br /&gt;
&lt;br /&gt;
=== Reserva de espacio ===&lt;br /&gt;
Como puede suponer, cada recolocación supone un proceso considerable, sobre todo en contenedores muy grandes. Para evitar sus inconvenientes si se conoce de antemano el tamaño máximo a utilizar, la STL ofrece la posibilidad de preasignar un espacio arbitrario. Para esto se dispone del método reserve(n), que garantiza la asignación de espacio inicial suficiente para alojar n miembros en el contenedor. Si el argumento n es mayor que la capacidad actual, se produce una recolocación y el nuevo argumento determina la nueva capacidad. Si es menor no se produce ninguna acción.&lt;br /&gt;
&lt;br /&gt;
Ejemplo, para crear un vector de enteros capaz para al menos 1000 miembros:&lt;br /&gt;
  vector &amp;lt;int&amp;gt; v;&lt;br /&gt;
  v.reserve(1000);&lt;br /&gt;
&lt;br /&gt;
En el siguiente ejemplo se muestran los resultados compilado con Borland C++ 5.5 para Win32; con MS Visual C++ 6.0 y con GNU gcc 2.95.3 para Linux:&lt;br /&gt;
  // resultados con:         BC++   VC++   GNU   &lt;br /&gt;
  vector&amp;lt;int&amp;gt; v;&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 0      0      0   &lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 0      0      0&lt;br /&gt;
  v.push_back(3);&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    1      1&lt;br /&gt;
  v.reserve(100);&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
  cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    100    100&lt;br /&gt;
&lt;br /&gt;
=== Operaciones sobre contenedores ===&lt;br /&gt;
Los elementos de un contenedor son colocados en él utilizando el constructor copia, aunque algunas operaciones requieren la existencia de un constructor por defecto. A su vez, los algoritmos genéricos, como copy(), que copian a un contenedor, utilizan el operador de asignación.&lt;br /&gt;
&lt;br /&gt;
Cuando se duplica todo un contenedor de tipos T por invocación del [[Constructor (C++)|constructor]] copia o por asignación, cada miembro es copiado en la nueva estructura utilizando el constructor copia o el operador de asignación. Tanto si una copia profunda o una copia somera, el resultado es controlado por el programador, que puede proporcionar el operador de asignación para el tipo T con cualquier significado que desee. Si se ha definido un destructor para el tipo T, este destructor es invocado cada vez que deba ser eliminado un elemento del contenedor. Cuando se destruye toda la colección, el destructor es invocado por cada elemento que permaneciera almacenado.&lt;br /&gt;
&lt;br /&gt;
En estos casos, el contenedor es solamente responsable de mantener los propios punteros, siendo responsabilidad del programador manejar la memoria de los valores referenciados por estos, lo que supone que los espacios de memoria son asignados correctamente; por lo general mediante el operador new; que no son desasignados mientras el contenedor albergue referencias a ellos, y que sean adecuadamente desasignados una vez que han sido eliminados del contenedor.&lt;br /&gt;
&lt;br /&gt;
===  Secuencias ===&lt;br /&gt;
Las secuencias son estructuras de datos de tipo lineal, con posibilidad de que su tamaño puede ser alterado insertando elementos al principio, al final o en cualquier posición, si bien la idoneidad en este sentido es distinta entre los diversos tipos.&lt;br /&gt;
&lt;br /&gt;
La STL ofrece los siguientes:&lt;br /&gt;
  • deque&lt;br /&gt;
  • list&lt;br /&gt;
  • stack&lt;br /&gt;
  • vector&lt;br /&gt;
  • vector&amp;lt;bool&amp;gt;&lt;br /&gt;
&lt;br /&gt;
La estructura lineal implica que sus datos son lógicamente contiguos, aunque su disposición física puede que no lo sea. Los elementos pueden ser accedidos por un índice numérico, aunque en algunos tipos de secuencia el acceso a un elemento implica un recorrido por la lista.&lt;br /&gt;
&lt;br /&gt;
== Contenedores asociativos ==&lt;br /&gt;
Los contenedores asociativos son una extensión de las secuencias. Mientras que en estas para acceder a los elementos solo pueden utilizarse claves numéricas, que señalan el número de orden del elemento dentro de la secuencia (al estilo de los índices en las matrices). Los contenedores asociativos admiten cualquier tipo de clave de acceso. Las más frecuentes son las cadenas alfanuméricas (stings).&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, razón por la que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.&lt;br /&gt;
&lt;br /&gt;
La ordenación se realiza según los valores de ciertos miembros del contenedor. Estos elementos son denominados &amp;quot;de claves&amp;quot; (&amp;quot;Key values&amp;quot;). Lo que exige que los objetos &amp;quot;de clave&amp;quot; sean de un tipo para el que estén definidos los operadores relacionales. El contenedor es mantenido ordenado de forma automática por los algoritmos de inserción y borrado.&lt;br /&gt;
&lt;br /&gt;
La STL proporciona cinco tipo distintos, aunque en realidad son tres clases; dos de ellas en dos variedades (permitiendo o no claves duplicadas). Uno de los tipos (bitset) sirve para almacenar campos de bits de longitud constante. Los otros dos permiten elementos ordenados de cualquier tipo (set y multiset), mientras que map y multimap permiten alojar pares de elementos. Uno que actúa como &amp;quot;Key value&amp;quot; y otro que puede ser un tipo cualquiera al que llamaremos valor-dato.&lt;br /&gt;
&lt;br /&gt;
  • bitset&lt;br /&gt;
  • set&lt;br /&gt;
  • multiset&lt;br /&gt;
  • map&lt;br /&gt;
  • multimap&lt;br /&gt;
&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave, y para recorrer el conjunto (ordenado) de las claves.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http://www.zator.com/Cpp/E5_1_1.htm Contenerores C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Contenedores en C.conclase.net]&lt;br /&gt;
* [https://docs.microsoft.com/es-es/cpp/standard-library/stl-containers?view=vs-2017  Contenedores de la biblioteca estándar de C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234198</id>
		<title>Contenedores C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234198"/>
		<updated>2018-11-29T17:57:20Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Contenedores C++ |imagen=  |concepto= En sentido C++ estricto, un contenedor de la STL es una clase genérica que puede instanciarse para representar diversos tipos de objetos. Esta clase incluye ciertas operaciones  sobre los objetos de su tipo; estas operaciones están representadas por funciones-miembro, incluyendo constructores y funciones-operador, que son a su vez funciones genéricas}}''' Contenedores C++ '''. Al mismo tiempo, desde el punto de vista de las teorías de la información, podemos considerarlos estructuras de datos más o menos adecuadas (según el caso) para aplicarles ciertos algoritmos.&lt;br /&gt;
De su propio nombre (&amp;quot;Containers&amp;quot;) podemos deducir que su misión principal, y razón de su existencia, es su función como estructuras de datos, y en este sentido podemos adelantar que entre sus funcionalidades más destacadas se encuentran la gestión del espacio de almacenamiento necesario.&lt;br /&gt;
Una de las primerísimas ventajas de la utilización de contenedores es que el programador no tiene que enredarse con las cuestiones siempre espinosas de asignar o liberar memoria para los objetos creados, de forma que queda liberado de los [[Operadores|operadores]] [[Operador new|new]] y [[Operador delete|delete]].&lt;br /&gt;
== Filosofía de uso ==&lt;br /&gt;
Una primera pincelada sobre la filosofía de uso de los contenedores mediante un sencillo ejemplo: si tenemos que manejar un conjunto de enteros, puede utilizarse una matriz de enteros, pero ya hemos señalado  que esta estructura nos obliga a conocer de antemano la cantidad de datos a almacenar (el tamaño de la matriz). En consecuencia, si el número de datos puede variar, esta opción no es muy adecuada. Además, si es importante mantener los datos ordenados, la utilización de una matriz nos obligaría a ingeniar por nuestra cuenta la forma de hacerlo; seguramente mediante complicadas rutinas de &amp;quot;sort&amp;quot; hechas manualmente.&lt;br /&gt;
&lt;br /&gt;
Una alternativa es utilizar como &amp;quot;contenedor&amp;quot; para nuestros enteros una clase genérica de la STL denominada vector. En este caso, serían posibles expresiones como las siguientes:&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;int&amp;gt; v(3);         // L1:&lt;br /&gt;
v[0] = 7;                 // L2:&lt;br /&gt;
v[1] = v[0] + 1;          // L3:&lt;br /&gt;
v[2] = v[0] + v[1];       // L4:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Al encontrar la primera sentencia, el compilador crea una instancia (especialidad) anónima de la plantilla vector para alojar enteros; a continuación una instancia de ella para alojar tres enteros, a la que denominamos v.&lt;br /&gt;
&lt;br /&gt;
Una primera inspección de las sentencias L2 a L3, nos muestra que la clase ofrece la posibilidad de utilizar con sus miembros el operador subíndice de matriz [ ]. Deducimos por tanto, que dispone de una versión sobrecargada de este operador para los miembros de la clase, lo que nos permite utilizar el objeto v como una matriz, aunque con algunas funcionalidades no incluidas en aquellas.&lt;br /&gt;
&lt;br /&gt;
Después de L4 los valores finales para los miembros de nuestra &amp;quot;matriz&amp;quot; serian:&lt;br /&gt;
 v[0] == 7, v[1] == 8, v[2] == 15&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Si deseamos invertir el orden de los elementos de nuestra matriz. Para ello utilizamos una [[Función (programación)|función]] especial:&lt;br /&gt;
 reverse(v.begin(), v.end());&lt;br /&gt;
después de lo cual, el orden de miembros sería:&lt;br /&gt;
 v[0] == 15, v[1] == 8, v[2] == 7&lt;br /&gt;
&lt;br /&gt;
La primera observación es que la función reverse utiliza dos argumentos, que son a su vez el valor devuelto por sendos métodos de clase (los aplicamos sobre nuestro objeto v).  El valor devuelto por estos métodos es lo que se conoce como un [[Iteradores (Programación)|iterador]]; una especie de puntero que señalan al interior de la estructura de datos representada por el contenedor v. En este caso, el primer iterador señala al primer miembro y el segundo a una posición después del último; de esta forma se indican los miembros inicial y final entre los que se realizará la operación de inversión efectuada por reverse.&lt;br /&gt;
&lt;br /&gt;
La segunda observación es que la función reverse no es un método de clase, sino una función global; es lo que denominamos un [[Algoritmo|algoritmo]]. Esta función tiene la peculiaridad de que puede ser aplicado sobre el contenedor vector (y algún otro); que opera sobre un rango de los elementos del contenedor, en nuestro caso sobre la totalidad (esta capacidad de operar sobre una parte de un contenedor es característica de los algoritmos). También que pueden operar sobre otros contenedores produciendo un efecto similar. Por ejemplo, el algoritmo reverse puede operar incluso sobre una simple matriz:&lt;br /&gt;
 char Ch[5] = { 'A', 'E', 'I', 'O', 'U' };&lt;br /&gt;
 reverse(Ch, Ch + 5);&lt;br /&gt;
 for (int i = 0; i &amp;lt; 5; ++i) cout &amp;lt;&amp;lt; &amp;quot;Ch[&amp;quot; &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &amp;quot;] = &amp;quot; &amp;lt;&amp;lt; Ch[i];&lt;br /&gt;
 Salida:&lt;br /&gt;
 Ch[0] = U Ch[1] = O Ch[2] = I Ch[3] = E Ch[4] = A&lt;br /&gt;
&lt;br /&gt;
Es significativo que el objeto v es una estructura de datos que permite acceder individualmente a sus miembros &amp;quot;como si&amp;quot; fuesen elementos de una matriz. También que se pueden aplicar ciertas operaciones sobre la totalidad, o parte, de esta estructura considerada como una unidad.&lt;br /&gt;
== Clasificación ==&lt;br /&gt;
Existen dos tipos de contenedores: secuencias y asociativos; a su vez se subdividen según el tipo de [[Iteradores (Programación)|iterador]] que soportan.&lt;br /&gt;
&lt;br /&gt;
Las secuencias almacenan los elementos en orden secuencial (de ahí su nombre). El contenedor agrupa a todos sus miembros como una sucesión lineal, y en consecuencia son adecuadas para accesos directos y secuenciales. Un ejemplo de secuencia es una matriz. De hecho, los algoritmos que pueden aplicarse a las secuencias pueden aplicarse también a las matrices.&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, por lo que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.  La STL proporciona cinco tipos distintos.&lt;br /&gt;
&lt;br /&gt;
La existencia de índices supone una ordenación según los valores de un conjunto de elementos (denominado &amp;quot;de claves&amp;quot;) para el que debe existir un criterio de ordenación. Dicho en otras palabras, los objetos &amp;quot;de clave&amp;quot; deben ser de un tipo para el que estén definidos los operadores relacionales. El árbol es mantenido ordenado de forma automática por los algoritmos de inserción y borrado del contenedor.&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave y para recorrer el conjunto (ordenado) de los elementos.&lt;br /&gt;
&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] contiene diez formas de contenedores y tres adaptadores de contenedor (denominados simplemente [[Adapter|adaptadores]]). En esta sección se expondrán brevemente cuales son estas formas; sus características, y cuál es la más adecuada para cada tipo de problema específico. En secciones sucesivas se comentarán individualmente con mayor detalle.&lt;br /&gt;
Relación siguiendo la clasificación utilizada en el Estándar:&lt;br /&gt;
  •	Secuencias&lt;br /&gt;
      o	deque&lt;br /&gt;
      o	list&lt;br /&gt;
      o	stack&lt;br /&gt;
      o	vector&lt;br /&gt;
      o	vector &amp;lt;bool&amp;gt;&lt;br /&gt;
  •	adaptadores&lt;br /&gt;
      o	queue&lt;br /&gt;
      o	priority_queue&lt;br /&gt;
  •	Contenedores asociativos&lt;br /&gt;
      o	map&lt;br /&gt;
      o	multimap&lt;br /&gt;
      o	set&lt;br /&gt;
      o	multiset&lt;br /&gt;
      o	bitset&lt;br /&gt;
== Características ==&lt;br /&gt;
Las características más significativas de las diversas formas de contenedor son:&lt;br /&gt;
&lt;br /&gt;
Contenedor	Características&lt;br /&gt;
&lt;br /&gt;
Secuencias&lt;br /&gt;
&lt;br /&gt;
 vector: Este contenedor es una estructura de datos de tamaño fijo preferentemente. Aunque la STL proporciona herramientas para cambiar el tamaño de un vector de forma dinámica, esta operación es costosa y debe ser evitada dentro de lo posible (en este sentido el vector se comporta como una matriz ordinaria). &lt;br /&gt;
&lt;br /&gt;
Disponen de un buén mecanismo de acceso aleatorio a elementos y de un mecanismo de inserción al final muy eficiente.&lt;br /&gt;
Generalmente es preferible utilizar un vector que un deque o un list, a menos que sea frecuentemente necesario insertar datos al comienzo o al final, en cuyo caso es mejor utilizar un deque.  Si por el contrario es frecuente la inserción de elementos en el centro, entonces es preferible un list.&lt;br /&gt;
&lt;br /&gt;
 vector&amp;lt;bool&amp;gt;:	Es una versión de la anterior especial para valores binarios (bits).&lt;br /&gt;
&lt;br /&gt;
 list: Este contenedor responde a la idéa intuitiva de &amp;quot;lista&amp;quot;, el almacenamiento de objetos en una secuencia lineal que no está necesariamente ordenada (aunque sus miembros pueden ser ordenados fácilmente mediante la función-miembro sort() ). Estos contenedores suelen ser implementados como listas doblemente enlazadas. &lt;br /&gt;
&lt;br /&gt;
Dispone de mecanismos eficientes para insertar elementos al principio, al final o en cualquier posición (utilizando iteradores que denoten posición). Estas operaciones consumen un tiempo constante con independencia del número de elmentos albergados en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Dado que son estructuras lineales, en general los elementos no pueden ser accedidos por subíndices como en un vector.  Es necesario realizar un recorrido lineal por todos los valores, por lo que en las operaciones de acceso se utilizan tiempos proporcionales al número de elementos.&lt;br /&gt;
&lt;br /&gt;
 stack: Contenedor de elementos tipo pila LIFO que permite inserciones y eliminaciones solo en la parte superior.&lt;br /&gt;
&lt;br /&gt;
 deque: Los deques o colas de doble terminación (&amp;quot;Double-ended queue&amp;quot;) son un tipo de estructura de datos que comparte las características de las colas (&amp;quot;Queues&amp;quot;) y las pilas (&amp;quot;Stacks&amp;quot;). Como en las colas , los elementos pueden ser empujados por un extremo al interior del contenedor, y el primer elemento introducido puede ser extraído por el extremo opuesto. Al mismo tiempo, el último elemento introducido por el principio puede ser extraído en ese mismo extremo como si fuese una pila.&lt;br /&gt;
 &lt;br /&gt;
Estos contenedores suelen ser implementados bajo la forma de matrices bidimensionales.&lt;br /&gt;
&lt;br /&gt;
Las características de los deques implementados en la STL pueden resumirse en: Acceso aleatorio; mecanismo eficiente de inserción al principio o al final.&lt;br /&gt;
&lt;br /&gt;
 string: Contenedor de caracteres adaptado a operaciones con cadenas de caracteres.&lt;br /&gt;
&lt;br /&gt;
Asociaciones&lt;br /&gt;
&lt;br /&gt;
 set: Como el resto de contenedores asociativos, esta forma de contenedor mantiene los elementos en orden. Dispone de mecanismos eficientes para inclusión, inserción y eliminación de elementos, y soporta claves únicas (solo puede existir un miembro con una clave determinada).&lt;br /&gt;
&lt;br /&gt;
 multiset: Versión del anterior que permite la existencia de claves duplicadas. Es decir, distintos elementos dentro del conjunto pueden responder a la misma clave.&lt;br /&gt;
&lt;br /&gt;
 bitset: Contenedor de bit más orientado al tamaño que hacia el tipo de contenido. Permite almacenar secuencias de bits de tamaño fijo. No existen iteradores para reccorrerlas, y sus elementos se acceden utilizando el operador subíndice.&lt;br /&gt;
 &lt;br /&gt;
Se dispone de varias funciones para realizar con ellos operaciones de bits.&lt;br /&gt;
 &lt;br /&gt;
 map: Como el resto de estructuras asociativas, el map mantiene sus elementos ordenados. Se caracteriza porque sus miembros son pares de valores que pueden ser de tipos distintos. Uno de ellos, el que actúa como clave para el índice (&amp;quot;Key-value&amp;quot;), puede ser de cualquier tipo, a condición de que sus elementos puedan ser ordenados según un criterio (por defecto se utiliza el operador &amp;lt;).&lt;br /&gt;
 &lt;br /&gt;
Permite claves únicas. Es decir, que solo puede existir un miembro para cada clave. Dispone de mecanismos de inserción y borrado muy eficientes y no existe límite de tamaño. La estructura se encarga de crecer y disminuir en concordancia con las necesidades de sus miembros. Permite el operador [ ] subíndice para los elementos de la clave así como otras técnicas de acceso.&lt;br /&gt;
&lt;br /&gt;
Estas estructuras de datos recibe también los nombres de diccionarios, tablas y matrices asociativas, en referencia a que pueden considerarse como dos matrices del mismo número de elementos, en las que existe una relación entre cada miembro de una con otro miembro de la otra.  Una de las matrices (que actúa de índice) estaría ordenada según su contenido.&lt;br /&gt;
&lt;br /&gt;
 multimap: En todo igual que el anterior pero permitiendo además claves duplicadas. Es decir, que una misma clave pueda estar asociada a dos &amp;quot;valores&amp;quot; distintos.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Adaptador	Características&lt;br /&gt;
&lt;br /&gt;
 queue: Contenedor tipo cola FIFO que permite inserciones al final y eliminaciones al principio.&lt;br /&gt;
&lt;br /&gt;
 priority queue: Este contenedor dispone de mecanismos eficientes para acceso y eliminación de grandes valores.&lt;br /&gt;
&lt;br /&gt;
== Seleccionar un contenedor ==&lt;br /&gt;
El binomio contendor-iterador conforma una herramienta que se adapta a circunstancias muy variadas. Es posible que un determinado problema pueda ser abordado de varias formas, en estos casos la selección de la forma de contenedor más adecuado depende de las circunstancias. En ciertas ocasiones puede resultar bastante obvia; en otras puede no estar tan claro cuál es la mejor opción, pues &amp;quot;a priori&amp;quot;, pueden adaptarse varias formas al caso concreto. Puede utilizarse el sistema de prueba y comparación. Por ejemplo, cronometrando los resultados obtenidos en un modo u otro. También será de gran ayuda la experiencia, pero como una guía o criterio general puede utilizarse el principio de selección que se indica a continuación.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Como se accederá a los datos?.&lt;br /&gt;
| Si es importante un acceso aleatorio, pueden utilizarse un vector o un deque. Si basta con un acceso secuencial cualquiera de los dos puede ser el elegido.&lt;br /&gt;
|-&lt;br /&gt;
| Es importante el orden en que serán mantenidos los valores dentro de la colección de datos?&lt;br /&gt;
| Existen muchas formas de secuenciar los valores. Si es importante un orden estricto a lo largo de toda la vida del contenedor, la elección obvia es un set, dado que las inserciones en una de estas estructuras se realizan automáticamente en orden.&lt;br /&gt;
 &lt;br /&gt;
Si este orden es importante solo en algún momento, por ejemplo al final de una serie de inserciones, puede ser más sencillo colocar los valores en un list o vector para ordenar más tarde el resultado en el momento necesario.&lt;br /&gt;
&lt;br /&gt;
Si el orden en que se almacenan los valores en la estructura está relacionado con el orden de su inserción, entonces un stack, un queue o un list pueden ser la mejor elección.&lt;br /&gt;
|-&lt;br /&gt;
| fila 2, celda 1&lt;br /&gt;
| fila 2, celda 2&lt;br /&gt;
|-&lt;br /&gt;
| fila 2, celda 1&lt;br /&gt;
| fila 2, celda 2&lt;br /&gt;
|-&lt;br /&gt;
| fila 2, celda 1&lt;br /&gt;
| fila 2, celda 2&lt;br /&gt;
|-&lt;br /&gt;
| fila 2, celda 1&lt;br /&gt;
| fila 2, celda 2&lt;br /&gt;
|-&lt;br /&gt;
| fila 2, celda 1&lt;br /&gt;
| fila 2, celda 2&lt;br /&gt;
|-&lt;br /&gt;
| fila 2, celda 1&lt;br /&gt;
| fila 2, celda 2&lt;br /&gt;
|-&lt;br /&gt;
| fila 2, celda 1&lt;br /&gt;
| fila 2, celda 2&lt;br /&gt;
|-&lt;br /&gt;
| fila 2, celda 1&lt;br /&gt;
| fila 2, celda 2&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
Como se accederá a los datos?	Si es importante un acceso aleatorio, pueden utilizarse un vector o un deque. Si basta con un acceso secuencial cualquiera de los dos puede ser el elegido.&lt;br /&gt;
&lt;br /&gt;
Es importante el orden en que serán mantenidos los valores dentro de la colección de datos?	Existen muchas formas de secuenciar los valores. Si es importante un orden estricto a lo largo de toda la vida del contenedor, la elección obvia es un set, dado que las inserciones en una de estas estructuras se realizan automáticamente en orden. &lt;br /&gt;
Si este orden es importante solo en algún momento, por ejemplo al final de una serie de inserciones, puede ser más sencillo colocar los valores en un list o vector para ordenar más tarde el resultado en el momento necesario.&lt;br /&gt;
Si el orden en que se almacenan los valores en la estructura está relacionado con el orden de su inserción, entonces un stack, un queue o un list pueden ser la mejor elección.&lt;br /&gt;
Puede variar mucho el tamaño de la estructura de datos durante el curso de la ejecución del programa?	Si es así, entonces puede ser que la mejor opción sean un list o un set. Un vector o un deque pueden conducir a mantener un gran almacenamiento intermedio (buffer); incluso después que los elementos hayan sido eliminados de la colección de datos. Estos dos contenedores no son adecuados para cambios de tamaño, aunque vector dispone de un mecanismo de inserción al final eficiente. &lt;br /&gt;
Recíprocamente: si el tamaño de la colección se mantiene relativamente estable, entonces un vector o un deque pueden utilizar menos memoria que un list o un set que almacenen el mismo número de elementos.&lt;br /&gt;
Es posible determinar el tamaño de la colección?	La estructura de datos vector proporciona un medio para pre-seleccionar un bloque de memoria de un tamaño específico con la función miembro reserve, posibilidad que no existe en otros contenedores.&lt;br /&gt;
Es frecuente tener que comprobar si un valor cualquiera está incluido en la colección?	En este caso, un contenedor set o map pueden ser buena elección. En estos casos comprobar si un determinado valor está incluido puede ser realizado con un pequeño número de pasos (logarítmicos con el tamaño del contenedor). Mientras que la misma verificación en cualquiera de los otros tipos puede requerir comparar el valor con cada elemento almacenado en el contenedor.&lt;br /&gt;
Está indexada la colección de datos? 	Si las claves son enteros entre 0 y un límite superior, pueden utilizarse un vector o un deque. &lt;br /&gt;
Si es así, puede ser vista la colección como una serie de pares clave/valor?	Si la clave es algún otro valor, como cadenas de caracteres o tipos definidos por el usuario, puede utilizarse un contenedor map.&lt;br /&gt;
Pueden los valores estar relacionados unos con otros?	Todos los valores almacenados en cualquier contenedor de la STL debe ser capaz de comprobar la igualdad con cualquier otro valor similar, pero recuerde que no todos son capaces de reconocer el operador de relación menor-que; sin embargo, si los valores no pueden ser ordenados utilizando el operador menor-que, no pueden ser almacenados en un set o en un map.&lt;br /&gt;
Es una operación frecuente tener que encontrar y eliminar el valor mayor de la colección?	En caso afirmativo, la estructura de datos más idónea es el priority queue.&lt;br /&gt;
En que posiciones son insertados o eliminados los elementos de la estructura?	Si los valores son añadidos o eliminados en la zona interior, entonces la mejor opción es un list. &lt;br /&gt;
Si los valores son insertados solo al comienzo, un deque o un list pueden ser lo más adecuado.&lt;br /&gt;
Si los valores son insertados y eliminados solo al final, un stack o un queue pueden ser elecciones lógicas.&lt;br /&gt;
Es frecuente tener que refundir dos o más secuencias en una sola?	En caso afirmativo, puede considerarse que las mejores opciones son un set o un list, dependiendo que la colección deba o no ser mantenida en orden. &lt;br /&gt;
Refundir dos set es una operación muy eficiente.  Si la colección de datos no está ordenada, pero puede utilizarse la función miembro splice() de las list (que es muy eficiente), entonces es preferible este último tipo de contenedor, dado que esta operación no está contemplada en las demás formas.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Tipos no incluidos ===&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] incluye contenedores adecuados para la mayoría de los casos prácticos, aunque quizás existen una serie de estructuras de datos clásicas que no han sido incluidas. En la mayoría de los casos, la causa es que los contenedores proporcionados pueden ser fácilmente adaptados para suplir los usos facilitados por los tipos omitidos.&lt;br /&gt;
Tipos clásicos no incluidos y la sustitución más fácil.&lt;br /&gt;
Contenedor omitido	Sustitución utilizando elementos de STL&lt;br /&gt;
tree	El modo set está implementado internamente como un árbol de búsqueda binaria. &lt;br /&gt;
Para la mayoría de los casos prácticos que pueden ser resueltos utilizando árboles este modo es un sustituto adecuado.&lt;br /&gt;
matrices multidimensionales	Puesto que los vectores pueden almacenar elementos que sean otros vectores, estas estructuras pueden ser construidas fácilmente.&lt;br /&gt;
graph	La representación de un gráfico puede ser fácilmente construida como un map que contiene otros map. Un map cuyos elementos son a su vez maps, es la representación natural de un gráfico directo. Por ejemplo, supongamos que utilizamos cadenas de caracteres para codificar nombres de ciudades, y que deseamos construir un map donde el valor asociado con un borde es la distancia entre dos ciudades conectadas. &lt;br /&gt;
Se puede crear uno de estos gráficos como se muestra en el ejemplo (  xxx)&lt;br /&gt;
sparse array	Una novedosa sustitución es la representación de un gráfico.&lt;br /&gt;
hash table	Las tablas hash proporcionan un tiempo de acceso constante, así como inserción y borrado de elementos, convirtiendo estas operaciones en operaciones de índice. &lt;br /&gt;
Una tabla hash puede ser construida fácilmente como un vector (o deque) cuyos elementos son lists (o incluso sets).  En el ejemplo de la ordenación raíz (  xxx) se describe una de estas estructuras (un vector de deques), aunque en este ejemplo no incluye invocación la función hash para convertir un valor en un índice.&lt;br /&gt;
Funcionalidad set	En la STL, los tipos set están específicamente ordenados, y sus operaciones (como la unión intersección, etc.) no pueden ser realizadas sobre colecciones de valores no ordenados (por ejemplo un conjunto de números complejos). &lt;br /&gt;
Una list puede ser utilizada como sustituto, aunque es necesario escribir funciones de operación especiales, dado que los algoritmos genéricos no pueden ser utilizados con listas.&lt;br /&gt;
== Gestión de memoria ==&lt;br /&gt;
La gestión de memoria realizada por los contenedores comprende tanto la asignación y liberación de espacio para sus miembros, como para las claves que constituyen el sistema de índice de algunos tipos de contenedor. En general los algoritmos de la STL están muy optimizados y el sistema de asignación de memoria intenta compaginar rapidez y eficacia. La primera exige asignar y desasignar espacio cada vez que se introduce o elimina un miembro del contenedor. La eficacia, e incluso la disminución de la fragmentación inherentes al manejo del montón, exige asignar y rehusar trozos de memoria lo más grandes posible cada vez. El abordaje a este problema se ha realizado de dos formas básicas: (a) Contenedores que no pueden alterar su tamaño, de forma que la asignación de espacio para sus elementos debe realizarse en el momento de su declaración. (b) Contenedores que pueden crecer y/o disminuir en consonancia con los elementos a albergar.&lt;br /&gt;
Refiriéndonos al caso (b), para balancear estas exigencias contrapuestas, algunas implementaciones utilizan el siguiente esquema de trabajo: inicialmente el sistema asigna al contenedor un trozo de memoria de tamaño adecuado para contener cierto número de elementos; espacio que es utilizando hasta que se agota. A partir de aquí, cada nueva demanda origina la asignación una zona de doble tamaño que la anterior. Por ejemplo, supongamos que para gestionar un vector de enteros, el compilador asigna inicialmente espacio para un máximo de 16 miembros.  Cuando se agotara, se realizaría una nueva asignación de espacio para 32 miembros, e inmediatamente se efectuaría una recolocación del contenido actual en el nuevo espacio y la liberación del primitivo. Si el nuevo contenedor quedara lleno de nuevo, la siguiente asignación sería capaz de 64 miembros y así sucesivamente.&lt;br /&gt;
El factor de aumento de tamaño puede ser cualquiera. Muchos compiladores utilizan un factor 1.5 cada vez que deben ampliar el espacio necesario.&lt;br /&gt;
Cada nueva recolocación implica varios pasos:&lt;br /&gt;
•	Asignación de memoria al estilo malloc() de la librería clásica en cantidad suficiente para el nuevo tamaño.&lt;br /&gt;
•	Copia de los elementos actuales en la nueva localización. Los elementos son colocados en la nueva situación utilizando el constructor copia.&lt;br /&gt;
•	Actualización de las estructuras internas del nuevo contenedor (sistema de índices).&lt;br /&gt;
•	Eliminación de los elementos originales mediante invocación sucesiva de sus correspondientes destructores.&lt;br /&gt;
•	Liberación de la memoria utilizada por las estructuras internas.&lt;br /&gt;
•	Liberación de la zona original mediante una invocación al estilo free de la librería clásica.&lt;br /&gt;
&lt;br /&gt;
En general, al referirse al tamaño de un contenedor existen tres magnitudes distintas aunque relacionadas, cuyos valores pueden obtenerse mediante tres métodos:&lt;br /&gt;
•	El número de elementos contenidos actualmente. size()&lt;br /&gt;
•	El máximo número de elementos que pueden alcanzarse actualmente sin necesidad de una nueva recolocación. capacity()&lt;br /&gt;
•	El máximo número de elementos que pueden alcanzarse en cualquier caso. max_size().&lt;br /&gt;
Ejemplo:&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {         // ================&lt;br /&gt;
vector&amp;lt;int&amp;gt; vInt;&lt;br /&gt;
for (int i=0; i &amp;lt; 100; i++) vInt.push_back(i);&lt;br /&gt;
&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;Tamaño actual:   &amp;quot; &amp;lt;&amp;lt; vInt.size()     &amp;lt;&amp;lt; endl;&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;Capacidad actual: &amp;quot; &amp;lt;&amp;lt; vInt.capacity() &amp;lt;&amp;lt; endl;&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;Tamano maximo:   &amp;quot; &amp;lt;&amp;lt; vInt.max_size() &amp;lt;&amp;lt; endl;&lt;br /&gt;
return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
Tamaño actual: 100&lt;br /&gt;
Capacidad actual: 256&lt;br /&gt;
Tamano maximo: 1073741823&lt;br /&gt;
En todos los casos: size() &amp;lt;= capacity()&lt;br /&gt;
Es posible comprobar si un contenedor está vacío, comparando su tamaño actual size() con cero, aunque es más rápido utilizar el método empty(), que devuelve true si realmente size() == 0.&lt;br /&gt;
=== Reserva de espacio ==&lt;br /&gt;
Como puede suponer, cada recolocación supone un proceso considerable, sobre todo en contenedores muy grandes. Para evitar sus inconvenientes si se conoce de antemano el tamaño máximo a utilizar, la STL ofrece la posibilidad de preasignar un espacio arbitrario. Para esto se dispone del método reserve(n), que garantiza la asignación de espacio inicial suficiente para alojar n miembros en el contenedor. Si el argumento n es mayor que la capacidad actual, se produce una recolocación y el nuevo argumento determina la nueva capacidad. Si es menor no se produce ninguna acción.&lt;br /&gt;
Ejemplo, para crear un vector de enteros capaz para al menos 1000 miembros:&lt;br /&gt;
vector &amp;lt;int&amp;gt; v;&lt;br /&gt;
v.reserve(1000);&lt;br /&gt;
&lt;br /&gt;
En el siguiente ejemplo se muestran los resultados compilado con Borland C++ 5.5 para Win32; con MS Visual C++ 6.0 y con GNU gcc 2.95.3 para Linux:&lt;br /&gt;
// resultados con:         BC++   VC++   GNU   &lt;br /&gt;
vector&amp;lt;int&amp;gt; v;&lt;br /&gt;
cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 0      0      0   &lt;br /&gt;
cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 0      0      0&lt;br /&gt;
v.push_back(3);&lt;br /&gt;
cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    1      1&lt;br /&gt;
v.reserve(100);&lt;br /&gt;
cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    100    100&lt;br /&gt;
=== Operaciones sobre contenedores ===&lt;br /&gt;
Los elementos de un contenedor son colocados en él utilizando el constructor copia, aunque algunas operaciones requieren la existencia de un constructor por defecto. A su vez, los algoritmos genéricos, como copy(), que copian a un contenedor, utilizan el operador de asignación.&lt;br /&gt;
Por ejemplo, cuando se duplica todo un contenedor de tipos T por invocación del constructor copia o por asignación, cada miembro es copiado en la nueva estructura utilizando el constructor copia o el operador de asignación. Tanto si una copia profunda o una copia somera, el resultado es controlado por el programador, que puede proporcionar el operador de asignación para el tipo T con cualquier significado que desee. Si se ha definido un destructor para el tipo T, este destructor es invocado cada vez que deba ser eliminado un elemento del contenedor. Cuando se destruye toda la colección, el destructor es invocado por cada elemento que permaneciera almacenado.&lt;br /&gt;
Debemos añadir algunas palabras acerca de los contenedores que almacenan colecciones de punteros. Estos conjuntos no son raros. Por ejemplo, una colección de punteros es el único medio de almacenar valores que pueden representar indistintamente instancias de una clase o instancias de una subclase. Puede encontrarse una de estas colecciones en el ejemplo de simulación manejada por eventos (  xxx).&lt;br /&gt;
En estos casos, el contenedor es solamente responsable de mantener los propios punteros, siendo responsabilidad del programador manejar la memoria de los valores referenciados por estos, lo que supone que los espacios de memoria son asignados correctamente; por lo general mediante el operador new; que no son desasignados mientras el contenedor albergue referencias a ellos, y que sean adecuadamente desasignados una vez que han sido eliminados del contenedor.&lt;br /&gt;
===  Secuencias ===&lt;br /&gt;
Las secuencias son estructuras de datos de tipo lineal, con posibilidad de que su tamaño puede ser alterado insertando elementos al principio, al final o en cualquier posición, si bien la idoneidad en este sentido es distinta entre los diversos tipos.&lt;br /&gt;
La STL ofrece los siguientes:&lt;br /&gt;
•	deque&lt;br /&gt;
•	list&lt;br /&gt;
•	stack&lt;br /&gt;
•	vector&lt;br /&gt;
•	vector&amp;lt;bool&amp;gt;&lt;br /&gt;
La estructura lineal implica que sus datos son lógicamente contiguos, aunque su disposición física puede que no lo sea. Los elementos pueden ser accedidos por un índice numérico, aunque en algunos tipos de secuencia el acceso a un elemento implica un recorrido por la lista.&lt;br /&gt;
== Contenedores asociativos ==&lt;br /&gt;
Los contenedores asociativos son una extensión de las secuencias. Mientras que en estas para acceder a los elementos solo pueden utilizarse claves numéricas, que señalan el número de orden del elemento dentro de la secuencia (al estilo de los índices en las matrices). Los contenedores asociativos admiten cualquier tipo de clave de acceso. Las más frecuentes son las cadenas alfanuméricas (stings).&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, razón por la que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.&lt;br /&gt;
La ordenación se realiza según los valores de ciertos miembros del contenedor. Estos elementos son denominados &amp;quot;de claves&amp;quot; (&amp;quot;Key values&amp;quot;). Lo que exige que los objetos &amp;quot;de clave&amp;quot; sean de un tipo para el que estén definidos los operadores relacionales. El contenedor es mantenido ordenado de forma automática por los algoritmos de inserción y borrado.&lt;br /&gt;
La STL proporciona cinco tipo distintos, aunque en realidad son tres clases; dos de ellas en dos variedades (permitiendo o no claves duplicadas). Uno de los tipos (bitset) sirve para almacenar campos de bits de longitud constante. Los otros dos permiten elementos ordenados de cualquier tipo (set y multiset), mientras que map y multimap permiten alojar pares de elementos. Uno que actúa como &amp;quot;Key value&amp;quot; y otro que puede ser un tipo cualquiera al que llamaremos valor-dato.&lt;br /&gt;
•	bitset&lt;br /&gt;
•	set&lt;br /&gt;
•	multiset&lt;br /&gt;
•	map&lt;br /&gt;
•	multimap&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave, y para recorrer el conjunto (ordenado) de las claves.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http://www.zator.com/Cpp/E5_1_1.htm Contenerores C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Contenedores en C.conclase.net]&lt;br /&gt;
* [https://docs.microsoft.com/es-es/cpp/standard-library/stl-containers?view=vs-2017  Contenedores de la biblioteca estándar de C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234196</id>
		<title>Contenedores C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234196"/>
		<updated>2018-11-29T17:55:40Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Contenedores C++ |imagen=  |concepto= En sentido C++ estricto, un contenedor de la STL es una clase genérica que puede instanciarse para representar diversos tipos de objetos. Esta clase incluye ciertas operaciones  sobre los objetos de su tipo; estas operaciones están representadas por funciones-miembro, incluyendo constructores y funciones-operador, que son a su vez funciones genéricas}}''' Contenedores C++ '''. Al mismo tiempo, desde el punto de vista de las teorías de la información, podemos considerarlos estructuras de datos más o menos adecuadas (según el caso) para aplicarles ciertos algoritmos.&lt;br /&gt;
De su propio nombre (&amp;quot;Containers&amp;quot;) podemos deducir que su misión principal, y razón de su existencia, es su función como estructuras de datos, y en este sentido podemos adelantar que entre sus funcionalidades más destacadas se encuentran la gestión del espacio de almacenamiento necesario.&lt;br /&gt;
Una de las primerísimas ventajas de la utilización de contenedores es que el programador no tiene que enredarse con las cuestiones siempre espinosas de asignar o liberar memoria para los objetos creados, de forma que queda liberado de los [[Operadores|operadores]] [[Operador new|new]] y [[Operador delete|delete]].&lt;br /&gt;
== Filosofía de uso ==&lt;br /&gt;
Una primera pincelada sobre la filosofía de uso de los contenedores mediante un sencillo ejemplo: si tenemos que manejar un conjunto de enteros, puede utilizarse una matriz de enteros, pero ya hemos señalado  que esta estructura nos obliga a conocer de antemano la cantidad de datos a almacenar (el tamaño de la matriz). En consecuencia, si el número de datos puede variar, esta opción no es muy adecuada. Además, si es importante mantener los datos ordenados, la utilización de una matriz nos obligaría a ingeniar por nuestra cuenta la forma de hacerlo; seguramente mediante complicadas rutinas de &amp;quot;sort&amp;quot; hechas manualmente.&lt;br /&gt;
&lt;br /&gt;
Una alternativa es utilizar como &amp;quot;contenedor&amp;quot; para nuestros enteros una clase genérica de la STL denominada vector. En este caso, serían posibles expresiones como las siguientes:&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;int&amp;gt; v(3);         // L1:&lt;br /&gt;
v[0] = 7;                 // L2:&lt;br /&gt;
v[1] = v[0] + 1;          // L3:&lt;br /&gt;
v[2] = v[0] + v[1];       // L4:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Al encontrar la primera sentencia, el compilador crea una instancia (especialidad) anónima de la plantilla vector para alojar enteros; a continuación una instancia de ella para alojar tres enteros, a la que denominamos v.&lt;br /&gt;
&lt;br /&gt;
Una primera inspección de las sentencias L2 a L3, nos muestra que la clase ofrece la posibilidad de utilizar con sus miembros el operador subíndice de matriz [ ]. Deducimos por tanto, que dispone de una versión sobrecargada de este operador para los miembros de la clase, lo que nos permite utilizar el objeto v como una matriz, aunque con algunas funcionalidades no incluidas en aquellas.&lt;br /&gt;
&lt;br /&gt;
Después de L4 los valores finales para los miembros de nuestra &amp;quot;matriz&amp;quot; serian:&lt;br /&gt;
 v[0] == 7, v[1] == 8, v[2] == 15&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Si deseamos invertir el orden de los elementos de nuestra matriz. Para ello utilizamos una [[Función (programación)|función]] especial:&lt;br /&gt;
 reverse(v.begin(), v.end());&lt;br /&gt;
después de lo cual, el orden de miembros sería:&lt;br /&gt;
 v[0] == 15, v[1] == 8, v[2] == 7&lt;br /&gt;
&lt;br /&gt;
La primera observación es que la función reverse utiliza dos argumentos, que son a su vez el valor devuelto por sendos métodos de clase (los aplicamos sobre nuestro objeto v).  El valor devuelto por estos métodos es lo que se conoce como un [[Iteradores (Programación)|iterador]]; una especie de puntero que señalan al interior de la estructura de datos representada por el contenedor v. En este caso, el primer iterador señala al primer miembro y el segundo a una posición después del último; de esta forma se indican los miembros inicial y final entre los que se realizará la operación de inversión efectuada por reverse.&lt;br /&gt;
&lt;br /&gt;
La segunda observación es que la función reverse no es un método de clase, sino una función global; es lo que denominamos un [[Algoritmo|algoritmo]]. Esta función tiene la peculiaridad de que puede ser aplicado sobre el contenedor vector (y algún otro); que opera sobre un rango de los elementos del contenedor, en nuestro caso sobre la totalidad (esta capacidad de operar sobre una parte de un contenedor es característica de los algoritmos). También que pueden operar sobre otros contenedores produciendo un efecto similar. Por ejemplo, el algoritmo reverse puede operar incluso sobre una simple matriz:&lt;br /&gt;
 char Ch[5] = { 'A', 'E', 'I', 'O', 'U' };&lt;br /&gt;
 reverse(Ch, Ch + 5);&lt;br /&gt;
 for (int i = 0; i &amp;lt; 5; ++i) cout &amp;lt;&amp;lt; &amp;quot;Ch[&amp;quot; &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &amp;quot;] = &amp;quot; &amp;lt;&amp;lt; Ch[i];&lt;br /&gt;
 Salida:&lt;br /&gt;
 Ch[0] = U Ch[1] = O Ch[2] = I Ch[3] = E Ch[4] = A&lt;br /&gt;
&lt;br /&gt;
Es significativo que el objeto v es una estructura de datos que permite acceder individualmente a sus miembros &amp;quot;como si&amp;quot; fuesen elementos de una matriz. También que se pueden aplicar ciertas operaciones sobre la totalidad, o parte, de esta estructura considerada como una unidad.&lt;br /&gt;
== Clasificación ==&lt;br /&gt;
Existen dos tipos de contenedores: secuencias y asociativos; a su vez se subdividen según el tipo de [[Iteradores (Programación)|iterador]] que soportan.&lt;br /&gt;
&lt;br /&gt;
Las secuencias almacenan los elementos en orden secuencial (de ahí su nombre). El contenedor agrupa a todos sus miembros como una sucesión lineal, y en consecuencia son adecuadas para accesos directos y secuenciales. Un ejemplo de secuencia es una matriz. De hecho, los algoritmos que pueden aplicarse a las secuencias pueden aplicarse también a las matrices.&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, por lo que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.  La STL proporciona cinco tipos distintos.&lt;br /&gt;
&lt;br /&gt;
La existencia de índices supone una ordenación según los valores de un conjunto de elementos (denominado &amp;quot;de claves&amp;quot;) para el que debe existir un criterio de ordenación. Dicho en otras palabras, los objetos &amp;quot;de clave&amp;quot; deben ser de un tipo para el que estén definidos los operadores relacionales. El árbol es mantenido ordenado de forma automática por los algoritmos de inserción y borrado del contenedor.&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave y para recorrer el conjunto (ordenado) de los elementos.&lt;br /&gt;
&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] contiene diez formas de contenedores y tres adaptadores de contenedor (denominados simplemente [[Adapter|adaptadores]]). En esta sección se expondrán brevemente cuales son estas formas; sus características, y cuál es la más adecuada para cada tipo de problema específico. En secciones sucesivas se comentarán individualmente con mayor detalle.&lt;br /&gt;
Relación siguiendo la clasificación utilizada en el Estándar:&lt;br /&gt;
  •	Secuencias&lt;br /&gt;
      o	deque&lt;br /&gt;
      o	list&lt;br /&gt;
      o	stack&lt;br /&gt;
      o	vector&lt;br /&gt;
      o	vector &amp;lt;bool&amp;gt;&lt;br /&gt;
  •	adaptadores&lt;br /&gt;
      o	queue&lt;br /&gt;
      o	priority_queue&lt;br /&gt;
  •	Contenedores asociativos&lt;br /&gt;
      o	map&lt;br /&gt;
      o	multimap&lt;br /&gt;
      o	set&lt;br /&gt;
      o	multiset&lt;br /&gt;
      o	bitset&lt;br /&gt;
== Características ==&lt;br /&gt;
Las características más significativas de las diversas formas de contenedor son:&lt;br /&gt;
&lt;br /&gt;
Contenedor	Características&lt;br /&gt;
&lt;br /&gt;
Secuencias&lt;br /&gt;
&lt;br /&gt;
 vector: Este contenedor es una estructura de datos de tamaño fijo preferentemente. Aunque la STL proporciona herramientas para cambiar el tamaño de un vector de forma dinámica, esta operación es costosa y debe ser evitada dentro de lo posible (en este sentido el vector se comporta como una matriz ordinaria). &lt;br /&gt;
&lt;br /&gt;
Disponen de un buén mecanismo de acceso aleatorio a elementos y de un mecanismo de inserción al final muy eficiente.&lt;br /&gt;
Generalmente es preferible utilizar un vector que un deque o un list, a menos que sea frecuentemente necesario insertar datos al comienzo o al final, en cuyo caso es mejor utilizar un deque.  Si por el contrario es frecuente la inserción de elementos en el centro, entonces es preferible un list.&lt;br /&gt;
&lt;br /&gt;
 vector&amp;lt;bool&amp;gt;:	Es una versión de la anterior especial para valores binarios (bits).&lt;br /&gt;
&lt;br /&gt;
 list: Este contenedor responde a la idéa intuitiva de &amp;quot;lista&amp;quot;, el almacenamiento de objetos en una secuencia lineal que no está necesariamente ordenada (aunque sus miembros pueden ser ordenados fácilmente mediante la función-miembro sort() ). Estos contenedores suelen ser implementados como listas doblemente enlazadas. &lt;br /&gt;
&lt;br /&gt;
Dispone de mecanismos eficientes para insertar elementos al principio, al final o en cualquier posición (utilizando iteradores que denoten posición). Estas operaciones consumen un tiempo constante con independencia del número de elmentos albergados en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Dado que son estructuras lineales, en general los elementos no pueden ser accedidos por subíndices como en un vector.  Es necesario realizar un recorrido lineal por todos los valores, por lo que en las operaciones de acceso se utilizan tiempos proporcionales al número de elementos.&lt;br /&gt;
&lt;br /&gt;
 stack: Contenedor de elementos tipo pila LIFO que permite inserciones y eliminaciones solo en la parte superior.&lt;br /&gt;
&lt;br /&gt;
 deque: Los deques o colas de doble terminación (&amp;quot;Double-ended queue&amp;quot;) son un tipo de estructura de datos que comparte las características de las colas (&amp;quot;Queues&amp;quot;) y las pilas (&amp;quot;Stacks&amp;quot;). Como en las colas , los elementos pueden ser empujados por un extremo al interior del contenedor, y el primer elemento introducido puede ser extraído por el extremo opuesto. Al mismo tiempo, el último elemento introducido por el principio puede ser extraído en ese mismo extremo como si fuese una pila.&lt;br /&gt;
 &lt;br /&gt;
Estos contenedores suelen ser implementados bajo la forma de matrices bidimensionales.&lt;br /&gt;
&lt;br /&gt;
Las características de los deques implementados en la STL pueden resumirse en: Acceso aleatorio; mecanismo eficiente de inserción al principio o al final.&lt;br /&gt;
&lt;br /&gt;
 string: Contenedor de caracteres adaptado a operaciones con cadenas de caracteres.&lt;br /&gt;
&lt;br /&gt;
Asociaciones&lt;br /&gt;
&lt;br /&gt;
 set: Como el resto de contenedores asociativos, esta forma de contenedor mantiene los elementos en orden. Dispone de mecanismos eficientes para inclusión, inserción y eliminación de elementos, y soporta claves únicas (solo puede existir un miembro con una clave determinada).&lt;br /&gt;
&lt;br /&gt;
 multiset: Versión del anterior que permite la existencia de claves duplicadas. Es decir, distintos elementos dentro del conjunto pueden responder a la misma clave.&lt;br /&gt;
&lt;br /&gt;
 bitset: Contenedor de bit más orientado al tamaño que hacia el tipo de contenido. Permite almacenar secuencias de bits de tamaño fijo. No existen iteradores para reccorrerlas, y sus elementos se acceden utilizando el operador subíndice.&lt;br /&gt;
 &lt;br /&gt;
Se dispone de varias funciones para realizar con ellos operaciones de bits.&lt;br /&gt;
 &lt;br /&gt;
 map: Como el resto de estructuras asociativas, el map mantiene sus elementos ordenados. Se caracteriza porque sus miembros son pares de valores que pueden ser de tipos distintos. Uno de ellos, el que actúa como clave para el índice (&amp;quot;Key-value&amp;quot;), puede ser de cualquier tipo, a condición de que sus elementos puedan ser ordenados según un criterio (por defecto se utiliza el operador &amp;lt;).&lt;br /&gt;
 &lt;br /&gt;
Permite claves únicas. Es decir, que solo puede existir un miembro para cada clave. Dispone de mecanismos de inserción y borrado muy eficientes y no existe límite de tamaño. La estructura se encarga de crecer y disminuir en concordancia con las necesidades de sus miembros. Permite el operador [ ] subíndice para los elementos de la clave así como otras técnicas de acceso.&lt;br /&gt;
&lt;br /&gt;
Estas estructuras de datos recibe también los nombres de diccionarios, tablas y matrices asociativas, en referencia a que pueden considerarse como dos matrices del mismo número de elementos, en las que existe una relación entre cada miembro de una con otro miembro de la otra.  Una de las matrices (que actúa de índice) estaría ordenada según su contenido.&lt;br /&gt;
&lt;br /&gt;
 multimap: En todo igual que el anterior pero permitiendo además claves duplicadas. Es decir, que una misma clave pueda estar asociada a dos &amp;quot;valores&amp;quot; distintos.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Adaptador	Características&lt;br /&gt;
&lt;br /&gt;
 queue: Contenedor tipo cola FIFO que permite inserciones al final y eliminaciones al principio.&lt;br /&gt;
&lt;br /&gt;
 priority queue: Este contenedor dispone de mecanismos eficientes para acceso y eliminación de grandes valores.&lt;br /&gt;
&lt;br /&gt;
== Seleccionar un contenedor ==&lt;br /&gt;
El binomio contendor-iterador conforma una herramienta que se adapta a circunstancias muy variadas. Es posible que un determinado problema pueda ser abordado de varias formas, en estos casos la selección de la forma de contenedor más adecuado depende de las circunstancias. En ciertas ocasiones puede resultar bastante obvia; en otras puede no estar tan claro cuál es la mejor opción, pues &amp;quot;a priori&amp;quot;, pueden adaptarse varias formas al caso concreto. Puede utilizarse el sistema de prueba y comparación. Por ejemplo, cronometrando los resultados obtenidos en un modo u otro. También será de gran ayuda la experiencia, pero como una guía o criterio general puede utilizarse el principio de selección que se indica a continuación.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Como se accederá a los datos?.&lt;br /&gt;
| Si es importante un acceso aleatorio, pueden utilizarse un vector o un deque. Si basta con un acceso secuencial cualquiera de los dos puede ser el elegido.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| fila 2, celda 1&lt;br /&gt;
| fila 2, celda 2&lt;br /&gt;
|}&lt;br /&gt;
Como se accederá a los datos?	Si es importante un acceso aleatorio, pueden utilizarse un vector o un deque. Si basta con un acceso secuencial cualquiera de los dos puede ser el elegido.&lt;br /&gt;
&lt;br /&gt;
Es importante el orden en que serán mantenidos los valores dentro de la colección de datos?	Existen muchas formas de secuenciar los valores. Si es importante un orden estricto a lo largo de toda la vida del contenedor, la elección obvia es un set, dado que las inserciones en una de estas estructuras se realizan automáticamente en orden. &lt;br /&gt;
Si este orden es importante solo en algún momento, por ejemplo al final de una serie de inserciones, puede ser más sencillo colocar los valores en un list o vector para ordenar más tarde el resultado en el momento necesario.&lt;br /&gt;
Si el orden en que se almacenan los valores en la estructura está relacionado con el orden de su inserción, entonces un stack, un queue o un list pueden ser la mejor elección.&lt;br /&gt;
Puede variar mucho el tamaño de la estructura de datos durante el curso de la ejecución del programa?	Si es así, entonces puede ser que la mejor opción sean un list o un set. Un vector o un deque pueden conducir a mantener un gran almacenamiento intermedio (buffer); incluso después que los elementos hayan sido eliminados de la colección de datos. Estos dos contenedores no son adecuados para cambios de tamaño, aunque vector dispone de un mecanismo de inserción al final eficiente. &lt;br /&gt;
Recíprocamente: si el tamaño de la colección se mantiene relativamente estable, entonces un vector o un deque pueden utilizar menos memoria que un list o un set que almacenen el mismo número de elementos.&lt;br /&gt;
Es posible determinar el tamaño de la colección?	La estructura de datos vector proporciona un medio para pre-seleccionar un bloque de memoria de un tamaño específico con la función miembro reserve, posibilidad que no existe en otros contenedores.&lt;br /&gt;
Es frecuente tener que comprobar si un valor cualquiera está incluido en la colección?	En este caso, un contenedor set o map pueden ser buena elección. En estos casos comprobar si un determinado valor está incluido puede ser realizado con un pequeño número de pasos (logarítmicos con el tamaño del contenedor). Mientras que la misma verificación en cualquiera de los otros tipos puede requerir comparar el valor con cada elemento almacenado en el contenedor.&lt;br /&gt;
Está indexada la colección de datos? 	Si las claves son enteros entre 0 y un límite superior, pueden utilizarse un vector o un deque. &lt;br /&gt;
Si es así, puede ser vista la colección como una serie de pares clave/valor?	Si la clave es algún otro valor, como cadenas de caracteres o tipos definidos por el usuario, puede utilizarse un contenedor map.&lt;br /&gt;
Pueden los valores estar relacionados unos con otros?	Todos los valores almacenados en cualquier contenedor de la STL debe ser capaz de comprobar la igualdad con cualquier otro valor similar, pero recuerde que no todos son capaces de reconocer el operador de relación menor-que; sin embargo, si los valores no pueden ser ordenados utilizando el operador menor-que, no pueden ser almacenados en un set o en un map.&lt;br /&gt;
Es una operación frecuente tener que encontrar y eliminar el valor mayor de la colección?	En caso afirmativo, la estructura de datos más idónea es el priority queue.&lt;br /&gt;
En que posiciones son insertados o eliminados los elementos de la estructura?	Si los valores son añadidos o eliminados en la zona interior, entonces la mejor opción es un list. &lt;br /&gt;
Si los valores son insertados solo al comienzo, un deque o un list pueden ser lo más adecuado.&lt;br /&gt;
Si los valores son insertados y eliminados solo al final, un stack o un queue pueden ser elecciones lógicas.&lt;br /&gt;
Es frecuente tener que refundir dos o más secuencias en una sola?	En caso afirmativo, puede considerarse que las mejores opciones son un set o un list, dependiendo que la colección deba o no ser mantenida en orden. &lt;br /&gt;
Refundir dos set es una operación muy eficiente.  Si la colección de datos no está ordenada, pero puede utilizarse la función miembro splice() de las list (que es muy eficiente), entonces es preferible este último tipo de contenedor, dado que esta operación no está contemplada en las demás formas.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Tipos no incluidos ===&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] incluye contenedores adecuados para la mayoría de los casos prácticos, aunque quizás existen una serie de estructuras de datos clásicas que no han sido incluidas. En la mayoría de los casos, la causa es que los contenedores proporcionados pueden ser fácilmente adaptados para suplir los usos facilitados por los tipos omitidos.&lt;br /&gt;
Tipos clásicos no incluidos y la sustitución más fácil.&lt;br /&gt;
Contenedor omitido	Sustitución utilizando elementos de STL&lt;br /&gt;
tree	El modo set está implementado internamente como un árbol de búsqueda binaria. &lt;br /&gt;
Para la mayoría de los casos prácticos que pueden ser resueltos utilizando árboles este modo es un sustituto adecuado.&lt;br /&gt;
matrices multidimensionales	Puesto que los vectores pueden almacenar elementos que sean otros vectores, estas estructuras pueden ser construidas fácilmente.&lt;br /&gt;
graph	La representación de un gráfico puede ser fácilmente construida como un map que contiene otros map. Un map cuyos elementos son a su vez maps, es la representación natural de un gráfico directo. Por ejemplo, supongamos que utilizamos cadenas de caracteres para codificar nombres de ciudades, y que deseamos construir un map donde el valor asociado con un borde es la distancia entre dos ciudades conectadas. &lt;br /&gt;
Se puede crear uno de estos gráficos como se muestra en el ejemplo (  xxx)&lt;br /&gt;
sparse array	Una novedosa sustitución es la representación de un gráfico.&lt;br /&gt;
hash table	Las tablas hash proporcionan un tiempo de acceso constante, así como inserción y borrado de elementos, convirtiendo estas operaciones en operaciones de índice. &lt;br /&gt;
Una tabla hash puede ser construida fácilmente como un vector (o deque) cuyos elementos son lists (o incluso sets).  En el ejemplo de la ordenación raíz (  xxx) se describe una de estas estructuras (un vector de deques), aunque en este ejemplo no incluye invocación la función hash para convertir un valor en un índice.&lt;br /&gt;
Funcionalidad set	En la STL, los tipos set están específicamente ordenados, y sus operaciones (como la unión intersección, etc.) no pueden ser realizadas sobre colecciones de valores no ordenados (por ejemplo un conjunto de números complejos). &lt;br /&gt;
Una list puede ser utilizada como sustituto, aunque es necesario escribir funciones de operación especiales, dado que los algoritmos genéricos no pueden ser utilizados con listas.&lt;br /&gt;
== Gestión de memoria ==&lt;br /&gt;
La gestión de memoria realizada por los contenedores comprende tanto la asignación y liberación de espacio para sus miembros, como para las claves que constituyen el sistema de índice de algunos tipos de contenedor. En general los algoritmos de la STL están muy optimizados y el sistema de asignación de memoria intenta compaginar rapidez y eficacia. La primera exige asignar y desasignar espacio cada vez que se introduce o elimina un miembro del contenedor. La eficacia, e incluso la disminución de la fragmentación inherentes al manejo del montón, exige asignar y rehusar trozos de memoria lo más grandes posible cada vez. El abordaje a este problema se ha realizado de dos formas básicas: (a) Contenedores que no pueden alterar su tamaño, de forma que la asignación de espacio para sus elementos debe realizarse en el momento de su declaración. (b) Contenedores que pueden crecer y/o disminuir en consonancia con los elementos a albergar.&lt;br /&gt;
Refiriéndonos al caso (b), para balancear estas exigencias contrapuestas, algunas implementaciones utilizan el siguiente esquema de trabajo: inicialmente el sistema asigna al contenedor un trozo de memoria de tamaño adecuado para contener cierto número de elementos; espacio que es utilizando hasta que se agota. A partir de aquí, cada nueva demanda origina la asignación una zona de doble tamaño que la anterior. Por ejemplo, supongamos que para gestionar un vector de enteros, el compilador asigna inicialmente espacio para un máximo de 16 miembros.  Cuando se agotara, se realizaría una nueva asignación de espacio para 32 miembros, e inmediatamente se efectuaría una recolocación del contenido actual en el nuevo espacio y la liberación del primitivo. Si el nuevo contenedor quedara lleno de nuevo, la siguiente asignación sería capaz de 64 miembros y así sucesivamente.&lt;br /&gt;
El factor de aumento de tamaño puede ser cualquiera. Muchos compiladores utilizan un factor 1.5 cada vez que deben ampliar el espacio necesario.&lt;br /&gt;
Cada nueva recolocación implica varios pasos:&lt;br /&gt;
•	Asignación de memoria al estilo malloc() de la librería clásica en cantidad suficiente para el nuevo tamaño.&lt;br /&gt;
•	Copia de los elementos actuales en la nueva localización. Los elementos son colocados en la nueva situación utilizando el constructor copia.&lt;br /&gt;
•	Actualización de las estructuras internas del nuevo contenedor (sistema de índices).&lt;br /&gt;
•	Eliminación de los elementos originales mediante invocación sucesiva de sus correspondientes destructores.&lt;br /&gt;
•	Liberación de la memoria utilizada por las estructuras internas.&lt;br /&gt;
•	Liberación de la zona original mediante una invocación al estilo free de la librería clásica.&lt;br /&gt;
&lt;br /&gt;
En general, al referirse al tamaño de un contenedor existen tres magnitudes distintas aunque relacionadas, cuyos valores pueden obtenerse mediante tres métodos:&lt;br /&gt;
•	El número de elementos contenidos actualmente. size()&lt;br /&gt;
•	El máximo número de elementos que pueden alcanzarse actualmente sin necesidad de una nueva recolocación. capacity()&lt;br /&gt;
•	El máximo número de elementos que pueden alcanzarse en cualquier caso. max_size().&lt;br /&gt;
Ejemplo:&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {         // ================&lt;br /&gt;
vector&amp;lt;int&amp;gt; vInt;&lt;br /&gt;
for (int i=0; i &amp;lt; 100; i++) vInt.push_back(i);&lt;br /&gt;
&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;Tamaño actual:   &amp;quot; &amp;lt;&amp;lt; vInt.size()     &amp;lt;&amp;lt; endl;&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;Capacidad actual: &amp;quot; &amp;lt;&amp;lt; vInt.capacity() &amp;lt;&amp;lt; endl;&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;Tamano maximo:   &amp;quot; &amp;lt;&amp;lt; vInt.max_size() &amp;lt;&amp;lt; endl;&lt;br /&gt;
return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
Tamaño actual: 100&lt;br /&gt;
Capacidad actual: 256&lt;br /&gt;
Tamano maximo: 1073741823&lt;br /&gt;
En todos los casos: size() &amp;lt;= capacity()&lt;br /&gt;
Es posible comprobar si un contenedor está vacío, comparando su tamaño actual size() con cero, aunque es más rápido utilizar el método empty(), que devuelve true si realmente size() == 0.&lt;br /&gt;
=== Reserva de espacio ==&lt;br /&gt;
Como puede suponer, cada recolocación supone un proceso considerable, sobre todo en contenedores muy grandes. Para evitar sus inconvenientes si se conoce de antemano el tamaño máximo a utilizar, la STL ofrece la posibilidad de preasignar un espacio arbitrario. Para esto se dispone del método reserve(n), que garantiza la asignación de espacio inicial suficiente para alojar n miembros en el contenedor. Si el argumento n es mayor que la capacidad actual, se produce una recolocación y el nuevo argumento determina la nueva capacidad. Si es menor no se produce ninguna acción.&lt;br /&gt;
Ejemplo, para crear un vector de enteros capaz para al menos 1000 miembros:&lt;br /&gt;
vector &amp;lt;int&amp;gt; v;&lt;br /&gt;
v.reserve(1000);&lt;br /&gt;
&lt;br /&gt;
En el siguiente ejemplo se muestran los resultados compilado con Borland C++ 5.5 para Win32; con MS Visual C++ 6.0 y con GNU gcc 2.95.3 para Linux:&lt;br /&gt;
// resultados con:         BC++   VC++   GNU   &lt;br /&gt;
vector&amp;lt;int&amp;gt; v;&lt;br /&gt;
cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 0      0      0   &lt;br /&gt;
cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 0      0      0&lt;br /&gt;
v.push_back(3);&lt;br /&gt;
cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    1      1&lt;br /&gt;
v.reserve(100);&lt;br /&gt;
cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    100    100&lt;br /&gt;
=== Operaciones sobre contenedores ===&lt;br /&gt;
Los elementos de un contenedor son colocados en él utilizando el constructor copia, aunque algunas operaciones requieren la existencia de un constructor por defecto. A su vez, los algoritmos genéricos, como copy(), que copian a un contenedor, utilizan el operador de asignación.&lt;br /&gt;
Por ejemplo, cuando se duplica todo un contenedor de tipos T por invocación del constructor copia o por asignación, cada miembro es copiado en la nueva estructura utilizando el constructor copia o el operador de asignación. Tanto si una copia profunda o una copia somera, el resultado es controlado por el programador, que puede proporcionar el operador de asignación para el tipo T con cualquier significado que desee. Si se ha definido un destructor para el tipo T, este destructor es invocado cada vez que deba ser eliminado un elemento del contenedor. Cuando se destruye toda la colección, el destructor es invocado por cada elemento que permaneciera almacenado.&lt;br /&gt;
Debemos añadir algunas palabras acerca de los contenedores que almacenan colecciones de punteros. Estos conjuntos no son raros. Por ejemplo, una colección de punteros es el único medio de almacenar valores que pueden representar indistintamente instancias de una clase o instancias de una subclase. Puede encontrarse una de estas colecciones en el ejemplo de simulación manejada por eventos (  xxx).&lt;br /&gt;
En estos casos, el contenedor es solamente responsable de mantener los propios punteros, siendo responsabilidad del programador manejar la memoria de los valores referenciados por estos, lo que supone que los espacios de memoria son asignados correctamente; por lo general mediante el operador new; que no son desasignados mientras el contenedor albergue referencias a ellos, y que sean adecuadamente desasignados una vez que han sido eliminados del contenedor.&lt;br /&gt;
===  Secuencias ===&lt;br /&gt;
Las secuencias son estructuras de datos de tipo lineal, con posibilidad de que su tamaño puede ser alterado insertando elementos al principio, al final o en cualquier posición, si bien la idoneidad en este sentido es distinta entre los diversos tipos.&lt;br /&gt;
La STL ofrece los siguientes:&lt;br /&gt;
•	deque&lt;br /&gt;
•	list&lt;br /&gt;
•	stack&lt;br /&gt;
•	vector&lt;br /&gt;
•	vector&amp;lt;bool&amp;gt;&lt;br /&gt;
La estructura lineal implica que sus datos son lógicamente contiguos, aunque su disposición física puede que no lo sea. Los elementos pueden ser accedidos por un índice numérico, aunque en algunos tipos de secuencia el acceso a un elemento implica un recorrido por la lista.&lt;br /&gt;
== Contenedores asociativos ==&lt;br /&gt;
Los contenedores asociativos son una extensión de las secuencias. Mientras que en estas para acceder a los elementos solo pueden utilizarse claves numéricas, que señalan el número de orden del elemento dentro de la secuencia (al estilo de los índices en las matrices). Los contenedores asociativos admiten cualquier tipo de clave de acceso. Las más frecuentes son las cadenas alfanuméricas (stings).&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, razón por la que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.&lt;br /&gt;
La ordenación se realiza según los valores de ciertos miembros del contenedor. Estos elementos son denominados &amp;quot;de claves&amp;quot; (&amp;quot;Key values&amp;quot;). Lo que exige que los objetos &amp;quot;de clave&amp;quot; sean de un tipo para el que estén definidos los operadores relacionales. El contenedor es mantenido ordenado de forma automática por los algoritmos de inserción y borrado.&lt;br /&gt;
La STL proporciona cinco tipo distintos, aunque en realidad son tres clases; dos de ellas en dos variedades (permitiendo o no claves duplicadas). Uno de los tipos (bitset) sirve para almacenar campos de bits de longitud constante. Los otros dos permiten elementos ordenados de cualquier tipo (set y multiset), mientras que map y multimap permiten alojar pares de elementos. Uno que actúa como &amp;quot;Key value&amp;quot; y otro que puede ser un tipo cualquiera al que llamaremos valor-dato.&lt;br /&gt;
•	bitset&lt;br /&gt;
•	set&lt;br /&gt;
•	multiset&lt;br /&gt;
•	map&lt;br /&gt;
•	multimap&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave, y para recorrer el conjunto (ordenado) de las claves.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http://www.zator.com/Cpp/E5_1_1.htm Contenerores C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Contenedores en C.conclase.net]&lt;br /&gt;
* [https://docs.microsoft.com/es-es/cpp/standard-library/stl-containers?view=vs-2017  Contenedores de la biblioteca estándar de C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234195</id>
		<title>Contenedores C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234195"/>
		<updated>2018-11-29T17:52:56Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Contenedores C++ |imagen=  |concepto= En sentido C++ estricto, un contenedor de la STL es una clase genérica que puede instanciarse para representar diversos tipos de objetos. Esta clase incluye ciertas operaciones  sobre los objetos de su tipo; estas operaciones están representadas por funciones-miembro, incluyendo constructores y funciones-operador, que son a su vez funciones genéricas}}''' Contenedores C++ '''. Al mismo tiempo, desde el punto de vista de las teorías de la información, podemos considerarlos estructuras de datos más o menos adecuadas (según el caso) para aplicarles ciertos algoritmos.&lt;br /&gt;
De su propio nombre (&amp;quot;Containers&amp;quot;) podemos deducir que su misión principal, y razón de su existencia, es su función como estructuras de datos, y en este sentido podemos adelantar que entre sus funcionalidades más destacadas se encuentran la gestión del espacio de almacenamiento necesario.&lt;br /&gt;
Una de las primerísimas ventajas de la utilización de contenedores es que el programador no tiene que enredarse con las cuestiones siempre espinosas de asignar o liberar memoria para los objetos creados, de forma que queda liberado de los [[Operadores|operadores]] [[Operador new|new]] y [[Operador delete|delete]].&lt;br /&gt;
== Filosofía de uso ==&lt;br /&gt;
Una primera pincelada sobre la filosofía de uso de los contenedores mediante un sencillo ejemplo: si tenemos que manejar un conjunto de enteros, puede utilizarse una matriz de enteros, pero ya hemos señalado  que esta estructura nos obliga a conocer de antemano la cantidad de datos a almacenar (el tamaño de la matriz). En consecuencia, si el número de datos puede variar, esta opción no es muy adecuada. Además, si es importante mantener los datos ordenados, la utilización de una matriz nos obligaría a ingeniar por nuestra cuenta la forma de hacerlo; seguramente mediante complicadas rutinas de &amp;quot;sort&amp;quot; hechas manualmente.&lt;br /&gt;
&lt;br /&gt;
Una alternativa es utilizar como &amp;quot;contenedor&amp;quot; para nuestros enteros una clase genérica de la STL denominada vector. En este caso, serían posibles expresiones como las siguientes:&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;int&amp;gt; v(3);         // L1:&lt;br /&gt;
v[0] = 7;                 // L2:&lt;br /&gt;
v[1] = v[0] + 1;          // L3:&lt;br /&gt;
v[2] = v[0] + v[1];       // L4:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Al encontrar la primera sentencia, el compilador crea una instancia (especialidad) anónima de la plantilla vector para alojar enteros; a continuación una instancia de ella para alojar tres enteros, a la que denominamos v.&lt;br /&gt;
&lt;br /&gt;
Una primera inspección de las sentencias L2 a L3, nos muestra que la clase ofrece la posibilidad de utilizar con sus miembros el operador subíndice de matriz [ ]. Deducimos por tanto, que dispone de una versión sobrecargada de este operador para los miembros de la clase, lo que nos permite utilizar el objeto v como una matriz, aunque con algunas funcionalidades no incluidas en aquellas.&lt;br /&gt;
&lt;br /&gt;
Después de L4 los valores finales para los miembros de nuestra &amp;quot;matriz&amp;quot; serian:&lt;br /&gt;
 v[0] == 7, v[1] == 8, v[2] == 15&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Si deseamos invertir el orden de los elementos de nuestra matriz. Para ello utilizamos una [[Función (programación)|función]] especial:&lt;br /&gt;
 reverse(v.begin(), v.end());&lt;br /&gt;
después de lo cual, el orden de miembros sería:&lt;br /&gt;
 v[0] == 15, v[1] == 8, v[2] == 7&lt;br /&gt;
&lt;br /&gt;
La primera observación es que la función reverse utiliza dos argumentos, que son a su vez el valor devuelto por sendos métodos de clase (los aplicamos sobre nuestro objeto v).  El valor devuelto por estos métodos es lo que se conoce como un [[Iteradores (Programación)|iterador]]; una especie de puntero que señalan al interior de la estructura de datos representada por el contenedor v. En este caso, el primer iterador señala al primer miembro y el segundo a una posición después del último; de esta forma se indican los miembros inicial y final entre los que se realizará la operación de inversión efectuada por reverse.&lt;br /&gt;
&lt;br /&gt;
La segunda observación es que la función reverse no es un método de clase, sino una función global; es lo que denominamos un [[Algoritmo|algoritmo]]. Esta función tiene la peculiaridad de que puede ser aplicado sobre el contenedor vector (y algún otro); que opera sobre un rango de los elementos del contenedor, en nuestro caso sobre la totalidad (esta capacidad de operar sobre una parte de un contenedor es característica de los algoritmos). También que pueden operar sobre otros contenedores produciendo un efecto similar. Por ejemplo, el algoritmo reverse puede operar incluso sobre una simple matriz:&lt;br /&gt;
 char Ch[5] = { 'A', 'E', 'I', 'O', 'U' };&lt;br /&gt;
 reverse(Ch, Ch + 5);&lt;br /&gt;
 for (int i = 0; i &amp;lt; 5; ++i) cout &amp;lt;&amp;lt; &amp;quot;Ch[&amp;quot; &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &amp;quot;] = &amp;quot; &amp;lt;&amp;lt; Ch[i];&lt;br /&gt;
 Salida:&lt;br /&gt;
 Ch[0] = U Ch[1] = O Ch[2] = I Ch[3] = E Ch[4] = A&lt;br /&gt;
&lt;br /&gt;
Es significativo que el objeto v es una estructura de datos que permite acceder individualmente a sus miembros &amp;quot;como si&amp;quot; fuesen elementos de una matriz. También que se pueden aplicar ciertas operaciones sobre la totalidad, o parte, de esta estructura considerada como una unidad.&lt;br /&gt;
== Clasificación ==&lt;br /&gt;
Existen dos tipos de contenedores: secuencias y asociativos; a su vez se subdividen según el tipo de [[Iteradores (Programación)|iterador]] que soportan.&lt;br /&gt;
&lt;br /&gt;
Las secuencias almacenan los elementos en orden secuencial (de ahí su nombre). El contenedor agrupa a todos sus miembros como una sucesión lineal, y en consecuencia son adecuadas para accesos directos y secuenciales. Un ejemplo de secuencia es una matriz. De hecho, los algoritmos que pueden aplicarse a las secuencias pueden aplicarse también a las matrices.&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, por lo que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.  La STL proporciona cinco tipos distintos.&lt;br /&gt;
&lt;br /&gt;
La existencia de índices supone una ordenación según los valores de un conjunto de elementos (denominado &amp;quot;de claves&amp;quot;) para el que debe existir un criterio de ordenación. Dicho en otras palabras, los objetos &amp;quot;de clave&amp;quot; deben ser de un tipo para el que estén definidos los operadores relacionales. El árbol es mantenido ordenado de forma automática por los algoritmos de inserción y borrado del contenedor.&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave y para recorrer el conjunto (ordenado) de los elementos.&lt;br /&gt;
&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] contiene diez formas de contenedores y tres adaptadores de contenedor (denominados simplemente [[Adapter|adaptadores]]). En esta sección se expondrán brevemente cuales son estas formas; sus características, y cuál es la más adecuada para cada tipo de problema específico. En secciones sucesivas se comentarán individualmente con mayor detalle.&lt;br /&gt;
Relación siguiendo la clasificación utilizada en el Estándar:&lt;br /&gt;
  •	Secuencias&lt;br /&gt;
      o	deque&lt;br /&gt;
      o	list&lt;br /&gt;
      o	stack&lt;br /&gt;
      o	vector&lt;br /&gt;
      o	vector &amp;lt;bool&amp;gt;&lt;br /&gt;
  •	adaptadores&lt;br /&gt;
      o	queue&lt;br /&gt;
      o	priority_queue&lt;br /&gt;
  •	Contenedores asociativos&lt;br /&gt;
      o	map&lt;br /&gt;
      o	multimap&lt;br /&gt;
      o	set&lt;br /&gt;
      o	multiset&lt;br /&gt;
      o	bitset&lt;br /&gt;
== Características ==&lt;br /&gt;
Las características más significativas de las diversas formas de contenedor son:&lt;br /&gt;
&lt;br /&gt;
Contenedor	Características&lt;br /&gt;
&lt;br /&gt;
Secuencias&lt;br /&gt;
&lt;br /&gt;
 vector: Este contenedor es una estructura de datos de tamaño fijo preferentemente. Aunque la STL proporciona herramientas para cambiar el tamaño de un vector de forma dinámica, esta operación es costosa y debe ser evitada dentro de lo posible (en este sentido el vector se comporta como una matriz ordinaria). &lt;br /&gt;
&lt;br /&gt;
Disponen de un buén mecanismo de acceso aleatorio a elementos y de un mecanismo de inserción al final muy eficiente.&lt;br /&gt;
Generalmente es preferible utilizar un vector que un deque o un list, a menos que sea frecuentemente necesario insertar datos al comienzo o al final, en cuyo caso es mejor utilizar un deque.  Si por el contrario es frecuente la inserción de elementos en el centro, entonces es preferible un list.&lt;br /&gt;
&lt;br /&gt;
 vector&amp;lt;bool&amp;gt;:	Es una versión de la anterior especial para valores binarios (bits).&lt;br /&gt;
&lt;br /&gt;
 list: Este contenedor responde a la idéa intuitiva de &amp;quot;lista&amp;quot;, el almacenamiento de objetos en una secuencia lineal que no está necesariamente ordenada (aunque sus miembros pueden ser ordenados fácilmente mediante la función-miembro sort() ). Estos contenedores suelen ser implementados como listas doblemente enlazadas. &lt;br /&gt;
&lt;br /&gt;
Dispone de mecanismos eficientes para insertar elementos al principio, al final o en cualquier posición (utilizando iteradores que denoten posición). Estas operaciones consumen un tiempo constante con independencia del número de elmentos albergados en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Dado que son estructuras lineales, en general los elementos no pueden ser accedidos por subíndices como en un vector.  Es necesario realizar un recorrido lineal por todos los valores, por lo que en las operaciones de acceso se utilizan tiempos proporcionales al número de elementos.&lt;br /&gt;
&lt;br /&gt;
 stack: Contenedor de elementos tipo pila LIFO que permite inserciones y eliminaciones solo en la parte superior.&lt;br /&gt;
&lt;br /&gt;
 deque: Los deques o colas de doble terminación (&amp;quot;Double-ended queue&amp;quot;) son un tipo de estructura de datos que comparte las características de las colas (&amp;quot;Queues&amp;quot;) y las pilas (&amp;quot;Stacks&amp;quot;). Como en las colas , los elementos pueden ser empujados por un extremo al interior del contenedor, y el primer elemento introducido puede ser extraído por el extremo opuesto. Al mismo tiempo, el último elemento introducido por el principio puede ser extraído en ese mismo extremo como si fuese una pila.&lt;br /&gt;
 &lt;br /&gt;
Estos contenedores suelen ser implementados bajo la forma de matrices bidimensionales.&lt;br /&gt;
&lt;br /&gt;
Las características de los deques implementados en la STL pueden resumirse en: Acceso aleatorio; mecanismo eficiente de inserción al principio o al final.&lt;br /&gt;
&lt;br /&gt;
 string: Contenedor de caracteres adaptado a operaciones con cadenas de caracteres.&lt;br /&gt;
&lt;br /&gt;
Asociaciones&lt;br /&gt;
&lt;br /&gt;
 set: Como el resto de contenedores asociativos, esta forma de contenedor mantiene los elementos en orden. Dispone de mecanismos eficientes para inclusión, inserción y eliminación de elementos, y soporta claves únicas (solo puede existir un miembro con una clave determinada).&lt;br /&gt;
&lt;br /&gt;
 multiset: Versión del anterior que permite la existencia de claves duplicadas. Es decir, distintos elementos dentro del conjunto pueden responder a la misma clave.&lt;br /&gt;
&lt;br /&gt;
 bitset: Contenedor de bit más orientado al tamaño que hacia el tipo de contenido. Permite almacenar secuencias de bits de tamaño fijo. No existen iteradores para reccorrerlas, y sus elementos se acceden utilizando el operador subíndice.&lt;br /&gt;
 &lt;br /&gt;
Se dispone de varias funciones para realizar con ellos operaciones de bits.&lt;br /&gt;
 &lt;br /&gt;
 map: Como el resto de estructuras asociativas, el map mantiene sus elementos ordenados. Se caracteriza porque sus miembros son pares de valores que pueden ser de tipos distintos. Uno de ellos, el que actúa como clave para el índice (&amp;quot;Key-value&amp;quot;), puede ser de cualquier tipo, a condición de que sus elementos puedan ser ordenados según un criterio (por defecto se utiliza el operador &amp;lt;).&lt;br /&gt;
 &lt;br /&gt;
Permite claves únicas. Es decir, que solo puede existir un miembro para cada clave. Dispone de mecanismos de inserción y borrado muy eficientes y no existe límite de tamaño. La estructura se encarga de crecer y disminuir en concordancia con las necesidades de sus miembros. Permite el operador [ ] subíndice para los elementos de la clave así como otras técnicas de acceso.&lt;br /&gt;
&lt;br /&gt;
Estas estructuras de datos recibe también los nombres de diccionarios, tablas y matrices asociativas, en referencia a que pueden considerarse como dos matrices del mismo número de elementos, en las que existe una relación entre cada miembro de una con otro miembro de la otra.  Una de las matrices (que actúa de índice) estaría ordenada según su contenido.&lt;br /&gt;
&lt;br /&gt;
 multimap: En todo igual que el anterior pero permitiendo además claves duplicadas. Es decir, que una misma clave pueda estar asociada a dos &amp;quot;valores&amp;quot; distintos.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Adaptador	Características&lt;br /&gt;
&lt;br /&gt;
 queue: Contenedor tipo cola FIFO que permite inserciones al final y eliminaciones al principio.&lt;br /&gt;
&lt;br /&gt;
 priority queue: Este contenedor dispone de mecanismos eficientes para acceso y eliminación de grandes valores.&lt;br /&gt;
&lt;br /&gt;
== Seleccionar un contenedor ==&lt;br /&gt;
El binomio contendor-iterador conforma una herramienta que se adapta a circunstancias muy variadas. Es posible que un determinado problema pueda ser abordado de varias formas, en estos casos la selección de la forma de contenedor más adecuado depende de las circunstancias. En ciertas ocasiones puede resultar bastante obvia; en otras puede no estar tan claro cuál es la mejor opción, pues &amp;quot;a priori&amp;quot;, pueden adaptarse varias formas al caso concreto. Puede utilizarse el sistema de prueba y comparación. Por ejemplo, cronometrando los resultados obtenidos en un modo u otro. También será de gran ayuda la experiencia, pero como una guía o criterio general puede utilizarse el principio de selección que se indica a continuación.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Como se accederá a los datos?, Si es importante un acceso aleatorio, pueden utilizarse un vector o un deque. Si basta con un acceso secuencial cualquiera de los dos puede ser el elegido.&lt;br /&gt;
| Es importante el orden en que serán mantenidos los valores dentro de la colección de datos?, Existen muchas formas de secuenciar los valores. Si es importante un orden estricto a lo largo de toda la vida del contenedor, la elección obvia es un set, dado que las inserciones en una de estas estructuras se realizan automáticamente en orden. &lt;br /&gt;
Si este orden es importante solo en algún momento, por ejemplo al final de una serie de inserciones, puede ser más sencillo colocar los valores en un list o vector para ordenar más tarde el resultado en el momento necesario.&lt;br /&gt;
Si el orden en que se almacenan los valores en la estructura está relacionado con el orden de su inserción, entonces un stack, un queue o un list pueden ser la mejor elección.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| fila 2, celda 1&lt;br /&gt;
| fila 2, celda 2&lt;br /&gt;
|}&lt;br /&gt;
Como se accederá a los datos?	Si es importante un acceso aleatorio, pueden utilizarse un vector o un deque. Si basta con un acceso secuencial cualquiera de los dos puede ser el elegido.&lt;br /&gt;
&lt;br /&gt;
Es importante el orden en que serán mantenidos los valores dentro de la colección de datos?	Existen muchas formas de secuenciar los valores. Si es importante un orden estricto a lo largo de toda la vida del contenedor, la elección obvia es un set, dado que las inserciones en una de estas estructuras se realizan automáticamente en orden. &lt;br /&gt;
Si este orden es importante solo en algún momento, por ejemplo al final de una serie de inserciones, puede ser más sencillo colocar los valores en un list o vector para ordenar más tarde el resultado en el momento necesario.&lt;br /&gt;
Si el orden en que se almacenan los valores en la estructura está relacionado con el orden de su inserción, entonces un stack, un queue o un list pueden ser la mejor elección.&lt;br /&gt;
Puede variar mucho el tamaño de la estructura de datos durante el curso de la ejecución del programa?	Si es así, entonces puede ser que la mejor opción sean un list o un set. Un vector o un deque pueden conducir a mantener un gran almacenamiento intermedio (buffer); incluso después que los elementos hayan sido eliminados de la colección de datos. Estos dos contenedores no son adecuados para cambios de tamaño, aunque vector dispone de un mecanismo de inserción al final eficiente. &lt;br /&gt;
Recíprocamente: si el tamaño de la colección se mantiene relativamente estable, entonces un vector o un deque pueden utilizar menos memoria que un list o un set que almacenen el mismo número de elementos.&lt;br /&gt;
Es posible determinar el tamaño de la colección?	La estructura de datos vector proporciona un medio para pre-seleccionar un bloque de memoria de un tamaño específico con la función miembro reserve, posibilidad que no existe en otros contenedores.&lt;br /&gt;
Es frecuente tener que comprobar si un valor cualquiera está incluido en la colección?	En este caso, un contenedor set o map pueden ser buena elección. En estos casos comprobar si un determinado valor está incluido puede ser realizado con un pequeño número de pasos (logarítmicos con el tamaño del contenedor). Mientras que la misma verificación en cualquiera de los otros tipos puede requerir comparar el valor con cada elemento almacenado en el contenedor.&lt;br /&gt;
Está indexada la colección de datos? 	Si las claves son enteros entre 0 y un límite superior, pueden utilizarse un vector o un deque. &lt;br /&gt;
Si es así, puede ser vista la colección como una serie de pares clave/valor?	Si la clave es algún otro valor, como cadenas de caracteres o tipos definidos por el usuario, puede utilizarse un contenedor map.&lt;br /&gt;
Pueden los valores estar relacionados unos con otros?	Todos los valores almacenados en cualquier contenedor de la STL debe ser capaz de comprobar la igualdad con cualquier otro valor similar, pero recuerde que no todos son capaces de reconocer el operador de relación menor-que; sin embargo, si los valores no pueden ser ordenados utilizando el operador menor-que, no pueden ser almacenados en un set o en un map.&lt;br /&gt;
Es una operación frecuente tener que encontrar y eliminar el valor mayor de la colección?	En caso afirmativo, la estructura de datos más idónea es el priority queue.&lt;br /&gt;
En que posiciones son insertados o eliminados los elementos de la estructura?	Si los valores son añadidos o eliminados en la zona interior, entonces la mejor opción es un list. &lt;br /&gt;
Si los valores son insertados solo al comienzo, un deque o un list pueden ser lo más adecuado.&lt;br /&gt;
Si los valores son insertados y eliminados solo al final, un stack o un queue pueden ser elecciones lógicas.&lt;br /&gt;
Es frecuente tener que refundir dos o más secuencias en una sola?	En caso afirmativo, puede considerarse que las mejores opciones son un set o un list, dependiendo que la colección deba o no ser mantenida en orden. &lt;br /&gt;
Refundir dos set es una operación muy eficiente.  Si la colección de datos no está ordenada, pero puede utilizarse la función miembro splice() de las list (que es muy eficiente), entonces es preferible este último tipo de contenedor, dado que esta operación no está contemplada en las demás formas.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Tipos no incluidos ===&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] incluye contenedores adecuados para la mayoría de los casos prácticos, aunque quizás existen una serie de estructuras de datos clásicas que no han sido incluidas. En la mayoría de los casos, la causa es que los contenedores proporcionados pueden ser fácilmente adaptados para suplir los usos facilitados por los tipos omitidos.&lt;br /&gt;
Tipos clásicos no incluidos y la sustitución más fácil.&lt;br /&gt;
Contenedor omitido	Sustitución utilizando elementos de STL&lt;br /&gt;
tree	El modo set está implementado internamente como un árbol de búsqueda binaria. &lt;br /&gt;
Para la mayoría de los casos prácticos que pueden ser resueltos utilizando árboles este modo es un sustituto adecuado.&lt;br /&gt;
matrices multidimensionales	Puesto que los vectores pueden almacenar elementos que sean otros vectores, estas estructuras pueden ser construidas fácilmente.&lt;br /&gt;
graph	La representación de un gráfico puede ser fácilmente construida como un map que contiene otros map. Un map cuyos elementos son a su vez maps, es la representación natural de un gráfico directo. Por ejemplo, supongamos que utilizamos cadenas de caracteres para codificar nombres de ciudades, y que deseamos construir un map donde el valor asociado con un borde es la distancia entre dos ciudades conectadas. &lt;br /&gt;
Se puede crear uno de estos gráficos como se muestra en el ejemplo (  xxx)&lt;br /&gt;
sparse array	Una novedosa sustitución es la representación de un gráfico.&lt;br /&gt;
hash table	Las tablas hash proporcionan un tiempo de acceso constante, así como inserción y borrado de elementos, convirtiendo estas operaciones en operaciones de índice. &lt;br /&gt;
Una tabla hash puede ser construida fácilmente como un vector (o deque) cuyos elementos son lists (o incluso sets).  En el ejemplo de la ordenación raíz (  xxx) se describe una de estas estructuras (un vector de deques), aunque en este ejemplo no incluye invocación la función hash para convertir un valor en un índice.&lt;br /&gt;
Funcionalidad set	En la STL, los tipos set están específicamente ordenados, y sus operaciones (como la unión intersección, etc.) no pueden ser realizadas sobre colecciones de valores no ordenados (por ejemplo un conjunto de números complejos). &lt;br /&gt;
Una list puede ser utilizada como sustituto, aunque es necesario escribir funciones de operación especiales, dado que los algoritmos genéricos no pueden ser utilizados con listas.&lt;br /&gt;
== Gestión de memoria ==&lt;br /&gt;
La gestión de memoria realizada por los contenedores comprende tanto la asignación y liberación de espacio para sus miembros, como para las claves que constituyen el sistema de índice de algunos tipos de contenedor. En general los algoritmos de la STL están muy optimizados y el sistema de asignación de memoria intenta compaginar rapidez y eficacia. La primera exige asignar y desasignar espacio cada vez que se introduce o elimina un miembro del contenedor. La eficacia, e incluso la disminución de la fragmentación inherentes al manejo del montón, exige asignar y rehusar trozos de memoria lo más grandes posible cada vez. El abordaje a este problema se ha realizado de dos formas básicas: (a) Contenedores que no pueden alterar su tamaño, de forma que la asignación de espacio para sus elementos debe realizarse en el momento de su declaración. (b) Contenedores que pueden crecer y/o disminuir en consonancia con los elementos a albergar.&lt;br /&gt;
Refiriéndonos al caso (b), para balancear estas exigencias contrapuestas, algunas implementaciones utilizan el siguiente esquema de trabajo: inicialmente el sistema asigna al contenedor un trozo de memoria de tamaño adecuado para contener cierto número de elementos; espacio que es utilizando hasta que se agota. A partir de aquí, cada nueva demanda origina la asignación una zona de doble tamaño que la anterior. Por ejemplo, supongamos que para gestionar un vector de enteros, el compilador asigna inicialmente espacio para un máximo de 16 miembros.  Cuando se agotara, se realizaría una nueva asignación de espacio para 32 miembros, e inmediatamente se efectuaría una recolocación del contenido actual en el nuevo espacio y la liberación del primitivo. Si el nuevo contenedor quedara lleno de nuevo, la siguiente asignación sería capaz de 64 miembros y así sucesivamente.&lt;br /&gt;
El factor de aumento de tamaño puede ser cualquiera. Muchos compiladores utilizan un factor 1.5 cada vez que deben ampliar el espacio necesario.&lt;br /&gt;
Cada nueva recolocación implica varios pasos:&lt;br /&gt;
•	Asignación de memoria al estilo malloc() de la librería clásica en cantidad suficiente para el nuevo tamaño.&lt;br /&gt;
•	Copia de los elementos actuales en la nueva localización. Los elementos son colocados en la nueva situación utilizando el constructor copia.&lt;br /&gt;
•	Actualización de las estructuras internas del nuevo contenedor (sistema de índices).&lt;br /&gt;
•	Eliminación de los elementos originales mediante invocación sucesiva de sus correspondientes destructores.&lt;br /&gt;
•	Liberación de la memoria utilizada por las estructuras internas.&lt;br /&gt;
•	Liberación de la zona original mediante una invocación al estilo free de la librería clásica.&lt;br /&gt;
&lt;br /&gt;
En general, al referirse al tamaño de un contenedor existen tres magnitudes distintas aunque relacionadas, cuyos valores pueden obtenerse mediante tres métodos:&lt;br /&gt;
•	El número de elementos contenidos actualmente. size()&lt;br /&gt;
•	El máximo número de elementos que pueden alcanzarse actualmente sin necesidad de una nueva recolocación. capacity()&lt;br /&gt;
•	El máximo número de elementos que pueden alcanzarse en cualquier caso. max_size().&lt;br /&gt;
Ejemplo:&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {         // ================&lt;br /&gt;
vector&amp;lt;int&amp;gt; vInt;&lt;br /&gt;
for (int i=0; i &amp;lt; 100; i++) vInt.push_back(i);&lt;br /&gt;
&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;Tamaño actual:   &amp;quot; &amp;lt;&amp;lt; vInt.size()     &amp;lt;&amp;lt; endl;&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;Capacidad actual: &amp;quot; &amp;lt;&amp;lt; vInt.capacity() &amp;lt;&amp;lt; endl;&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;Tamano maximo:   &amp;quot; &amp;lt;&amp;lt; vInt.max_size() &amp;lt;&amp;lt; endl;&lt;br /&gt;
return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
Tamaño actual: 100&lt;br /&gt;
Capacidad actual: 256&lt;br /&gt;
Tamano maximo: 1073741823&lt;br /&gt;
En todos los casos: size() &amp;lt;= capacity()&lt;br /&gt;
Es posible comprobar si un contenedor está vacío, comparando su tamaño actual size() con cero, aunque es más rápido utilizar el método empty(), que devuelve true si realmente size() == 0.&lt;br /&gt;
=== Reserva de espacio ==&lt;br /&gt;
Como puede suponer, cada recolocación supone un proceso considerable, sobre todo en contenedores muy grandes. Para evitar sus inconvenientes si se conoce de antemano el tamaño máximo a utilizar, la STL ofrece la posibilidad de preasignar un espacio arbitrario. Para esto se dispone del método reserve(n), que garantiza la asignación de espacio inicial suficiente para alojar n miembros en el contenedor. Si el argumento n es mayor que la capacidad actual, se produce una recolocación y el nuevo argumento determina la nueva capacidad. Si es menor no se produce ninguna acción.&lt;br /&gt;
Ejemplo, para crear un vector de enteros capaz para al menos 1000 miembros:&lt;br /&gt;
vector &amp;lt;int&amp;gt; v;&lt;br /&gt;
v.reserve(1000);&lt;br /&gt;
&lt;br /&gt;
En el siguiente ejemplo se muestran los resultados compilado con Borland C++ 5.5 para Win32; con MS Visual C++ 6.0 y con GNU gcc 2.95.3 para Linux:&lt;br /&gt;
// resultados con:         BC++   VC++   GNU   &lt;br /&gt;
vector&amp;lt;int&amp;gt; v;&lt;br /&gt;
cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 0      0      0   &lt;br /&gt;
cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 0      0      0&lt;br /&gt;
v.push_back(3);&lt;br /&gt;
cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    1      1&lt;br /&gt;
v.reserve(100);&lt;br /&gt;
cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    100    100&lt;br /&gt;
=== Operaciones sobre contenedores ===&lt;br /&gt;
Los elementos de un contenedor son colocados en él utilizando el constructor copia, aunque algunas operaciones requieren la existencia de un constructor por defecto. A su vez, los algoritmos genéricos, como copy(), que copian a un contenedor, utilizan el operador de asignación.&lt;br /&gt;
Por ejemplo, cuando se duplica todo un contenedor de tipos T por invocación del constructor copia o por asignación, cada miembro es copiado en la nueva estructura utilizando el constructor copia o el operador de asignación. Tanto si una copia profunda o una copia somera, el resultado es controlado por el programador, que puede proporcionar el operador de asignación para el tipo T con cualquier significado que desee. Si se ha definido un destructor para el tipo T, este destructor es invocado cada vez que deba ser eliminado un elemento del contenedor. Cuando se destruye toda la colección, el destructor es invocado por cada elemento que permaneciera almacenado.&lt;br /&gt;
Debemos añadir algunas palabras acerca de los contenedores que almacenan colecciones de punteros. Estos conjuntos no son raros. Por ejemplo, una colección de punteros es el único medio de almacenar valores que pueden representar indistintamente instancias de una clase o instancias de una subclase. Puede encontrarse una de estas colecciones en el ejemplo de simulación manejada por eventos (  xxx).&lt;br /&gt;
En estos casos, el contenedor es solamente responsable de mantener los propios punteros, siendo responsabilidad del programador manejar la memoria de los valores referenciados por estos, lo que supone que los espacios de memoria son asignados correctamente; por lo general mediante el operador new; que no son desasignados mientras el contenedor albergue referencias a ellos, y que sean adecuadamente desasignados una vez que han sido eliminados del contenedor.&lt;br /&gt;
===  Secuencias ===&lt;br /&gt;
Las secuencias son estructuras de datos de tipo lineal, con posibilidad de que su tamaño puede ser alterado insertando elementos al principio, al final o en cualquier posición, si bien la idoneidad en este sentido es distinta entre los diversos tipos.&lt;br /&gt;
La STL ofrece los siguientes:&lt;br /&gt;
•	deque&lt;br /&gt;
•	list&lt;br /&gt;
•	stack&lt;br /&gt;
•	vector&lt;br /&gt;
•	vector&amp;lt;bool&amp;gt;&lt;br /&gt;
La estructura lineal implica que sus datos son lógicamente contiguos, aunque su disposición física puede que no lo sea. Los elementos pueden ser accedidos por un índice numérico, aunque en algunos tipos de secuencia el acceso a un elemento implica un recorrido por la lista.&lt;br /&gt;
== Contenedores asociativos ==&lt;br /&gt;
Los contenedores asociativos son una extensión de las secuencias. Mientras que en estas para acceder a los elementos solo pueden utilizarse claves numéricas, que señalan el número de orden del elemento dentro de la secuencia (al estilo de los índices en las matrices). Los contenedores asociativos admiten cualquier tipo de clave de acceso. Las más frecuentes son las cadenas alfanuméricas (stings).&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, razón por la que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.&lt;br /&gt;
La ordenación se realiza según los valores de ciertos miembros del contenedor. Estos elementos son denominados &amp;quot;de claves&amp;quot; (&amp;quot;Key values&amp;quot;). Lo que exige que los objetos &amp;quot;de clave&amp;quot; sean de un tipo para el que estén definidos los operadores relacionales. El contenedor es mantenido ordenado de forma automática por los algoritmos de inserción y borrado.&lt;br /&gt;
La STL proporciona cinco tipo distintos, aunque en realidad son tres clases; dos de ellas en dos variedades (permitiendo o no claves duplicadas). Uno de los tipos (bitset) sirve para almacenar campos de bits de longitud constante. Los otros dos permiten elementos ordenados de cualquier tipo (set y multiset), mientras que map y multimap permiten alojar pares de elementos. Uno que actúa como &amp;quot;Key value&amp;quot; y otro que puede ser un tipo cualquiera al que llamaremos valor-dato.&lt;br /&gt;
•	bitset&lt;br /&gt;
•	set&lt;br /&gt;
•	multiset&lt;br /&gt;
•	map&lt;br /&gt;
•	multimap&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave, y para recorrer el conjunto (ordenado) de las claves.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http://www.zator.com/Cpp/E5_1_1.htm Contenerores C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Contenedores en C.conclase.net]&lt;br /&gt;
* [https://docs.microsoft.com/es-es/cpp/standard-library/stl-containers?view=vs-2017  Contenedores de la biblioteca estándar de C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234193</id>
		<title>Contenedores C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234193"/>
		<updated>2018-11-29T17:50:11Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Contenedores C++ |imagen=  |concepto= En sentido C++ estricto, un contenedor de la STL es una clase genérica que puede instanciarse para representar diversos tipos de objetos. Esta clase incluye ciertas operaciones  sobre los objetos de su tipo; estas operaciones están representadas por funciones-miembro, incluyendo constructores y funciones-operador, que son a su vez funciones genéricas}}''' Contenedores C++ '''. Al mismo tiempo, desde el punto de vista de las teorías de la información, podemos considerarlos estructuras de datos más o menos adecuadas (según el caso) para aplicarles ciertos algoritmos.&lt;br /&gt;
De su propio nombre (&amp;quot;Containers&amp;quot;) podemos deducir que su misión principal, y razón de su existencia, es su función como estructuras de datos, y en este sentido podemos adelantar que entre sus funcionalidades más destacadas se encuentran la gestión del espacio de almacenamiento necesario.&lt;br /&gt;
Una de las primerísimas ventajas de la utilización de contenedores es que el programador no tiene que enredarse con las cuestiones siempre espinosas de asignar o liberar memoria para los objetos creados, de forma que queda liberado de los [[Operadores|operadores]] [[Operador new|new]] y [[Operador delete|delete]].&lt;br /&gt;
== Filosofía de uso ==&lt;br /&gt;
Una primera pincelada sobre la filosofía de uso de los contenedores mediante un sencillo ejemplo: si tenemos que manejar un conjunto de enteros, puede utilizarse una matriz de enteros, pero ya hemos señalado  que esta estructura nos obliga a conocer de antemano la cantidad de datos a almacenar (el tamaño de la matriz). En consecuencia, si el número de datos puede variar, esta opción no es muy adecuada. Además, si es importante mantener los datos ordenados, la utilización de una matriz nos obligaría a ingeniar por nuestra cuenta la forma de hacerlo; seguramente mediante complicadas rutinas de &amp;quot;sort&amp;quot; hechas manualmente.&lt;br /&gt;
&lt;br /&gt;
Una alternativa es utilizar como &amp;quot;contenedor&amp;quot; para nuestros enteros una clase genérica de la STL denominada vector. En este caso, serían posibles expresiones como las siguientes:&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;int&amp;gt; v(3);         // L1:&lt;br /&gt;
v[0] = 7;                 // L2:&lt;br /&gt;
v[1] = v[0] + 1;          // L3:&lt;br /&gt;
v[2] = v[0] + v[1];       // L4:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Al encontrar la primera sentencia, el compilador crea una instancia (especialidad) anónima de la plantilla vector para alojar enteros; a continuación una instancia de ella para alojar tres enteros, a la que denominamos v.&lt;br /&gt;
&lt;br /&gt;
Una primera inspección de las sentencias L2 a L3, nos muestra que la clase ofrece la posibilidad de utilizar con sus miembros el operador subíndice de matriz [ ]. Deducimos por tanto, que dispone de una versión sobrecargada de este operador para los miembros de la clase, lo que nos permite utilizar el objeto v como una matriz, aunque con algunas funcionalidades no incluidas en aquellas.&lt;br /&gt;
&lt;br /&gt;
Después de L4 los valores finales para los miembros de nuestra &amp;quot;matriz&amp;quot; serian:&lt;br /&gt;
v[0] == 7, v[1] == 8, v[2] == 15&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Si deseamos invertir el orden de los elementos de nuestra matriz. Para ello utilizamos una [[Función (programación)|función]] especial:&lt;br /&gt;
reverse(v.begin(), v.end());&lt;br /&gt;
después de lo cual, el orden de miembros sería:&lt;br /&gt;
 v[0] == 15, v[1] == 8, v[2] == 7&lt;br /&gt;
&lt;br /&gt;
La primera observación es que la función reverse utiliza dos argumentos, que son a su vez el valor devuelto por sendos métodos de clase (los aplicamos sobre nuestro objeto v).  El valor devuelto por estos métodos es lo que se conoce como un [[Iteradores (Programación)|iterador]]; una especie de puntero que señalan al interior de la estructura de datos representada por el contenedor v. En este caso, el primer iterador señala al primer miembro y el segundo a una posición después del último; de esta forma se indican los miembros inicial y final entre los que se realizará la operación de inversión efectuada por reverse.&lt;br /&gt;
&lt;br /&gt;
La segunda observación es que la función reverse no es un método de clase, sino una función global; es lo que denominamos un [[Algoritmo|algoritmo]]. Esta función tiene la peculiaridad de que puede ser aplicado sobre el contenedor vector (y algún otro); que opera sobre un rango de los elementos del contenedor, en nuestro caso sobre la totalidad (esta capacidad de operar sobre una parte de un contenedor es característica de los algoritmos). También que pueden operar sobre otros contenedores produciendo un efecto similar. Por ejemplo, el algoritmo reverse puede operar incluso sobre una simple matriz:&lt;br /&gt;
 char Ch[5] = { 'A', 'E', 'I', 'O', 'U' };&lt;br /&gt;
 reverse(Ch, Ch + 5);&lt;br /&gt;
 for (int i = 0; i &amp;lt; 5; ++i) cout &amp;lt;&amp;lt; &amp;quot;Ch[&amp;quot; &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &amp;quot;] = &amp;quot; &amp;lt;&amp;lt; Ch[i];&lt;br /&gt;
 Salida:&lt;br /&gt;
 Ch[0] = U Ch[1] = O Ch[2] = I Ch[3] = E Ch[4] = A&lt;br /&gt;
&lt;br /&gt;
Es significativo que el objeto v es una estructura de datos que permite acceder individualmente a sus miembros &amp;quot;como si&amp;quot; fuesen elementos de una matriz. También que se pueden aplicar ciertas operaciones sobre la totalidad, o parte, de esta estructura considerada como una unidad.&lt;br /&gt;
== Clasificación ==&lt;br /&gt;
Existen dos tipos de contenedores: secuencias y asociativos; a su vez se subdividen según el tipo de [[Iteradores (Programación)|iterador]] que soportan.&lt;br /&gt;
&lt;br /&gt;
Las secuencias almacenan los elementos en orden secuencial (de ahí su nombre). El contenedor agrupa a todos sus miembros como una sucesión lineal, y en consecuencia son adecuadas para accesos directos y secuenciales. Un ejemplo de secuencia es una matriz. De hecho, los algoritmos que pueden aplicarse a las secuencias pueden aplicarse también a las matrices.&lt;br /&gt;
&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, por lo que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.  La STL proporciona cinco tipos distintos.&lt;br /&gt;
&lt;br /&gt;
La existencia de índices supone una ordenación según los valores de un conjunto de elementos (denominado &amp;quot;de claves&amp;quot;) para el que debe existir un criterio de ordenación. Dicho en otras palabras, los objetos &amp;quot;de clave&amp;quot; deben ser de un tipo para el que estén definidos los operadores relacionales. El árbol es mantenido ordenado de forma automática por los algoritmos de inserción y borrado del contenedor.&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave y para recorrer el conjunto (ordenado) de los elementos.&lt;br /&gt;
&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] contiene diez formas de contenedores y tres adaptadores de contenedor (denominados simplemente [[Adapter|adaptadores]]). En esta sección se expondrán brevemente cuales son estas formas; sus características, y cuál es la más adecuada para cada tipo de problema específico. En secciones sucesivas se comentarán individualmente con mayor detalle.&lt;br /&gt;
Relación siguiendo la clasificación utilizada en el Estándar:&lt;br /&gt;
  •	Secuencias&lt;br /&gt;
      o	deque&lt;br /&gt;
      o	list&lt;br /&gt;
      o	stack&lt;br /&gt;
      o	vector&lt;br /&gt;
      o	vector &amp;lt;bool&amp;gt;&lt;br /&gt;
  •	adaptadores&lt;br /&gt;
      o	queue&lt;br /&gt;
      o	priority_queue&lt;br /&gt;
  •	Contenedores asociativos&lt;br /&gt;
      o	map&lt;br /&gt;
      o	multimap&lt;br /&gt;
      o	set&lt;br /&gt;
      o	multiset&lt;br /&gt;
      o	bitset&lt;br /&gt;
== Características ==&lt;br /&gt;
Las características más significativas de las diversas formas de contenedor son:&lt;br /&gt;
&lt;br /&gt;
Contenedor	Características&lt;br /&gt;
&lt;br /&gt;
Secuencias&lt;br /&gt;
&lt;br /&gt;
 vector: Este contenedor es una estructura de datos de tamaño fijo preferentemente. Aunque la STL proporciona herramientas para cambiar el tamaño de un vector de forma dinámica, esta operación es costosa y debe ser evitada dentro de lo posible (en este sentido el vector se comporta como una matriz ordinaria). &lt;br /&gt;
&lt;br /&gt;
Disponen de un buén mecanismo de acceso aleatorio a elementos y de un mecanismo de inserción al final muy eficiente.&lt;br /&gt;
Generalmente es preferible utilizar un vector que un deque o un list, a menos que sea frecuentemente necesario insertar datos al comienzo o al final, en cuyo caso es mejor utilizar un deque.  Si por el contrario es frecuente la inserción de elementos en el centro, entonces es preferible un list.&lt;br /&gt;
&lt;br /&gt;
 vector&amp;lt;bool&amp;gt;:	Es una versión de la anterior especial para valores binarios (bits).&lt;br /&gt;
&lt;br /&gt;
 list: Este contenedor responde a la idéa intuitiva de &amp;quot;lista&amp;quot;, el almacenamiento de objetos en una secuencia lineal que no está necesariamente ordenada (aunque sus miembros pueden ser ordenados fácilmente mediante la función-miembro sort() ). Estos contenedores suelen ser implementados como listas doblemente enlazadas. &lt;br /&gt;
&lt;br /&gt;
Dispone de mecanismos eficientes para insertar elementos al principio, al final o en cualquier posición (utilizando iteradores que denoten posición). Estas operaciones consumen un tiempo constante con independencia del número de elmentos albergados en el contenedor.&lt;br /&gt;
&lt;br /&gt;
Dado que son estructuras lineales, en general los elementos no pueden ser accedidos por subíndices como en un vector.  Es necesario realizar un recorrido lineal por todos los valores, por lo que en las operaciones de acceso se utilizan tiempos proporcionales al número de elementos.&lt;br /&gt;
&lt;br /&gt;
 stack: Contenedor de elementos tipo pila LIFO que permite inserciones y eliminaciones solo en la parte superior.&lt;br /&gt;
&lt;br /&gt;
 deque: Los deques o colas de doble terminación (&amp;quot;Double-ended queue&amp;quot;) son un tipo de estructura de datos que comparte las características de las colas (&amp;quot;Queues&amp;quot;) y las pilas (&amp;quot;Stacks&amp;quot;). Como en las colas , los elementos pueden ser empujados por un extremo al interior del contenedor, y el primer elemento introducido puede ser extraído por el extremo opuesto. Al mismo tiempo, el último elemento introducido por el principio puede ser extraído en ese mismo extremo como si fuese una pila.&lt;br /&gt;
 &lt;br /&gt;
Estos contenedores suelen ser implementados bajo la forma de matrices bidimensionales.&lt;br /&gt;
&lt;br /&gt;
Las características de los deques implementados en la STL pueden resumirse en: Acceso aleatorio; mecanismo eficiente de inserción al principio o al final.&lt;br /&gt;
&lt;br /&gt;
 string: Contenedor de caracteres adaptado a operaciones con cadenas de caracteres.&lt;br /&gt;
&lt;br /&gt;
Asociaciones&lt;br /&gt;
&lt;br /&gt;
 set: Como el resto de contenedores asociativos, esta forma de contenedor mantiene los elementos en orden. Dispone de mecanismos eficientes para inclusión, inserción y eliminación de elementos, y soporta claves únicas (solo puede existir un miembro con una clave determinada).&lt;br /&gt;
&lt;br /&gt;
 multiset: Versión del anterior que permite la existencia de claves duplicadas. Es decir, distintos elementos dentro del conjunto pueden responder a la misma clave.&lt;br /&gt;
&lt;br /&gt;
 bitset: Contenedor de bit más orientado al tamaño que hacia el tipo de contenido. Permite almacenar secuencias de bits de tamaño fijo. No existen iteradores para reccorrerlas, y sus elementos se acceden utilizando el operador subíndice.&lt;br /&gt;
 &lt;br /&gt;
Se dispone de varias funciones para realizar con ellos operaciones de bits.&lt;br /&gt;
 &lt;br /&gt;
 map: Como el resto de estructuras asociativas, el map mantiene sus elementos ordenados. Se caracteriza porque sus miembros son pares de valores que pueden ser de tipos distintos. Uno de ellos, el que actúa como clave para el índice (&amp;quot;Key-value&amp;quot;), puede ser de cualquier tipo, a condición de que sus elementos puedan ser ordenados según un criterio (por defecto se utiliza el operador &amp;lt;).&lt;br /&gt;
 &lt;br /&gt;
Permite claves únicas. Es decir, que solo puede existir un miembro para cada clave. Dispone de mecanismos de inserción y borrado muy eficientes y no existe límite de tamaño. La estructura se encarga de crecer y disminuir en concordancia con las necesidades de sus miembros. Permite el operador [ ] subíndice para los elementos de la clave así como otras técnicas de acceso.&lt;br /&gt;
&lt;br /&gt;
Estas estructuras de datos recibe también los nombres de diccionarios, tablas y matrices asociativas, en referencia a que pueden considerarse como dos matrices del mismo número de elementos, en las que existe una relación entre cada miembro de una con otro miembro de la otra.  Una de las matrices (que actúa de índice) estaría ordenada según su contenido.&lt;br /&gt;
&lt;br /&gt;
 multimap: En todo igual que el anterior pero permitiendo además claves duplicadas. Es decir, que una misma clave pueda estar asociada a dos &amp;quot;valores&amp;quot; distintos.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Adaptador	Características&lt;br /&gt;
&lt;br /&gt;
 queue: Contenedor tipo cola FIFO que permite inserciones al final y eliminaciones al principio.&lt;br /&gt;
&lt;br /&gt;
 priority queue: Este contenedor dispone de mecanismos eficientes para acceso y eliminación de grandes valores.&lt;br /&gt;
&lt;br /&gt;
== Seleccionar un contenedor ==&lt;br /&gt;
El binomio contendor-iterador conforma una herramienta que se adapta a circunstancias muy variadas. Es posible que un determinado problema pueda ser abordado de varias formas, en estos casos la selección de la forma de contenedor más adecuado depende de las circunstancias. En ciertas ocasiones puede resultar bastante obvia; en otras puede no estar tan claro cuál es la mejor opción, pues &amp;quot;a priori&amp;quot;, pueden adaptarse varias formas al caso concreto. Puede utilizarse el sistema de prueba y comparación. Por ejemplo, cronometrando los resultados obtenidos en un modo u otro. También será de gran ayuda la experiencia, pero como una guía o criterio general puede utilizarse el principio de selección que se indica a continuación.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| fila 1, celda 1&lt;br /&gt;
| fila 1, celda 2&lt;br /&gt;
| fila 1, celda 3&lt;br /&gt;
|-&lt;br /&gt;
| fila 2, celda 1&lt;br /&gt;
| fila 2, celda 2&lt;br /&gt;
| fila 2, celda 3&lt;br /&gt;
|}&lt;br /&gt;
Como se accederá a los datos?	Si es importante un acceso aleatorio, pueden utilizarse un vector o un deque. Si basta con un acceso secuencial cualquiera de los dos puede ser el elegido.&lt;br /&gt;
&lt;br /&gt;
Es importante el orden en que serán mantenidos los valores dentro de la colección de datos?	Existen muchas formas de secuenciar los valores. Si es importante un orden estricto a lo largo de toda la vida del contenedor, la elección obvia es un set, dado que las inserciones en una de estas estructuras se realizan automáticamente en orden. &lt;br /&gt;
Si este orden es importante solo en algún momento, por ejemplo al final de una serie de inserciones, puede ser más sencillo colocar los valores en un list o vector para ordenar más tarde el resultado en el momento necesario.&lt;br /&gt;
Si el orden en que se almacenan los valores en la estructura está relacionado con el orden de su inserción, entonces un stack, un queue o un list pueden ser la mejor elección.&lt;br /&gt;
Puede variar mucho el tamaño de la estructura de datos durante el curso de la ejecución del programa?	Si es así, entonces puede ser que la mejor opción sean un list o un set. Un vector o un deque pueden conducir a mantener un gran almacenamiento intermedio (buffer); incluso después que los elementos hayan sido eliminados de la colección de datos. Estos dos contenedores no son adecuados para cambios de tamaño, aunque vector dispone de un mecanismo de inserción al final eficiente. &lt;br /&gt;
Recíprocamente: si el tamaño de la colección se mantiene relativamente estable, entonces un vector o un deque pueden utilizar menos memoria que un list o un set que almacenen el mismo número de elementos.&lt;br /&gt;
Es posible determinar el tamaño de la colección?	La estructura de datos vector proporciona un medio para pre-seleccionar un bloque de memoria de un tamaño específico con la función miembro reserve, posibilidad que no existe en otros contenedores.&lt;br /&gt;
Es frecuente tener que comprobar si un valor cualquiera está incluido en la colección?	En este caso, un contenedor set o map pueden ser buena elección. En estos casos comprobar si un determinado valor está incluido puede ser realizado con un pequeño número de pasos (logarítmicos con el tamaño del contenedor). Mientras que la misma verificación en cualquiera de los otros tipos puede requerir comparar el valor con cada elemento almacenado en el contenedor.&lt;br /&gt;
Está indexada la colección de datos? 	Si las claves son enteros entre 0 y un límite superior, pueden utilizarse un vector o un deque. &lt;br /&gt;
Si es así, puede ser vista la colección como una serie de pares clave/valor?	Si la clave es algún otro valor, como cadenas de caracteres o tipos definidos por el usuario, puede utilizarse un contenedor map.&lt;br /&gt;
Pueden los valores estar relacionados unos con otros?	Todos los valores almacenados en cualquier contenedor de la STL debe ser capaz de comprobar la igualdad con cualquier otro valor similar, pero recuerde que no todos son capaces de reconocer el operador de relación menor-que; sin embargo, si los valores no pueden ser ordenados utilizando el operador menor-que, no pueden ser almacenados en un set o en un map.&lt;br /&gt;
Es una operación frecuente tener que encontrar y eliminar el valor mayor de la colección?	En caso afirmativo, la estructura de datos más idónea es el priority queue.&lt;br /&gt;
En que posiciones son insertados o eliminados los elementos de la estructura?	Si los valores son añadidos o eliminados en la zona interior, entonces la mejor opción es un list. &lt;br /&gt;
Si los valores son insertados solo al comienzo, un deque o un list pueden ser lo más adecuado.&lt;br /&gt;
Si los valores son insertados y eliminados solo al final, un stack o un queue pueden ser elecciones lógicas.&lt;br /&gt;
Es frecuente tener que refundir dos o más secuencias en una sola?	En caso afirmativo, puede considerarse que las mejores opciones son un set o un list, dependiendo que la colección deba o no ser mantenida en orden. &lt;br /&gt;
Refundir dos set es una operación muy eficiente.  Si la colección de datos no está ordenada, pero puede utilizarse la función miembro splice() de las list (que es muy eficiente), entonces es preferible este último tipo de contenedor, dado que esta operación no está contemplada en las demás formas.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Tipos no incluidos ===&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] incluye contenedores adecuados para la mayoría de los casos prácticos, aunque quizás existen una serie de estructuras de datos clásicas que no han sido incluidas. En la mayoría de los casos, la causa es que los contenedores proporcionados pueden ser fácilmente adaptados para suplir los usos facilitados por los tipos omitidos.&lt;br /&gt;
Tipos clásicos no incluidos y la sustitución más fácil.&lt;br /&gt;
Contenedor omitido	Sustitución utilizando elementos de STL&lt;br /&gt;
tree	El modo set está implementado internamente como un árbol de búsqueda binaria. &lt;br /&gt;
Para la mayoría de los casos prácticos que pueden ser resueltos utilizando árboles este modo es un sustituto adecuado.&lt;br /&gt;
matrices multidimensionales	Puesto que los vectores pueden almacenar elementos que sean otros vectores, estas estructuras pueden ser construidas fácilmente.&lt;br /&gt;
graph	La representación de un gráfico puede ser fácilmente construida como un map que contiene otros map. Un map cuyos elementos son a su vez maps, es la representación natural de un gráfico directo. Por ejemplo, supongamos que utilizamos cadenas de caracteres para codificar nombres de ciudades, y que deseamos construir un map donde el valor asociado con un borde es la distancia entre dos ciudades conectadas. &lt;br /&gt;
Se puede crear uno de estos gráficos como se muestra en el ejemplo (  xxx)&lt;br /&gt;
sparse array	Una novedosa sustitución es la representación de un gráfico.&lt;br /&gt;
hash table	Las tablas hash proporcionan un tiempo de acceso constante, así como inserción y borrado de elementos, convirtiendo estas operaciones en operaciones de índice. &lt;br /&gt;
Una tabla hash puede ser construida fácilmente como un vector (o deque) cuyos elementos son lists (o incluso sets).  En el ejemplo de la ordenación raíz (  xxx) se describe una de estas estructuras (un vector de deques), aunque en este ejemplo no incluye invocación la función hash para convertir un valor en un índice.&lt;br /&gt;
Funcionalidad set	En la STL, los tipos set están específicamente ordenados, y sus operaciones (como la unión intersección, etc.) no pueden ser realizadas sobre colecciones de valores no ordenados (por ejemplo un conjunto de números complejos). &lt;br /&gt;
Una list puede ser utilizada como sustituto, aunque es necesario escribir funciones de operación especiales, dado que los algoritmos genéricos no pueden ser utilizados con listas.&lt;br /&gt;
== Gestión de memoria ==&lt;br /&gt;
La gestión de memoria realizada por los contenedores comprende tanto la asignación y liberación de espacio para sus miembros, como para las claves que constituyen el sistema de índice de algunos tipos de contenedor. En general los algoritmos de la STL están muy optimizados y el sistema de asignación de memoria intenta compaginar rapidez y eficacia. La primera exige asignar y desasignar espacio cada vez que se introduce o elimina un miembro del contenedor. La eficacia, e incluso la disminución de la fragmentación inherentes al manejo del montón, exige asignar y rehusar trozos de memoria lo más grandes posible cada vez. El abordaje a este problema se ha realizado de dos formas básicas: (a) Contenedores que no pueden alterar su tamaño, de forma que la asignación de espacio para sus elementos debe realizarse en el momento de su declaración. (b) Contenedores que pueden crecer y/o disminuir en consonancia con los elementos a albergar.&lt;br /&gt;
Refiriéndonos al caso (b), para balancear estas exigencias contrapuestas, algunas implementaciones utilizan el siguiente esquema de trabajo: inicialmente el sistema asigna al contenedor un trozo de memoria de tamaño adecuado para contener cierto número de elementos; espacio que es utilizando hasta que se agota. A partir de aquí, cada nueva demanda origina la asignación una zona de doble tamaño que la anterior. Por ejemplo, supongamos que para gestionar un vector de enteros, el compilador asigna inicialmente espacio para un máximo de 16 miembros.  Cuando se agotara, se realizaría una nueva asignación de espacio para 32 miembros, e inmediatamente se efectuaría una recolocación del contenido actual en el nuevo espacio y la liberación del primitivo. Si el nuevo contenedor quedara lleno de nuevo, la siguiente asignación sería capaz de 64 miembros y así sucesivamente.&lt;br /&gt;
El factor de aumento de tamaño puede ser cualquiera. Muchos compiladores utilizan un factor 1.5 cada vez que deben ampliar el espacio necesario.&lt;br /&gt;
Cada nueva recolocación implica varios pasos:&lt;br /&gt;
•	Asignación de memoria al estilo malloc() de la librería clásica en cantidad suficiente para el nuevo tamaño.&lt;br /&gt;
•	Copia de los elementos actuales en la nueva localización. Los elementos son colocados en la nueva situación utilizando el constructor copia.&lt;br /&gt;
•	Actualización de las estructuras internas del nuevo contenedor (sistema de índices).&lt;br /&gt;
•	Eliminación de los elementos originales mediante invocación sucesiva de sus correspondientes destructores.&lt;br /&gt;
•	Liberación de la memoria utilizada por las estructuras internas.&lt;br /&gt;
•	Liberación de la zona original mediante una invocación al estilo free de la librería clásica.&lt;br /&gt;
&lt;br /&gt;
En general, al referirse al tamaño de un contenedor existen tres magnitudes distintas aunque relacionadas, cuyos valores pueden obtenerse mediante tres métodos:&lt;br /&gt;
•	El número de elementos contenidos actualmente. size()&lt;br /&gt;
•	El máximo número de elementos que pueden alcanzarse actualmente sin necesidad de una nueva recolocación. capacity()&lt;br /&gt;
•	El máximo número de elementos que pueden alcanzarse en cualquier caso. max_size().&lt;br /&gt;
Ejemplo:&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {         // ================&lt;br /&gt;
vector&amp;lt;int&amp;gt; vInt;&lt;br /&gt;
for (int i=0; i &amp;lt; 100; i++) vInt.push_back(i);&lt;br /&gt;
&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;Tamaño actual:   &amp;quot; &amp;lt;&amp;lt; vInt.size()     &amp;lt;&amp;lt; endl;&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;Capacidad actual: &amp;quot; &amp;lt;&amp;lt; vInt.capacity() &amp;lt;&amp;lt; endl;&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;Tamano maximo:   &amp;quot; &amp;lt;&amp;lt; vInt.max_size() &amp;lt;&amp;lt; endl;&lt;br /&gt;
return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
Tamaño actual: 100&lt;br /&gt;
Capacidad actual: 256&lt;br /&gt;
Tamano maximo: 1073741823&lt;br /&gt;
En todos los casos: size() &amp;lt;= capacity()&lt;br /&gt;
Es posible comprobar si un contenedor está vacío, comparando su tamaño actual size() con cero, aunque es más rápido utilizar el método empty(), que devuelve true si realmente size() == 0.&lt;br /&gt;
=== Reserva de espacio ==&lt;br /&gt;
Como puede suponer, cada recolocación supone un proceso considerable, sobre todo en contenedores muy grandes. Para evitar sus inconvenientes si se conoce de antemano el tamaño máximo a utilizar, la STL ofrece la posibilidad de preasignar un espacio arbitrario. Para esto se dispone del método reserve(n), que garantiza la asignación de espacio inicial suficiente para alojar n miembros en el contenedor. Si el argumento n es mayor que la capacidad actual, se produce una recolocación y el nuevo argumento determina la nueva capacidad. Si es menor no se produce ninguna acción.&lt;br /&gt;
Ejemplo, para crear un vector de enteros capaz para al menos 1000 miembros:&lt;br /&gt;
vector &amp;lt;int&amp;gt; v;&lt;br /&gt;
v.reserve(1000);&lt;br /&gt;
&lt;br /&gt;
En el siguiente ejemplo se muestran los resultados compilado con Borland C++ 5.5 para Win32; con MS Visual C++ 6.0 y con GNU gcc 2.95.3 para Linux:&lt;br /&gt;
// resultados con:         BC++   VC++   GNU   &lt;br /&gt;
vector&amp;lt;int&amp;gt; v;&lt;br /&gt;
cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 0      0      0   &lt;br /&gt;
cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 0      0      0&lt;br /&gt;
v.push_back(3);&lt;br /&gt;
cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    1      1&lt;br /&gt;
v.reserve(100);&lt;br /&gt;
cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    100    100&lt;br /&gt;
=== Operaciones sobre contenedores ===&lt;br /&gt;
Los elementos de un contenedor son colocados en él utilizando el constructor copia, aunque algunas operaciones requieren la existencia de un constructor por defecto. A su vez, los algoritmos genéricos, como copy(), que copian a un contenedor, utilizan el operador de asignación.&lt;br /&gt;
Por ejemplo, cuando se duplica todo un contenedor de tipos T por invocación del constructor copia o por asignación, cada miembro es copiado en la nueva estructura utilizando el constructor copia o el operador de asignación. Tanto si una copia profunda o una copia somera, el resultado es controlado por el programador, que puede proporcionar el operador de asignación para el tipo T con cualquier significado que desee. Si se ha definido un destructor para el tipo T, este destructor es invocado cada vez que deba ser eliminado un elemento del contenedor. Cuando se destruye toda la colección, el destructor es invocado por cada elemento que permaneciera almacenado.&lt;br /&gt;
Debemos añadir algunas palabras acerca de los contenedores que almacenan colecciones de punteros. Estos conjuntos no son raros. Por ejemplo, una colección de punteros es el único medio de almacenar valores que pueden representar indistintamente instancias de una clase o instancias de una subclase. Puede encontrarse una de estas colecciones en el ejemplo de simulación manejada por eventos (  xxx).&lt;br /&gt;
En estos casos, el contenedor es solamente responsable de mantener los propios punteros, siendo responsabilidad del programador manejar la memoria de los valores referenciados por estos, lo que supone que los espacios de memoria son asignados correctamente; por lo general mediante el operador new; que no son desasignados mientras el contenedor albergue referencias a ellos, y que sean adecuadamente desasignados una vez que han sido eliminados del contenedor.&lt;br /&gt;
===  Secuencias ===&lt;br /&gt;
Las secuencias son estructuras de datos de tipo lineal, con posibilidad de que su tamaño puede ser alterado insertando elementos al principio, al final o en cualquier posición, si bien la idoneidad en este sentido es distinta entre los diversos tipos.&lt;br /&gt;
La STL ofrece los siguientes:&lt;br /&gt;
•	deque&lt;br /&gt;
•	list&lt;br /&gt;
•	stack&lt;br /&gt;
•	vector&lt;br /&gt;
•	vector&amp;lt;bool&amp;gt;&lt;br /&gt;
La estructura lineal implica que sus datos son lógicamente contiguos, aunque su disposición física puede que no lo sea. Los elementos pueden ser accedidos por un índice numérico, aunque en algunos tipos de secuencia el acceso a un elemento implica un recorrido por la lista.&lt;br /&gt;
== Contenedores asociativos ==&lt;br /&gt;
Los contenedores asociativos son una extensión de las secuencias. Mientras que en estas para acceder a los elementos solo pueden utilizarse claves numéricas, que señalan el número de orden del elemento dentro de la secuencia (al estilo de los índices en las matrices). Los contenedores asociativos admiten cualquier tipo de clave de acceso. Las más frecuentes son las cadenas alfanuméricas (stings).&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, razón por la que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.&lt;br /&gt;
La ordenación se realiza según los valores de ciertos miembros del contenedor. Estos elementos son denominados &amp;quot;de claves&amp;quot; (&amp;quot;Key values&amp;quot;). Lo que exige que los objetos &amp;quot;de clave&amp;quot; sean de un tipo para el que estén definidos los operadores relacionales. El contenedor es mantenido ordenado de forma automática por los algoritmos de inserción y borrado.&lt;br /&gt;
La STL proporciona cinco tipo distintos, aunque en realidad son tres clases; dos de ellas en dos variedades (permitiendo o no claves duplicadas). Uno de los tipos (bitset) sirve para almacenar campos de bits de longitud constante. Los otros dos permiten elementos ordenados de cualquier tipo (set y multiset), mientras que map y multimap permiten alojar pares de elementos. Uno que actúa como &amp;quot;Key value&amp;quot; y otro que puede ser un tipo cualquiera al que llamaremos valor-dato.&lt;br /&gt;
•	bitset&lt;br /&gt;
•	set&lt;br /&gt;
•	multiset&lt;br /&gt;
•	map&lt;br /&gt;
•	multimap&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave, y para recorrer el conjunto (ordenado) de las claves.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http://www.zator.com/Cpp/E5_1_1.htm Contenerores C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Contenedores en C.conclase.net]&lt;br /&gt;
* [https://docs.microsoft.com/es-es/cpp/standard-library/stl-containers?view=vs-2017  Contenedores de la biblioteca estándar de C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234176</id>
		<title>Contenedores C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Contenedores_C%2B%2B&amp;diff=3234176"/>
		<updated>2018-11-29T17:29:20Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: Página creada con «&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Contenedores C++ |imagen=  |concepto= En sentido C++ estricto, un contenedor de la STL es una clase genérica que puede instancia...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Contenedores C++ |imagen=  |concepto= En sentido C++ estricto, un contenedor de la STL es una clase genérica que puede instanciarse para representar diversos tipos de objetos. Esta clase incluye ciertas operaciones  sobre los objetos de su tipo; estas operaciones están representadas por funciones-miembro, incluyendo constructores y funciones-operador, que son a su vez funciones genéricas}}''' Contenedores C++ '''. Al mismo tiempo, desde el punto de vista de las teorías de la información, podemos considerarlos estructuras de datos más o menos adecuadas (según el caso) para aplicarles ciertos algoritmos.&lt;br /&gt;
De su propio nombre (&amp;quot;Containers&amp;quot;) podemos deducir que su misión principal, y razón de su existencia, es su función como estructuras de datos, y en este sentido podemos adelantar que entre sus funcionalidades más destacadas se encuentran la gestión del espacio de almacenamiento necesario.&lt;br /&gt;
Una de las primerísimas ventajas de la utilización de contenedores es que el programador no tiene que enredarse con las cuestiones siempre espinosas de asignar o liberar memoria para los objetos creados, de forma que queda liberado de los [[Operadores|operadores]] [[Operador new|new]] y [[Operador delete|delete]].&lt;br /&gt;
== Filosofía de uso ==&lt;br /&gt;
Una primera pincelada sobre la filosofía de uso de los contenedores mediante un sencillo ejemplo: si tenemos que manejar un conjunto de enteros, puede utilizarse una matriz de enteros, pero ya hemos señalado  que esta estructura nos obliga a conocer de antemano la cantidad de datos a almacenar (el tamaño de la matriz). En consecuencia, si el número de datos puede variar, esta opción no es muy adecuada. Además, si es importante mantener los datos ordenados, la utilización de una matriz nos obligaría a ingeniar por nuestra cuenta la forma de hacerlo; seguramente mediante complicadas rutinas de &amp;quot;sort&amp;quot; hechas manualmente.&lt;br /&gt;
&lt;br /&gt;
Una alternativa es utilizar como &amp;quot;contenedor&amp;quot; para nuestros enteros una clase genérica de la STL denominada vector. En este caso, serían posibles expresiones como las siguientes:&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;int&amp;gt; v(3);         // L1:&lt;br /&gt;
v[0] = 7;                 // L2:&lt;br /&gt;
v[1] = v[0] + 1;          // L3:&lt;br /&gt;
v[2] = v[0] + v[1];       // L4:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Al encontrar la primera sentencia, el compilador crea una instancia (especialidad) anónima de la plantilla vector para alojar enteros; a continuación una instancia de ella para alojar tres enteros, a la que denominamos v.&lt;br /&gt;
&lt;br /&gt;
Una primera inspección de las sentencias L2 a L3, nos muestra que la clase ofrece la posibilidad de utilizar con sus miembros el operador subíndice de matriz [ ]. Deducimos por tanto, que dispone de una versión sobrecargada de este operador para los miembros de la clase, lo que nos permite utilizar el objeto v como una matriz, aunque con algunas funcionalidades no incluidas en aquellas.&lt;br /&gt;
&lt;br /&gt;
Después de L4 los valores finales para los miembros de nuestra &amp;quot;matriz&amp;quot; serian:&lt;br /&gt;
v[0] == 7, v[1] == 8, v[2] == 15&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Si deseamos invertir el orden de los elementos de nuestra matriz. Para ello utilizamos una [[Función (programación)|función]] especial:&lt;br /&gt;
reverse(v.begin(), v.end());&lt;br /&gt;
después de lo cual, el orden de miembros sería:&lt;br /&gt;
v[0] == 15, v[1] == 8, v[2] == 7&lt;br /&gt;
&lt;br /&gt;
La primera observación es que la función reverse utiliza dos argumentos, que son a su vez el valor devuelto por sendos métodos de clase (los aplicamos sobre nuestro objeto v).  El valor devuelto por estos métodos es lo que se conoce como un [[Iteradores (Programación)|iterador]]; una especie de puntero que señalan al interior de la estructura de datos representada por el contenedor v. En este caso, el primer iterador señala al primer miembro y el segundo a una posición después del último; de esta forma se indican los miembros inicial y final entre los que se realizará la operación de inversión efectuada por reverse.&lt;br /&gt;
La segunda observación es que la función reverse no es un método de clase, sino una función global; es lo que denominamos un [[Algoritmo|algoritmo]]. Esta función tiene la peculiaridad de que puede ser aplicado sobre el contenedor vector (y algún otro); que opera sobre un rango de los elementos del contenedor, en nuestro caso sobre la totalidad (esta capacidad de operar sobre una parte de un contenedor es característica de los algoritmos). También que pueden operar sobre otros contenedores produciendo un efecto similar. Por ejemplo, el algoritmo reverse puede operar incluso sobre una simple matriz:&lt;br /&gt;
char Ch[5] = { 'A', 'E', 'I', 'O', 'U' };&lt;br /&gt;
reverse(Ch, Ch + 5);&lt;br /&gt;
for (int i = 0; i &amp;lt; 5; ++i) cout &amp;lt;&amp;lt; &amp;quot;Ch[&amp;quot; &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &amp;quot;] = &amp;quot; &amp;lt;&amp;lt; Ch[i];&lt;br /&gt;
Salida:&lt;br /&gt;
Ch[0] = U Ch[1] = O Ch[2] = I Ch[3] = E Ch[4] = A&lt;br /&gt;
&lt;br /&gt;
Es significativo que el objeto v es una estructura de datos que permite acceder individualmente a sus miembros &amp;quot;como si&amp;quot; fuesen elementos de una matriz. También que se pueden aplicar ciertas operaciones sobre la totalidad, o parte, de esta estructura considerada como una unidad.&lt;br /&gt;
== Clasificación ==&lt;br /&gt;
Existen dos tipos de contenedores: secuencias y asociativos; a su vez se subdividen según el tipo de [[Iteradores (Programación)|iterador]] que soportan.&lt;br /&gt;
Las secuencias almacenan los elementos en orden secuencial (de ahí su nombre). El contenedor agrupa a todos sus miembros como una sucesión lineal, y en consecuencia son adecuadas para accesos directos y secuenciales. Un ejemplo de secuencia es una matriz. De hecho, los algoritmos que pueden aplicarse a las secuencias pueden aplicarse también a las matrices.&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, por lo que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.  La STL proporciona cinco tipos distintos.&lt;br /&gt;
La existencia de índices supone una ordenación según los valores de un conjunto de elementos (denominado &amp;quot;de claves&amp;quot;) para el que debe existir un criterio de ordenación. Dicho en otras palabras, los objetos &amp;quot;de clave&amp;quot; deben ser de un tipo para el que estén definidos los operadores relacionales. El árbol es mantenido ordenado de forma automática por los algoritmos de inserción y borrado del contenedor.&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave y para recorrer el conjunto (ordenado) de los elementos.&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] contiene diez formas de contenedores y tres adaptadores de contenedor (denominados simplemente [[Adapter|adaptadores]]). En esta sección se expondrán brevemente cuales son estas formas; sus características, y cuál es la más adecuada para cada tipo de problema específico. En secciones sucesivas se comentarán individualmente con mayor detalle.&lt;br /&gt;
Relación siguiendo la clasificación utilizada en el Estándar:&lt;br /&gt;
•	Secuencias&lt;br /&gt;
o	deque&lt;br /&gt;
o	list&lt;br /&gt;
o	stack&lt;br /&gt;
o	vector&lt;br /&gt;
o	vector &amp;lt;bool&amp;gt;&lt;br /&gt;
•	adaptadores&lt;br /&gt;
o	queue&lt;br /&gt;
o	priority_queue&lt;br /&gt;
•	Contenedores asociativos&lt;br /&gt;
o	map&lt;br /&gt;
o	multimap&lt;br /&gt;
o	set&lt;br /&gt;
o	multiset&lt;br /&gt;
o	bitset&lt;br /&gt;
== Características ==&lt;br /&gt;
Las características más significativas de las diversas formas de contenedor son:&lt;br /&gt;
Contenedor	Características&lt;br /&gt;
Secuencias&lt;br /&gt;
vector	Este contenedor es una estructura de datos de tamaño fijo preferentemente. Aunque la STL proporciona herramientas para cambiar el tamaño de un vector de forma dinámica, esta operación es costosa y debe ser evitada dentro de lo posible (en este sentido el vector se comporta como una matriz ordinaria). &lt;br /&gt;
Disponen de un buén mecanismo de acceso aleatorio a elementos y de un mecanismo de inserción al final muy eficiente.&lt;br /&gt;
Generalmente es preferible utilizar un vector que un deque o un list, a menos que sea frecuentemente necesario insertar datos al comienzo o al final, en cuyo caso es mejor utilizar un deque.  Si por el contrario es frecuente la inserción de elementos en el centro, entonces es preferible un list.&lt;br /&gt;
vector&amp;lt;bool&amp;gt;	Es una versión de la anterior especial para valores binarios (bits).&lt;br /&gt;
list	Este contenedor responde a la idéa intuitiva de &amp;quot;lista&amp;quot;, el almacenamiento de objetos en una secuencia lineal que no está necesariamente ordenada (aunque sus miembros pueden ser ordenados fácilmente mediante la función-miembro sort() ). Estos contenedores suelen ser implementados como listas doblemente enlazadas. &lt;br /&gt;
Dispone de mecanismos eficientes para insertar elementos al principio, al final o en cualquier posición (utilizando iteradores que denoten posición). Estas operaciones consumen un tiempo constante con independencia del número de elmentos albergados en el contenedor.&lt;br /&gt;
Dado que son estructuras lineales, en general los elementos no pueden ser accedidos por subíndices como en un vector.  Es necesario realizar un recorrido lineal por todos los valores, por lo que en las operaciones de acceso se utilizan tiempos proporcionales al número de elementos.&lt;br /&gt;
stack	Contenedor de elementos tipo pila LIFO que permite inserciones y eliminaciones solo en la parte superior.&lt;br /&gt;
deque	Los deques o colas de doble terminación (&amp;quot;Double-ended queue&amp;quot;) son un tipo de estructura de datos que comparte las características de las colas (&amp;quot;Queues&amp;quot;) y las pilas (&amp;quot;Stacks&amp;quot;). Como en las colas , los elementos pueden ser empujados por un extremo al interior del contenedor, y el primer elemento introducido puede ser extraído por el extremo opuesto. Al mismo tiempo, el último elemento introducido por el principio puede ser extraído en ese mismo extremo como si fuese una pila. &lt;br /&gt;
Estos contenedores suelen ser implementados bajo la forma de matrices bidimensionales.&lt;br /&gt;
Las características de los deques implementados en la STL pueden resumirse en: Acceso aleatorio; mecanismo eficiente de inserción al principio o al final.&lt;br /&gt;
string	Contenedor de caracteres adaptado a operaciones con cadenas de caracteres.&lt;br /&gt;
Asociaciones&lt;br /&gt;
set	Como el resto de contenedores asociativos, esta forma de contenedor mantiene los elementos en orden. Dispone de mecanismos eficientes para inclusión, inserción y eliminación de elementos, y soporta claves únicas (solo puede existir un miembro con una clave determinada).&lt;br /&gt;
multiset	Versión del anterior que permite la existencia de claves duplicadas. Es decir, distintos elementos dentro del conjunto pueden responder a la misma clave.&lt;br /&gt;
bitset	Contenedor de bit más orientado al tamaño que hacia el tipo de contenido. Permite almacenar secuencias de bits de tamaño fijo. No existen iteradores para reccorrerlas, y sus elementos se acceden utilizando el operador subíndice [ ]. &lt;br /&gt;
Se dispone de varias funciones para realizar con ellos operaciones de bits &lt;br /&gt;
map	Como el resto de estructuras asociativas, el map mantiene sus elementos ordenados. Se caracteriza porque sus miembros son pares de valores que pueden ser de tipos distintos. Uno de ellos, el que actúa como clave para el índice (&amp;quot;Key-value&amp;quot;), puede ser de cualquier tipo, a condición de que sus elementos puedan ser ordenados según un criterio (por defecto se utiliza el operador &amp;lt;). &lt;br /&gt;
Permite claves únicas. Es decir, que solo puede existir un miembro para cada clave. Dispone de mecanismos de inserción y borrado muy eficientes y no existe límite de tamaño. La estructura se encarga de crecer y disminuir en concordancia con las necesidades de sus miembros. Permite el operador [ ] subíndice para los elementos de la clave así como otras técnicas de acceso.&lt;br /&gt;
Estas estructuras de datos recibe también los nombres de diccionarios, tablas y matrices asociativas, en referencia a que pueden considerarse como dos matrices del mismo número de elementos, en las que existe una relación entre cada miembro de una con otro miembro de la otra.  Una de las matrices (que actúa de índice) estaría ordenada según su contenido.&lt;br /&gt;
multimap	En todo igual que el anterior pero permitiendo además claves duplicadas. Es decir, que una misma clave pueda estar asociada a dos &amp;quot;valores&amp;quot; distintos.&lt;br /&gt;
 &lt;br /&gt;
Adaptador	Características&lt;br /&gt;
queue	Contenedor tipo cola FIFO que permite inserciones al final y eliminaciones al principio.&lt;br /&gt;
priority queue	Este contenedor dispone de mecanismos eficientes para acceso y eliminación de grandes valores.&lt;br /&gt;
&lt;br /&gt;
== Seleccionar un contenedor ==&lt;br /&gt;
El binomio contendor-iterador conforma una herramienta que se adapta a circunstancias muy variadas. De hecho, es posible que un determinado problema pueda ser abordado de varias formas. En estos casos la selección de la forma de contenedor más adecuado depende de las circunstancias. En ciertas ocasiones puede resultar bastante obvia; en otras puede no estar tan claro cuál es la mejor opción, pues &amp;quot;a priori&amp;quot;, pueden adaptarse varias formas al caso concreto. Naturalmente puede utilizarse el sistema de prueba y comparación. Por ejemplo, cronometrando los resultados obtenidos en un modo u otro. También será de gran ayuda la experiencia, pero como una guía o criterio general puede utilizarse el principio de selección que se indica a continuación.&lt;br /&gt;
Como se accederá a los datos?	Si es importante un acceso aleatorio, pueden utilizarse un vector o un deque. Si basta con un acceso secuencial cualquiera de los dos puede ser el elegido.&lt;br /&gt;
Es importante el orden en que serán mantenidos los valores dentro de la colección de datos?	Existen muchas formas de secuenciar los valores. Si es importante un orden estricto a lo largo de toda la vida del contenedor, la elección obvia es un set, dado que las inserciones en una de estas estructuras se realiza automáticamente en orden. &lt;br /&gt;
Si este orden es importante solo en algún momento, por ejemplo al final de una serie de inserciones, puede ser más sencillo colocar los valores en un list o vector para ordenar más tarde el resultado en el momento necesario.&lt;br /&gt;
Si el orden en que se almacenan los valores en la estructura está relacionado con el orden de su inserción, entonces un stack, un queue o un list pueden ser la mejor elección.&lt;br /&gt;
Puede variar mucho el tamaño de la estructura de datos durante el curso de la ejecución del programa?	Si es así, entonces puede ser que la mejor opción sean un list o un set. Un vector o un deque pueden conducir a mantener un gran almacenamiento intermedio (buffer); incluso después que los elementos hayan sido eliminados de la colección de datos. Estos dos contenedores no son adecuados para cambios de tamaño, aunque vector dispone de un mecanismo de inserción al final eficiente. &lt;br /&gt;
Recíprocamente: si el tamaño de la colección se mantiene relativamente estable, entonces un vector o un deque pueden utilizar menos memoria que un list o un set que almacenen el mismo número de elementos.&lt;br /&gt;
Es posible determinar el tamaño de la colección?	La estructura de datos vector proporciona un medio para pre-seleccionar un bloque de memoria de un tamaño específico con la función miembro reserve, posibilidad que no existe en otros contenedores.&lt;br /&gt;
Es frecuente tener que comprobar si un valor cualquiera está incluido en la colección?	En este caso, un contenedor set o map pueden ser buena elección. En estos casos comprobar si un determinado valor está incluido puede ser realizado con un pequeño número de pasos (logarítmicos con el tamaño del contenedor). Mientras que la misma verificación en cualquiera de los otros tipos puede requerir comparar el valor con cada elemento almacenado en el contenedor.&lt;br /&gt;
Está indexada la colección de datos? &lt;br /&gt;
Si es así, puede ser vista la colección como una serie de pares clave/valor?	Si las claves son enteros entre 0 y un límite superior, pueden utilizarse un vector o un deque. &lt;br /&gt;
Si la clave es algún otro valor, como cadenas de caracteres o tipos definidos por el usuario, puede utilizarse un contenedor map.&lt;br /&gt;
Pueden los valores estar relacionados unos con otros?	Todos los valores almacenados en cualquier contenedor de la STL debe ser capaz de comprobar la igualdad con cualquier otro valor similar, pero recuerde que no todos son capaces de reconocer el operador de relación menor-que; sin embargo, si los valores no pueden ser ordenados utilizando el operador menor-que, no pueden ser almacenados en un set o en un map.&lt;br /&gt;
Es una operación frecuente tener que encontrar y eliminar el valor mayor de la colección?	En caso afirmativo, la estructura de datos más idónea es el priority queue.&lt;br /&gt;
En que posiciones son insertados o eliminados los elementos de la estructura?	Si los valores son añadidos o eliminados en la zona interior, entonces la mejor opción es un list. &lt;br /&gt;
Si los valores son insertados solo al comienzo, un deque o un list pueden ser lo más adecuado.&lt;br /&gt;
Si los valores son insertados y eliminados solo al final, un stack o un queue pueden ser elecciones lógicas.&lt;br /&gt;
Es frecuente tener que refundir dos o más secuencias en una sola?	En caso afirmativo, puede considerarse que las mejores opciones son un set o un list, dependiendo que la colección deba o no ser mantenida en orden. &lt;br /&gt;
Refundir dos set es una operación muy eficiente.  Si la colección de datos no está ordenada, pero puede utilizarse la función miembro splice() de las list (que es muy eficiente), entonces es preferible este último tipo de contenedor, dado que esta operación no está contemplada en las demás formas.&lt;br /&gt;
=== Tipos no incluidos ===&lt;br /&gt;
La [[Librería Estándar C++|Librería Estándar C++]] incluye contenedores adecuados para la mayoría de los casos prácticos, aunque quizás existen una serie de estructuras de datos clásicas que no han sido incluidas. En la mayoría de los casos, la causa es que los contenedores proporcionados pueden ser fácilmente adaptados para suplir los usos facilitados por los tipos omitidos.&lt;br /&gt;
Tipos clásicos no incluidos y la sustitución más fácil.&lt;br /&gt;
Contenedor omitido	Sustitución utilizando elementos de STL&lt;br /&gt;
tree	El modo set está implementado internamente como un árbol de búsqueda binaria. &lt;br /&gt;
Para la mayoría de los casos prácticos que pueden ser resueltos utilizando árboles este modo es un sustituto adecuado.&lt;br /&gt;
matrices multidimensionales	Puesto que los vectores pueden almacenar elementos que sean otros vectores, estas estructuras pueden ser construidas fácilmente.&lt;br /&gt;
graph	La representación de un gráfico puede ser fácilmente construida como un map que contiene otros map. Un map cuyos elementos son a su vez maps, es la representación natural de un gráfico directo. Por ejemplo, supongamos que utilizamos cadenas de caracteres para codificar nombres de ciudades, y que deseamos construir un map donde el valor asociado con un borde es la distancia entre dos ciudades conectadas. &lt;br /&gt;
Se puede crear uno de estos gráficos como se muestra en el ejemplo (  xxx)&lt;br /&gt;
sparse array	Una novedosa sustitución es la representación de un gráfico.&lt;br /&gt;
hash table	Las tablas hash proporcionan un tiempo de acceso constante, así como inserción y borrado de elementos, convirtiendo estas operaciones en operaciones de índice. &lt;br /&gt;
Una tabla hash puede ser construida fácilmente como un vector (o deque) cuyos elementos son lists (o incluso sets).  En el ejemplo de la ordenación raíz (  xxx) se describe una de estas estructuras (un vector de deques), aunque en este ejemplo no incluye invocación la función hash para convertir un valor en un índice.&lt;br /&gt;
Funcionalidad set	En la STL, los tipos set están específicamente ordenados, y sus operaciones (como la unión intersección, etc.) no pueden ser realizadas sobre colecciones de valores no ordenados (por ejemplo un conjunto de números complejos). &lt;br /&gt;
Una list puede ser utilizada como sustituto, aunque es necesario escribir funciones de operación especiales, dado que los algoritmos genéricos no pueden ser utilizados con listas.&lt;br /&gt;
== Gestión de memoria ==&lt;br /&gt;
La gestión de memoria realizada por los contenedores comprende tanto la asignación y liberación de espacio para sus miembros, como para las claves que constituyen el sistema de índice de algunos tipos de contenedor. En general los algoritmos de la STL están muy optimizados y el sistema de asignación de memoria intenta compaginar rapidez y eficacia. La primera exige asignar y desasignar espacio cada vez que se introduce o elimina un miembro del contenedor. La eficacia, e incluso la disminución de la fragmentación inherentes al manejo del montón, exige asignar y rehusar trozos de memoria lo más grandes posible cada vez. El abordaje a este problema se ha realizado de dos formas básicas: (a) Contenedores que no pueden alterar su tamaño, de forma que la asignación de espacio para sus elementos debe realizarse en el momento de su declaración. (b) Contenedores que pueden crecer y/o disminuir en consonancia con los elementos a albergar.&lt;br /&gt;
Refiriéndonos al caso (b), para balancear estas exigencias contrapuestas, algunas implementaciones utilizan el siguiente esquema de trabajo: inicialmente el sistema asigna al contenedor un trozo de memoria de tamaño adecuado para contener cierto número de elementos; espacio que es utilizando hasta que se agota. A partir de aquí, cada nueva demanda origina la asignación una zona de doble tamaño que la anterior. Por ejemplo, supongamos que para gestionar un vector de enteros, el compilador asigna inicialmente espacio para un máximo de 16 miembros.  Cuando se agotara, se realizaría una nueva asignación de espacio para 32 miembros, e inmediatamente se efectuaría una recolocación del contenido actual en el nuevo espacio y la liberación del primitivo. Si el nuevo contenedor quedara lleno de nuevo, la siguiente asignación sería capaz de 64 miembros y así sucesivamente.&lt;br /&gt;
El factor de aumento de tamaño puede ser cualquiera. Muchos compiladores utilizan un factor 1.5 cada vez que deben ampliar el espacio necesario.&lt;br /&gt;
Cada nueva recolocación implica varios pasos:&lt;br /&gt;
•	Asignación de memoria al estilo malloc() de la librería clásica en cantidad suficiente para el nuevo tamaño.&lt;br /&gt;
•	Copia de los elementos actuales en la nueva localización. Los elementos son colocados en la nueva situación utilizando el constructor copia.&lt;br /&gt;
•	Actualización de las estructuras internas del nuevo contenedor (sistema de índices).&lt;br /&gt;
•	Eliminación de los elementos originales mediante invocación sucesiva de sus correspondientes destructores.&lt;br /&gt;
•	Liberación de la memoria utilizada por las estructuras internas.&lt;br /&gt;
•	Liberación de la zona original mediante una invocación al estilo free de la librería clásica.&lt;br /&gt;
&lt;br /&gt;
En general, al referirse al tamaño de un contenedor existen tres magnitudes distintas aunque relacionadas, cuyos valores pueden obtenerse mediante tres métodos:&lt;br /&gt;
•	El número de elementos contenidos actualmente. size()&lt;br /&gt;
•	El máximo número de elementos que pueden alcanzarse actualmente sin necesidad de una nueva recolocación. capacity()&lt;br /&gt;
•	El máximo número de elementos que pueden alcanzarse en cualquier caso. max_size().&lt;br /&gt;
Ejemplo:&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {         // ================&lt;br /&gt;
vector&amp;lt;int&amp;gt; vInt;&lt;br /&gt;
for (int i=0; i &amp;lt; 100; i++) vInt.push_back(i);&lt;br /&gt;
&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;Tamaño actual:   &amp;quot; &amp;lt;&amp;lt; vInt.size()     &amp;lt;&amp;lt; endl;&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;Capacidad actual: &amp;quot; &amp;lt;&amp;lt; vInt.capacity() &amp;lt;&amp;lt; endl;&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;Tamano maximo:   &amp;quot; &amp;lt;&amp;lt; vInt.max_size() &amp;lt;&amp;lt; endl;&lt;br /&gt;
return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
Tamaño actual: 100&lt;br /&gt;
Capacidad actual: 256&lt;br /&gt;
Tamano maximo: 1073741823&lt;br /&gt;
En todos los casos: size() &amp;lt;= capacity()&lt;br /&gt;
Es posible comprobar si un contenedor está vacío, comparando su tamaño actual size() con cero, aunque es más rápido utilizar el método empty(), que devuelve true si realmente size() == 0.&lt;br /&gt;
=== Reserva de espacio ==&lt;br /&gt;
Como puede suponer, cada recolocación supone un proceso considerable, sobre todo en contenedores muy grandes. Para evitar sus inconvenientes si se conoce de antemano el tamaño máximo a utilizar, la STL ofrece la posibilidad de preasignar un espacio arbitrario. Para esto se dispone del método reserve(n), que garantiza la asignación de espacio inicial suficiente para alojar n miembros en el contenedor. Si el argumento n es mayor que la capacidad actual, se produce una recolocación y el nuevo argumento determina la nueva capacidad. Si es menor no se produce ninguna acción.&lt;br /&gt;
Ejemplo, para crear un vector de enteros capaz para al menos 1000 miembros:&lt;br /&gt;
vector &amp;lt;int&amp;gt; v;&lt;br /&gt;
v.reserve(1000);&lt;br /&gt;
&lt;br /&gt;
En el siguiente ejemplo se muestran los resultados compilado con Borland C++ 5.5 para Win32; con MS Visual C++ 6.0 y con GNU gcc 2.95.3 para Linux:&lt;br /&gt;
// resultados con:         BC++   VC++   GNU   &lt;br /&gt;
vector&amp;lt;int&amp;gt; v;&lt;br /&gt;
cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 0      0      0   &lt;br /&gt;
cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 0      0      0&lt;br /&gt;
v.push_back(3);&lt;br /&gt;
cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    1      1&lt;br /&gt;
v.reserve(100);&lt;br /&gt;
cout &amp;lt;&amp;lt; v.size();      // -&amp;gt; 1      1      1&lt;br /&gt;
cout &amp;lt;&amp;lt; v.capacity();  // -&amp;gt; 256    100    100&lt;br /&gt;
=== Operaciones sobre contenedores ===&lt;br /&gt;
Los elementos de un contenedor son colocados en él utilizando el constructor copia, aunque algunas operaciones requieren la existencia de un constructor por defecto. A su vez, los algoritmos genéricos, como copy(), que copian a un contenedor, utilizan el operador de asignación.&lt;br /&gt;
Por ejemplo, cuando se duplica todo un contenedor de tipos T por invocación del constructor copia o por asignación, cada miembro es copiado en la nueva estructura utilizando el constructor copia o el operador de asignación. Tanto si una copia profunda o una copia somera, el resultado es controlado por el programador, que puede proporcionar el operador de asignación para el tipo T con cualquier significado que desee. Si se ha definido un destructor para el tipo T, este destructor es invocado cada vez que deba ser eliminado un elemento del contenedor. Cuando se destruye toda la colección, el destructor es invocado por cada elemento que permaneciera almacenado.&lt;br /&gt;
Debemos añadir algunas palabras acerca de los contenedores que almacenan colecciones de punteros. Estos conjuntos no son raros. Por ejemplo, una colección de punteros es el único medio de almacenar valores que pueden representar indistintamente instancias de una clase o instancias de una subclase. Puede encontrarse una de estas colecciones en el ejemplo de simulación manejada por eventos (  xxx).&lt;br /&gt;
En estos casos, el contenedor es solamente responsable de mantener los propios punteros, siendo responsabilidad del programador manejar la memoria de los valores referenciados por estos, lo que supone que los espacios de memoria son asignados correctamente; por lo general mediante el operador new; que no son desasignados mientras el contenedor albergue referencias a ellos, y que sean adecuadamente desasignados una vez que han sido eliminados del contenedor.&lt;br /&gt;
===  Secuencias ===&lt;br /&gt;
Las secuencias son estructuras de datos de tipo lineal, con posibilidad de que su tamaño puede ser alterado insertando elementos al principio, al final o en cualquier posición, si bien la idoneidad en este sentido es distinta entre los diversos tipos.&lt;br /&gt;
La STL ofrece los siguientes:&lt;br /&gt;
•	deque&lt;br /&gt;
•	list&lt;br /&gt;
•	stack&lt;br /&gt;
•	vector&lt;br /&gt;
•	vector&amp;lt;bool&amp;gt;&lt;br /&gt;
La estructura lineal implica que sus datos son lógicamente contiguos, aunque su disposición física puede que no lo sea. Los elementos pueden ser accedidos por un índice numérico, aunque en algunos tipos de secuencia el acceso a un elemento implica un recorrido por la lista.&lt;br /&gt;
== Contenedores asociativos ==&lt;br /&gt;
Los contenedores asociativos son una extensión de las secuencias. Mientras que en estas para acceder a los elementos solo pueden utilizarse claves numéricas, que señalan el número de orden del elemento dentro de la secuencia (al estilo de los índices en las matrices). Los contenedores asociativos admiten cualquier tipo de clave de acceso. Las más frecuentes son las cadenas alfanuméricas (stings).&lt;br /&gt;
Las asociaciones almacenan sus miembros en forma de árbol indexado, razón por la que son denominados también contenedores asociativos ordenados, y resultan adecuados para accesos aleatorios mediante claves.&lt;br /&gt;
La ordenación se realiza según los valores de ciertos miembros del contenedor. Estos elementos son denominados &amp;quot;de claves&amp;quot; (&amp;quot;Key values&amp;quot;). Lo que exige que los objetos &amp;quot;de clave&amp;quot; sean de un tipo para el que estén definidos los operadores relacionales. El contenedor es mantenido ordenado de forma automática por los algoritmos de inserción y borrado.&lt;br /&gt;
La STL proporciona cinco tipo distintos, aunque en realidad son tres clases; dos de ellas en dos variedades (permitiendo o no claves duplicadas). Uno de los tipos (bitset) sirve para almacenar campos de bits de longitud constante. Los otros dos permiten elementos ordenados de cualquier tipo (set y multiset), mientras que map y multimap permiten alojar pares de elementos. Uno que actúa como &amp;quot;Key value&amp;quot; y otro que puede ser un tipo cualquiera al que llamaremos valor-dato.&lt;br /&gt;
•	bitset&lt;br /&gt;
•	set&lt;br /&gt;
•	multiset&lt;br /&gt;
•	map&lt;br /&gt;
•	multimap&lt;br /&gt;
Existen mecanismos para asociar un valor o dato de cualquier tipo con una clave; para encontrar el valor asociado a una clave, y para recorrer el conjunto (ordenado) de las claves.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http://www.zator.com/Cpp/E5_1_1.htm Contenerores C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Contenedores en C.conclase.net]&lt;br /&gt;
* [https://docs.microsoft.com/es-es/cpp/standard-library/stl-containers?view=vs-2017  Contenedores de la biblioteca estándar de C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Librer%C3%ADa_Est%C3%A1ndar_C%2B%2B&amp;diff=3232351</id>
		<title>Librería Estándar C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Librer%C3%ADa_Est%C3%A1ndar_C%2B%2B&amp;diff=3232351"/>
		<updated>2018-11-27T16:14:35Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Librería Estándar C++ |imagen=  |concepto= Una librería es un conjunto de recursos (algoritmos) prefabricados, que pueden ser utilizados por el programador para realizar determinadas operaciones }}''' Librería Estándar C++ '''. [[C++|C++]] no llega al nivel de simplicidad de su antecesor C, pero al igual que aquél, tampoco dispone de utilidades o funciones para entrada o salida implementadas en el propio lenguaje, de modo que estas y otras muchas, como manejo de cadenas de caracteres (strings), manejo de ficheros, funciones matemáticas. son implementadas en forma de librerías externas.&lt;br /&gt;
== Sinopsis ==&lt;br /&gt;
Una librería es un conjunto de recursos (algoritmos) prefabricados, que pueden ser utilizados por el programador para realizar determinadas operaciones. Las declaraciones de las funciones (prototipos) utilizadas en estas librerías, junto con algunas macros y constantes predefinidas que facilitan su utilización, se agrupan en ficheros de nombres conocidos que suelen encontrarse en sitios predefinidos. Por ejemplo, en los sistemas UNIX, en  /usr/include. Estos ficheros se suelen llamar &amp;quot;de cabecera&amp;quot;, porque es tradición utilizar las primeras líneas del programa para poner las directivas #include que los incluirá en el fuente durante la fase de preprocesado.&lt;br /&gt;
== Clases de librerías ==&lt;br /&gt;
Los [[Compilador|compiladores]] [[C++|C++]] incluyen un amplio repertorio de clases, funciones y macros que permiten realizar una amplia variedad de tareas, incluyendo entradas/salidas de bajo y alto nivel; manipulación de cadenas alfanuméricas y ficheros; control de procesos (incluyendo multiproceso); manejo de memoria; cálculos matemáticos y un largo etcétera.&lt;br /&gt;
Este repertorio de recursos es denominado colectivamente como &amp;quot;Rutinas de librería&amp;quot;; &amp;quot;Librerías de ejecución&amp;quot; RTL (&amp;quot;Runtime Librarys&amp;quot;) o simplemente &amp;quot;Librerías&amp;quot;.   Puede decirse que el lenguaje aislado (tal cual) no tiene prácticamente ninguna utilidad sin la concurrencia de estas utilidades. El Estándar C++ las clasifica según su utilidad:&lt;br /&gt;
•	Soporte del lenguaje&lt;br /&gt;
•	Diagnóstico&lt;br /&gt;
•	Utilidades generales&lt;br /&gt;
•	Cadenas alfanuméricas (&amp;quot;Strings&amp;quot;)&lt;br /&gt;
•	Localización&lt;br /&gt;
•	Contenedores&lt;br /&gt;
•	Iteradores&lt;br /&gt;
•	Algoritmos&lt;br /&gt;
•	Cálculo numérico&lt;br /&gt;
•	Entrada/Salida&lt;br /&gt;
=== Librería Estándar C++ ===&lt;br /&gt;
Para poner un poco de orden, el Estándar C++ define la denominada Librería Estándar que debe acompañar a cada implementación del compilador que se adhiera al estándar. Es decir: la norma determina cuales son, como se llaman y como se utiliza este conjunto de algoritmos que deben acompañar (como mínimo) a cada implementación del compilador que quiera llamarse &amp;quot;Estándar&amp;quot;. La última versión, ISO/IEC 14882 del año 1998, especifica que se compone de 32 ficheros de cabecera de nombres fijos y conocidos agrupados según la funcionalidad de los algoritmos. Son los siguientes:&lt;br /&gt;
 &lt;br /&gt;
Ficheros	Funcionalidad/funciones&lt;br /&gt;
&lt;br /&gt;
&amp;lt;algorithm&amp;gt;	Parte de la STL que describe los algoritmos&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bitset&amp;gt;	Parte de la STL relativa a contenedores tipo bitset. Set de valores booleanos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;complex&amp;gt;	Parte de la librería numérica de la STL relativa a los complejos .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;deque&amp;gt;	Parte de la STL relativa a contenedores tipo deque;  un tipo de colas: &amp;quot;Double-ended-queue&amp;quot; .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;exception&amp;gt;	Parte de la librería de diagnóstico relativa al manejo de excepciones&lt;br /&gt;
&lt;br /&gt;
&amp;lt;fstream&amp;gt;	Flujos hacia/desde ficheros.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;functional&amp;gt;	Parte de la STL relativa a Objetos-función&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iomanip&amp;gt;	Manipuladores.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ios&amp;gt;	Supreclases para manejo de flujos de E/S.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iosfwd&amp;gt;	Contiene declaraciones adelantadas de todas las plantillas de flujos y sus typedefs estándar. Por ejemplo ostream.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iostream&amp;gt;	Parte del a STL que contiene los algoritmos estándar de E/S.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;istream&amp;gt;	Algoritmos estándar de flujos de entrada.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iterator&amp;gt;	Parte de la STL relacionada con iteradores, un tipo de puntero que permite utilizar los algoritmos de la Librería con las estructuras de datos representadas por los contenedores.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;limits&amp;gt;	Descripción de propiedades dependientes de la implementación que afectan a los tipos fundamentales.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;list&amp;gt;	Parte de la STL relativa a contenedores tipo list;  listas doblemente enlazadas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;locale&amp;gt;	Parte de la STL relativa a la internacionalización.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;map&amp;gt;	Parte de la STL relativa a contenedores tipo map.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;memory&amp;gt;	Utilidades relativas a la gestión de memoria, incluyendo asignadores  y punteros inteligentes (auto_ptr).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;new&amp;gt;	Manejo de memoria dinámica.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;numeric&amp;gt;	Parte de la librería numérica de la STL relativa a operaciones numéricas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ostream&amp;gt;	Algoritmos estándar para los flujos de salida.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;queue&amp;gt;	Parte de la STL relativa a contenedores tipo queue;  colas de objetos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;set&amp;gt;	Parte de la STL relativa a contenedores tipo set.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sstream&amp;gt;	Flujos hacia/desde cadenas alfanuméricas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;stack&amp;gt;	Parte de la STL relativa a contenedores tipo stack;  pilas de objetos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;stdexcept&amp;gt;	Parte de la STL relativa a las clases de las que derivan los objetos lanzados por las excepciones ocasionadas en los algoritmos de la propia STL y otras expresiones.  Estas clases son utilizadas para reportar errores detectados durante runtime.  Los usuarios también pueden utilizar excepciones para reportar errores en sus propios programas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;streambuf&amp;gt;	Parte de la STL relativa al Almacenamiento de flujos de E/S (&amp;quot;Stream buffers&amp;quot;).  Define los tipos que controlan la capa de transporte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;string&amp;gt;	Parte de la STL relativa a contenedores tipo string;  una generalización de las cadenas alfanuméricas para albergar cadenas de objetos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;typeinfo&amp;gt;	Mecanismo de identificación de tipos en tiempo de ejecución.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;utility&amp;gt;	Parte de la STL que contiene elementos auxiliares como [[Operadores|operadores]] y pares (pairs).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;valarray&amp;gt;	Parte de la librería numérica de la STL relativa a manejo de matrices numéricas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vector&amp;gt;	Parte de la STL relativa a los contenedores tipo vector; una generalización de las matrices unidimensionales C/C++.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Aunque generalmente las librerías no aportan ninguna característica al lenguaje (se supone que son utilidades auxiliares que no forman parte del lenguaje propiamente dicho), una pequeña porción de la Librería Estándar C++ sí aporta características que se consideran pertenecientes a este, de forma que deben estar presentes los ficheros de cabecera correspondientes si se desea usarlas. En concreto se refieren a los siguientes elementos:&lt;br /&gt;
&lt;br /&gt;
•	[[Operadores|operadores]] new, new[], delete y delete[].&lt;br /&gt;
&lt;br /&gt;
•	Clase type_info que corresponde al mecanismo RTTI de identificación de tipos en tiempo de ejecución representado por el operador typeid &lt;br /&gt;
&lt;br /&gt;
•	Rutinas de inicio y terminación.&lt;br /&gt;
&lt;br /&gt;
•	Las excepciones estándar lanzadas por los algoritmos anteriores&lt;br /&gt;
&lt;br /&gt;
=== Librería C ===&lt;br /&gt;
Además de otras nuevas, cuyo diseño e importancia cambian drásticamente la filosofía del lenguaje, C++ incluye prácticamente la totalidad de [[Función_(programación)| funciones]] de la primitiva librería estándar C. A esta librería, mantenida por compatibilidad, la denominamos Librería clásica.&lt;br /&gt;
=== Otras librerías ===&lt;br /&gt;
Además de las que proporciona el estándar y las complementarias que pueda incluir por su cuenta el fabricante del compilador, en los proyectos reales se suelen utilizar infinidad de otras librerías, comerciales o públicas, que facilitan el trabajo en áreas particulares, y en este sentido, recordar que uno de los pecados que el programador novel debe evitar, es la tendencia a querer reinventar constantemente la rueda. De forma que el consejo es utilizar en lo posible librerías que estén probadas y sean fácilmente accesibles. Aunque hay que tener cuidado, porque determinados proyectos exigen que las librerías utilizadas estén perfectamente documentadas y en ciertos casos, que se cuente con los fuentes correspondientes.&lt;br /&gt;
== Componentes ==&lt;br /&gt;
Al referirnos a las librerías C++ utilizamos la terminología siguiente:&lt;br /&gt;
&lt;br /&gt;
•	RTL  Conjunto de librerías que acompañan a un compilador (&amp;quot;Runtime Library&amp;quot;), sean o no estándar.&lt;br /&gt;
&lt;br /&gt;
•	Librería Estándar. Conjunto de librerías cuyo contenido está definido por el Estándar C++ (abreviadamente LE).&lt;br /&gt;
&lt;br /&gt;
•	Libería clásica. Parte de la Librería Estándar correspondiente al C clásico.&lt;br /&gt;
&lt;br /&gt;
•	STL (&amp;quot;Standard Templete Library&amp;quot;). Parte de la LE genuina de C++ (que no es heredada de C) y que responde a la forma &amp;quot;++&amp;quot; de hacer las cosas.&lt;br /&gt;
&lt;br /&gt;
La calidad de un compilador C++ viene determinada en gran medida por la calidad y cantidad de su RTL; por su grado de adherencia al Estándar  y por el grado de soporte que proporciona para la plataforma concreta a que se destina.&lt;br /&gt;
&lt;br /&gt;
En lo que concierne a la programación para MS Windows (las referencias a la plataforma Wintel surgen de forma constante e inevitable), los [[Compilador|compiladores]] Borland C++ y MS Visual C++ son quizás los más conocidos y utilizados.  El primero incluye una completa librería denominada VCL (Visual Component Library. La del segundo es conocida como MFC (Microsoft Foundation Classes).&lt;br /&gt;
&lt;br /&gt;
Linux dispone de su propio compilador: GNU Cpp, que comenzó siendo un compilador C y ha evolucionado a un producto que es en realidad un superconjunto de compiladores. No solo puede compilar código C y C++;  también otros lenguajes como Ada o Fortran;  de forma que es común referirse a ellos como GCC (&amp;quot;GNU Compiler Collection&amp;quot;).  La buena noticia es que existen versiones de este compilador para plataformas Windows, de forma que incluso en este ambiente &amp;quot;Propietario&amp;quot; pueden realizarse desarrollos utilizando herramientas &amp;quot;Open source&amp;quot; &lt;br /&gt;
A grandes rasgos la librería Estándar C++ comprende los siguientes módulos:&lt;br /&gt;
&lt;br /&gt;
•	La denominada Librería Estándar de Plantillas, abreviadamente STL (&amp;quot;Standard Templete Library&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
•	Librería numérica. Parte de la STL que contiene algoritmos especialmente concebidos para computación numérica. Por ejemplo, una clase valarray optimizada para matrices numéricas y una clase complex para manejo y representación estandarizada de números complejos (en realidad una plantilla con especializaciones para los tipos float, double y long double.&lt;br /&gt;
&lt;br /&gt;
•	Utilidades. Parte de la STL dedicada a elementos auxiliares tales como adaptadores y la clase auto_ptr.&lt;br /&gt;
&lt;br /&gt;
•	Unas utilidades de entrada/salida de flujos, denominadas genéricamente iostreams.&lt;br /&gt;
&lt;br /&gt;
•	Una utilidad locale para manejo de localismos.&lt;br /&gt;
&lt;br /&gt;
•	Una clase string para manejo estandarizado de cadenas de caracteres.  En realidad es una instanciación (especialización) de la plantilla basic_string para cadenas de caracteres.&lt;br /&gt;
 &lt;br /&gt;
•	Un esquema para describir de modo uniforme el entorno de ejecución mediante la utilización de una clase estándar denominada numeric_limits y especialización para cada uno de los tipos de datos fundamentales.&lt;br /&gt;
&lt;br /&gt;
•	Utilidades para manejo de memoria.&lt;br /&gt;
&lt;br /&gt;
•	Soporte para utilización de juegos de caracteres y signos de diversos idiomas.&lt;br /&gt;
&lt;br /&gt;
•	Utilidades de diagnóstico y manejo de errores. Incluyen manejo de excepciones y la macro assert.&lt;br /&gt;
&lt;br /&gt;
== Funcionalidad ==&lt;br /&gt;
Si atendemos a su funcionalidad,  las utilidades ofrecidas por la Librería Estándar pueden agruparse en:&lt;br /&gt;
&lt;br /&gt;
•	Clasificación: Clasifican caracteres ASCII, como letras, caracteres de control (no imprimibles), Mayúsculas/minúsculas etc. Se definen en la cabecera &amp;lt;ctype.h&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
•	Entradas/Salidas de Consola: Estas son las denominadas entrada/salida estándar. Por defecto se refieren al teclado y a la pantalla (no pueden utilizarse directamente en aplicaciones de interfaz gráfica).&lt;br /&gt;
&lt;br /&gt;
•	Conversión: Convierten caracteres y cadenas de caracteres desde formato alfabético a numérico de diversos tipos (float, int, long).  También realizan la conversión inversa: de formatos numéricos a representaciones alfabéticas y de mayúsculas a minúsculas y viceversa.&lt;br /&gt;
&lt;br /&gt;
•	Diagnóstico: Son rutinas destinadas a comprobaciones; a descubrir y corregir posibles errores.&lt;br /&gt;
&lt;br /&gt;
•	Directorio: Rutinas para manejo de directorios y sus direcciones (path names).&lt;br /&gt;
&lt;br /&gt;
•	En linea (Inline): Rutinas para versiones inline de funciones. El compilador genera el código correspondiente para las versiones inline cuando se utiliza #pragma intrinsic o si se solicita optimización al compilador (optimización de tiempo de ejecución).&lt;br /&gt;
&lt;br /&gt;
•	Entrada/Salida. Son rutinas que proporcionan manejo de flujos y operaciones de Entrada/Salida a bajo nivel (de Sistema Operativo).&lt;br /&gt;
&lt;br /&gt;
•	Manipulación. Manejo de cadenas y bloques de memoria: copiar, comparar, convertir y buscar.&lt;br /&gt;
&lt;br /&gt;
•	Matemáticas: Para realizar cálculos matemáticos.&lt;br /&gt;
&lt;br /&gt;
•	De Memoria: Proporcionan asignación de memoria dinámica.&lt;br /&gt;
&lt;br /&gt;
•	Miscelánea. Se agrupan aquí rutinas varias, como las que posibilitan saltos (goto) no locales y las que manejan diferencias de tipo cultural o de lenguaje. Por ejemplo representación de números, de moneda, formatos de fecha y hora, clasificación de tipo alfabético.&lt;br /&gt;
&lt;br /&gt;
•	Control de proceso. Rutinas que permiten invocar y terminar nuevos procesos desde otra rutina.&lt;br /&gt;
&lt;br /&gt;
•	Fecha y hora. Incluyen rutinas para conversión y manipulación de variables de medida del tiempo (fecha y hora).&lt;br /&gt;
&lt;br /&gt;
•	Argumentos variables. Rutinas utilizadas cuando se usan listas variables de argumentos, como en los casos de printf(), vscanf().&lt;br /&gt;
== Utilización ==&lt;br /&gt;
La utilización de la Librería Estándar C++ requiere de dos tipos de condiciones que podríamos describir como formales y conceptuales.&lt;br /&gt;
&lt;br /&gt;
1. En cuanto a las primeras (condiciones formales) y habida cuenta que las utilidades aparecen en forma de funciones, resulta evidente que su utilización exige incluirlas en nuestro programa. Para ello se necesitan tres pasos (en realidad las exigencias son las mismas que con cualquier otra función, la diferencia estriba en la forma en que se realizan los pasos b y c):&lt;br /&gt;
&lt;br /&gt;
a:  Incluir en el código fuente las invocaciones a las [[Función_(programación)| funciones]] que estamos utilizando. Ejemplo:&lt;br /&gt;
printf(&amp;quot;Esto es una llamada a la función \&amp;quot;printf\&amp;quot; de librería\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
 b:  Incluir en el código fuente los prototipos de dichas funciones.&lt;br /&gt;
&lt;br /&gt;
Puesto que los prototipos ya están incluidos en los ficheros estándar de cabecera, hay que indicar al compilador que los incluya. Esto se realiza poniendo en nuestro fuente (normalmente al principio) una directiva de preprocesado #include que señala el fichero de cabecera que se debe añadir. Por ejemplo, si el manual indica que la función printf está definida en el fichero de cabecera stdio.h ponemos en nuestro código:&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  c:  Incluir en el fuente las definiciones de las funciones utilizadas. Como alternativa se puede indicar al compilador que tales definiciones están en ficheros compilados previamente.&lt;br /&gt;
&lt;br /&gt;
En este último caso se dice que las definiciones de las funciones están en librerías de las que existen dos tipos: estáticas (.LIB, .OBJ y .BPI) y dinámicas (.DLL). Toda la información que necesita el compilador está contenida en los ficheros de cabecera, por lo que las operaciones correspondientes son realizadas de forma automática; con la sola condición de que los ficheros y librerías correspondientes sean accesibles al enlazador.&lt;br /&gt;
&lt;br /&gt;
Las entidades de la Librería Estándar C++ (que no están en ficheros de cabecera .h), se han definido en un espacio de nombres denominado std, por lo que es preciso referirse a él específicamente cuando se quieran utilizar estos recursos.&lt;br /&gt;
&lt;br /&gt;
2. Respecto a las que hemos denominado &amp;quot;condiciones conceptuales&amp;quot;, damos por sentado que la utilización de algoritmos de la Librería exige conocerlos. Pero debemos advertir que existe una gran diferencia entre las rutinas de la que hemos denominado librería clásica y los recursos de la nueva Librería Estándar de Plantillas STL.&lt;br /&gt;
&lt;br /&gt;
En general los algoritmos contenidos en la librería clásica realizan tareas muy sencillas bajo la forma de funciones que, con un cierto número de argumentos, realizan la tarea encomendada. A veces devolviendo un objeto (que puede ser una estructura). Su utilización exige poco más que repasar esta colección de funciones (209 en la última versión del Estándar) hasta encontrar la que mejor se ajusta a nuestras necesidades. Para esto lo mejor es recurrir a la clasificación temática ofrecida en la documentación que acompaña a los compiladores antes que a la lista alfabética de las mismas. A continuación estudiamos atentamente su prototipo y la explicación de funcionamiento que acompaña el manual (eventualmente incluso con un ejemplo) y ya estamos listos para utilizarla. En el peor de los casos suelen bastar un par de pruebas hasta que conseguimos ajustar los argumentos de forma que se consiga el resultado esperado.&lt;br /&gt;
&lt;br /&gt;
Como última recomendación al respecto, sobre todo si pensamos que nuestro programa tendrá una larga vida y/o pensamos portarlo a otras plataformas, aconsejaría echar un vistazo a la sección de &amp;quot;compatibilidad&amp;quot; que acompaña a la descripción de cada función en la documentación de la mayoría de compiladores. Suele ocurrir que el compilador ofrezca muchas más funciones que las estrictamente Estándar C++, y que estas no estén claramente separadas del resto, de forma que es posible que elijamos una función que resuelve nuestro problema pero no es portable, en cuyo caso aconsejaría evitarlas dentro de lo posible.&lt;br /&gt;
&lt;br /&gt;
La utilización de la nueva Librería de Plantillas (STL) exige la asimilación de un nuevo paradigma;  una nueva forma de pensar que, si se tiene experiencia en programación tradicional, exige incluso un &amp;quot;cambio de chip&amp;quot;, ya que estas herramientas conforman un mundo enteramente nuevo y singular.&lt;br /&gt;
&lt;br /&gt;
La STL ofrece un conjunto de recursos flexible, potente y altamente optimizado para resolver una gran variedad de situaciones de programación. Pero esta versatilidad y potencia tributan un precio: su alto grado de parametrización supone algo más que utilizar herramientas aisladas. Es necesario saber ensamblar entre sí los recursos disponibles, que no trabajan aisladamente y que son básicamente de tres tipos: contenedores, iteradores y algoritmos. El resultado es que el proceso de utilizar la STL es algo más complicado que la simple búsqueda de una función que resuelva nuestras necesidades;  que la curva de aprendizaje es ciertamente más ardua que en el caso de la librería clásica, y  que los conceptos involucrados son más abstractos y requieren un conocimiento más extenso de sus fundamentos para utilizarlos. Desde luego, la descripción detallada de todos sus elementos exige un libro completo, y de hecho son muchos los que se han publicado con el objeto exclusivo de describir la STL y/o sus técnicas de uso. En compensación, las contrapartidas obtenidas justifican sin duda el esfuerzo. El programador puede concentrarse más en el problema que en los detalles de su implementación en el fuente, se incremente la productividad y se gana en claridad conceptual.&lt;br /&gt;
== Funciones y macros ==&lt;br /&gt;
Algunas [[Función_(programación)| funciones]] pueden venir implementadas de dos formas: como macro y como función. Por ejemplo, la función isalnum, contenida en &amp;lt;ctype.h&amp;gt;.  Esto significa que además de estar implementada como una función en la correspondiente librería (que se utiliza con los argumentos señalados en el manual), está definida como una macro de preprocesado en &amp;lt;ctype.h&amp;gt;, de forma que salvo indicación contraria al compilador, el preprocesador transforma la llamada del programador en otra serie de sentencias equivalentes que utilizan los mismos argumentos. El resultado es que en el código resultante, que luego pasa al compilador y al enlazador, no existe nada parecido a una llamada a una función isalnum (técnicamente el proceso es una sustitución inline de la función de librería.&lt;br /&gt;
&lt;br /&gt;
Para evitar que esto ocurra y por consiguiente que la llamada a islanum nunca llegue a producirse, basta con indefinir la correspondiente directiva. Esto se hace incluyendo al principio del código, y debajo de la línea #include &amp;lt;ctype.h&amp;gt;, una línea de preprocesado adecuada, en este caso:  #undef isalnum, con lo que el #define del preprocesador quedará sin efecto, con el resultado de que todas las invocaciones a isalnum de nuestro código serán respetadas por el preprocesador. Más tarde el enlazador cargará el código de isalnum (que extrae de la librería) con el resto de nuestro programa, y colocará en cada punto de nuestro código donde aparezca una invocación a isalnum, un salto a la dirección adecuada.&lt;br /&gt;
&lt;br /&gt;
En estos casos, el resultado es el mismo en ambas modalidades: como macro (por defecto) o como función de librería. La elección de una u otra es cuestión de optimización. Para tomar una decisión es necesario comprobar y valorar dos aspectos:&lt;br /&gt;
&lt;br /&gt;
•	El tamaño del ejecutable que resulta en uno y otro caso. Posiblemente mayor si se utiliza la función muchas veces y se adopta la macro.&lt;br /&gt;
&lt;br /&gt;
•	La velocidad de ejecución. Posiblemente mayor si se utiliza la función muchas veces (en bucles muy largos) y se utiliza la macro.&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[Ciencia de la Información]]&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http://www.zator.com/Cpp/E5.htm  Librería Estándar C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Librería Estándar en C.conclase.net]&lt;br /&gt;
* [https://uvadoc.uva.es/bitstream/10324/17502/1/PID_15_156_Anexo4.pdf  Elementos de la librería estándar C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Identificadores_(Inform%C3%A1tica)&amp;diff=3232345</id>
		<title>Identificadores (Informática)</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Identificadores_(Inform%C3%A1tica)&amp;diff=3232345"/>
		<updated>2018-11-27T16:12:00Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Definición|Nombre=Identificador |imagen= |concepto=Conjunto de caracteres alfanuméricos de cualquier longitud que sirve para identificar las entidades del programa}}&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;&lt;br /&gt;
'''Identificadores.''' Un identificador es un conjunto de caracteres alfanuméricos de cualquier longitud que sirve para identificar las entidades del programa (clases, funciones, [[Variables|variables]], tipos compuestos) Los identificadores pueden ser combinaciones de letras y números. Cada lenguaje tiene sus propias reglas que definen como pueden estar construidos. Cuando un identificador se asocia a una entidad concreta, entonces es el &amp;quot;nombre&amp;quot; de dicha entidad, y en adelante la representa en el programa. Nombrar las entidades hace posible referirse a las mismas, lo cual es esencial para cualquier tipo de procesamiento simbólico.'''&amp;lt;br&amp;gt; ''' '' &lt;br /&gt;
== Identificadores en lenguajes informáticos&amp;lt;br&amp;gt;  ==&lt;br /&gt;
&lt;br /&gt;
En los lenguajes informáticos, los identificadores son elementos textuales (también llamados [[Símbolos|símbolos]]) que nombran entidades del lenguaje. Algunas de las de entidades que un identificador puede denotar son las variables, las constantes, los tipos de dato, las etiquetas, las subrutinas (procedimientos y funciones) y los paquetes.&amp;lt;br&amp;gt;En muchos [[Lenguajes de programación|lenguajes]] algunas secuencias tienen la forma léxica de un identificador pero son conocidos como palabras clave (o palabras reservadas). Lo habitual es que si un identificador se corresponde con una palabra clave o reservada, éste ya no pueda utilizarse para referirse a otro tipo de entidades como variables o constantes (en unos pocos lenguajes, como PL/1, esta distinción no está del todo clara).&amp;lt;br&amp;gt;Los lenguajes informáticos normalmente ponen restricciones en qué caracteres pueden aparecer en un identificador. Por ejemplo, en las primeras versiones de [[C (lenguaje de programación)|C]] y [[Lenguaje de programación C++|C++]], los identificadores están restringidos para que sean una secuencia de una o más letras ASCII, dígitos numéricos (que en ningún caso deben aparecer como primer carácter) y barras bajas. Las versiones posteriores de estos lenguajes, así como otros muchos más lenguajes modernos soportan casi todos los caracteres Unicode en un identificador. Una restricción común es que no está permitido el uso de espacios en blanco ni [[Operadores|operadores]] del lenguaje.&amp;lt;br&amp;gt;En lenguajes de programación compilados, los identificadores generalmente son entidades en tiempo de compilación, es decir, en tiempo de ejecución el programa compilado contiene referencias a direcciones de memoria y offsets más que identificadores textuales (estas direcciones de memoria u offsets, han sido asignadas por el compilador a cada identificador).&amp;lt;br&amp;gt;En lenguajes interpretados los identificadores están frecuentemente en tiempo de ejecución, a veces incluso como objetos de primera clase que pueden ser manipulados y evaluados libremente. En Lisp, éstos se llaman símbolos.&amp;lt;br&amp;gt;Los [[Compilador (Informática)|compiladores]] e [[Intérpretes|intérpretes]] normalmente no asignan ningún significado semántico a un identificador basado en la secuencia de caracteres actual. Sin embargo, hay excepciones. Por ejemplo:&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
*En Perl una variable se indica utilizando un prefijo llamado sigil, que especifica aspectos de cómo se interpreta la variable en las expresiones. &lt;br /&gt;
*En Ruby una variable se considera automáticamente como inmutable si su identificador empieza con una letra mayúscula. &lt;br /&gt;
*En Fortran, la primera letra de una variable indica si por defecto es creada como entero o como flotante.&lt;br /&gt;
&lt;br /&gt;
== Identificadores C++&amp;lt;br&amp;gt;  ==&lt;br /&gt;
&lt;br /&gt;
Los identificadores C++ pueden contener las letras a a z y A a Z, el guión bajo &amp;quot;_&amp;quot; (&amp;quot;Underscore&amp;quot;) y los dígitos 0 a 9.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== '''Caracteres permitidos'''&amp;lt;br&amp;gt;  ===&lt;br /&gt;
&lt;br /&gt;
a b c d e f g h i j k l m n o p q r s t u v w x y z&amp;lt;br&amp;gt;A B C D E F G H I J K L M N O P Q R S T U V W X Y Z&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== '''Dígitos permitidos'''&amp;lt;br&amp;gt;  ===&lt;br /&gt;
&lt;br /&gt;
0 1 2 3 4 5 6 7 8 9&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Solo hay dos restricciones en cuanto a la composición:&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
*El primer carácter debe ser una letra o el guión bajo. El Estándar establece que los identificadores comenzando con guión bajo y mayúscula no deben ser utilizados. Este tipo de nombres se reserva para los [[Compilador (Informática)|compiladores]] y las Librerías Estándar. Tampoco se permite la utilización de nombres que contengan dos guiones bajos seguidos. &lt;br /&gt;
*El estándar ANSI establece que como mínimo serán significativos los 31 primeros caracteres, aunque pueden ser más, según la implementación. Es decir, para que un compilador se adhiera al estándar ANSI, debe considerar como significativos, al menos, los 31 primeros caracteres.&lt;br /&gt;
&lt;br /&gt;
Los identificadores distinguen mayúsculas y minúsculas, así que Sum, sum y suM son distintos para el compilador. Sin embargo, [[C++ (Builder)|C++Builder]] ofrece la opción de suspender la sensibilidad a mayúsculas / minúsculas, lo que permite la compatibilidad con lenguajes insensibles a esta cuestión, en este caso, las variables globales Sum, sum y suM serían consideradas idénticas, aunque podría resultar un mensaje de aviso &amp;quot;Duplicate symbol&amp;quot; durante el enlazado.&amp;lt;br&amp;gt;Con los identificadores del tipo [[Pascal|pascal]] hay una excepción a esta regla, ya que son convertidos siempre a mayúsculas con vistas al enlazado.&amp;lt;br&amp;gt;Los identificadores globales importados desde otros módulos siguen las mismas reglas que los identificadores normales.&amp;lt;br&amp;gt;Aunque los nombres de los identificadores pueden ser arbitrarios (dentro de las reglas señaladas), se produce un error si se utiliza el mismo identificador dentro del mismo ámbito compartiendo el mismo espacio de nombres. Los nombres duplicados son legales en diferentes espacios de nombres con independencia de las reglas de ámbito.&amp;lt;br&amp;gt;Un identificador no puede coincidir con una palabra clave o con el de ninguna función de biblioteca.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
== Tipos de identificadores&amp;lt;br&amp;gt;  ==&lt;br /&gt;
&lt;br /&gt;
El estándar ANSI distingue dos tipos de identificadores:&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
*Identificadores internos; los nombres de macros de preprocesado y todas las que no tengan enlazado externo. El estándar establece que serán significativos, al menos, los primeros 31 caracteres. &lt;br /&gt;
*Identificadores externos; los que corresponden a elementos que tengan enlazado externo. En este caso el estándar es más permisivo. Se acepta que el compilador identifique solo seis caracteres significativos y pueda ignorar la distinción mayúsculas/minúsculas&lt;br /&gt;
&lt;br /&gt;
== Reglas de estilo  ==&lt;br /&gt;
&lt;br /&gt;
Es bastante frecuente que en la enseñanza de [[C++|C++]] (y de cualquier otro [[Lenguaje de programación|lenguaje de programación]]) no se subraye suficientemente la importancia de la elección de los identificadores. En este sentido, los textos se suelen limitar a señalar las reglas formales que impone el lenguaje para la declaración de nombres. Sin embargo, como todos los que tienen que ver con la legibilidad del código, el asunto es de capital importancia. Sobre todo, si se trata de algo más que del consabido programita &amp;quot;Hola mundo&amp;quot;, y desde luego resulta crítico en proyectos medianamente grandes en los que puedan trabajar más de un programador y/o deba ser mantenido por personas distintas de su creador original (lo que antes o después acaba ocurriendo en la informática empresarial).&amp;lt;br&amp;gt;[[C (lenguaje de programación)|C]] y [[C++|C++]] tienen sus propias reglas no escritas, sancionadas por la costumbre, en cuanto a ciertas formas concretas de usar los identificadores. Por ejemplo: Es costumbre utilizar minúsculas para los nombres de [[Variables|variables]] y funciones (con frecuencia se utilizan combinaciones minúsculas/Mayúsculas - por ejemplo getRvalue o rColor-, aunque la inicial suele ser minúscula). Los identificadores de variables automáticas lo más cortos posibles; los de estáticas y globales más largos y descriptivos. Los nombres de constantes simbólicas normalmente en mayúsculas.&amp;lt;br&amp;gt;Ejemplo:&amp;lt;br&amp;gt;void someFunc (int numero, char clave, int* puntero_a_clase); // &amp;lt;br&amp;gt;static tipoCliente = 0; // &amp;lt;br&amp;gt;enum formaPago { CONTADO, CREDITO }; // &amp;lt;br&amp;gt;...&amp;lt;br&amp;gt;someFunc(int n, char k, int *ptr) { // &amp;lt;br&amp;gt; int z, y, z = 2; // &amp;lt;br&amp;gt;}&amp;lt;br&amp;gt;Aparte de las manías o hábitos particulares que pueda tener cada programador, la mayoría de empresas de software medianamente serias disponen de sus propios &amp;quot;Manuales de estilo&amp;quot; o &amp;quot;Reglas de uso&amp;quot;, en los que se recogen las convenciones que deben utilizarse para los identificadores, de forma que se mantenga la máxima homogeneidad posible en el código, lo que a la postre redunda en una mayor legibilidad y facilidad de mantenimiento. En este sentido cabría señalar que, dentro de ciertos límites, no es tan importante cuales sean estas reglas, sino que existan y se respeten.&amp;lt;br&amp;gt;En determinados entornos existen reglas consagradas por el uso. Por ejemplo, en la programación C/C++ para las plataformas [[Microsoft Windows|Windows]] suelen seguirse determinadas convenciones conocidas como Notación Húngara, en la que el identificador de cada variable comienza con una o varias letras (minúsculas) que señalan el tipo de la variable. Por ejemplo, nValor.&amp;lt;br&amp;gt;Los nombres de clases se preceden siempre con una &amp;quot;C&amp;quot; mayúscula, y la siguiente letra también es mayúscula. Por ejemplo: CAboutDlg, CAprenderApp, CMainFrame, etc. Los nombres de variables comienzan por letras fijas según su tipo, pero cuando se refieren a una propiedad de clase, los dos primeros caracteres son &amp;quot;m_&amp;quot; (ejemplo m_nValor, m_wndStatusBar, etc). Los nombres de funciones miembro de clase comienzan siempre con mayúscula, pero la siguiente letra es minúscula. Por ejemplo: DoDataExchange(), InitInstance(), OnAppAbout(), etc.&amp;lt;br&amp;gt;Este tipo de notación presenta la ventaja de con un poco de práctica es mucha la información que puede extraerse de la simple lectura del código.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
== Véase también  ==&lt;br /&gt;
&lt;br /&gt;
*[[Intérpretes|Intérpretes]] &lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]] &lt;br /&gt;
*[[Compilador|Compiladores]] &lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Tokens|Tokens]] &lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Signos_de_puntuación_(Informática)|Signos de puntuación]]&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Fuente  ==&lt;br /&gt;
&lt;br /&gt;
*[http://www.zator.com/Cpp/E3_2_2.htm zator.com]&amp;lt;br&amp;gt; &lt;br /&gt;
*[http://www.carlospes.com/curso_de_algoritmos/03_01_identificadores.php Curso de algoritmos]&amp;lt;br&amp;gt; &lt;br /&gt;
*[http://msdn.microsoft.com/es-es/library/ms175874.aspx Identidicadores]&lt;br /&gt;
&lt;br /&gt;
[[Category:Lenguajes_de_programación]] [[Category:Programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Operadores&amp;diff=3232342</id>
		<title>Operadores</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Operadores&amp;diff=3232342"/>
		<updated>2018-11-27T16:11:32Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre=Operadores |imagen= |concepto=Son un tipo de [[Tokens|tokens]] que pueden aparecer en las expresiones, e indican al compilador la realización de determinadas operaciones matemáticas, lógicas y numéricas}}'''Operadores'''. Son un tipo de [[Tokens|tokens]] que pueden aparecer en las expresiones, e indican al [[Compilador (Informática)|compilador]] la realización de determinadas operaciones [[Matemáticas|matemáticas]], lógicas y numéricas. Se aplican a variables u otros objetos denominados operandos y su efecto es una combinación de las siguientes acciones:&amp;lt;br&amp;gt; &lt;br /&gt;
*Producir un resultado-valor &lt;br /&gt;
*Alterar un operando &lt;br /&gt;
*Designar un objeto o función.&lt;br /&gt;
&lt;br /&gt;
== Ejemplos&amp;lt;br&amp;gt;  ==&lt;br /&gt;
&lt;br /&gt;
*y = a + b;&lt;br /&gt;
&lt;br /&gt;
En esta sentencia, el operador suma + produce un valor nuevo, pero no altera ninguno de los operandos (a y b); a su vez, el nuevo valor es asignado a la [[Variables|variable]] y mediante el operador de asignación =. En este caso el operando de la izquierda sí se ve alterado. &lt;br /&gt;
&lt;br /&gt;
*x++;&lt;br /&gt;
&lt;br /&gt;
Aquí el operador postincremento ++ produce un nuevo valor que es aplicado sobre el propio operando, de forma que queda alterado. Cuando un operador altera un operando se dice que tiene efectos laterales.&amp;lt;br&amp;gt;Nota: por lo general, los operadores aparecen a la derecha de expresiones de asignación (por ejemplo: y = 2 * y + x), pero en ocasiones estos &amp;quot;efectos laterales&amp;quot; se utilizan para conseguir expresiones muy compactas y de un cierto nivel de sofisticación, que incluso no necesitan del operador de asignación para producir el resultado. En estos casos su lógica es un poco más difícil de seguir que cuando estos efectos no se utilizan directamente.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
*z = (*fptr)(x, y);&lt;br /&gt;
&lt;br /&gt;
Aquí, el operador de indirección * es aplicado sobre el operando fptr que es un puntero-a-función. El resultado es un designador de función al que se aplica el operador ( ) de invocación de función con dos operandos x e y que actúan como argumentos. A su vez el resultado de este operador (invocación de función) es utilizado como argumento derecho del operador de asignación = que finalmente modifica uno de sus operandos (el operando izquierdo z)&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
== Clasificación&amp;lt;br&amp;gt;  ==&lt;br /&gt;
&lt;br /&gt;
Los operadores se pueden clasificar en unitarios, binarios y ternarios, según que necesiten uno, dos o tres operandos. Los operadores unitarios (denominados también unarios) se clasifican en dos tipos según la posición del operador (representado aquí por @) respecto del operando (representado aquí por n):&amp;lt;br&amp;gt;@n: Operador prefijo. Ejemplo: ++x&amp;lt;br&amp;gt;n@: Operador posfijo. Ejemplo: x++ &lt;br /&gt;
&lt;br /&gt;
== Observaciones &amp;lt;br&amp;gt;  ==&lt;br /&gt;
&lt;br /&gt;
*Los operadores pueden (en cierta forma) considerarse como funciones que tienen un álgebra un tanto especial. De hecho, al tratar la sobrecarga de operadores, veremos que precisamente la forma en que se definen es mediante una función, la función-operador. En este sentido podríamos imaginar que la expresión y = a + b es otra forma de representar algo como: y = suma(a, b). Del mismo modo, la asignación x = y sería algo así: asigna(x, y). Siguiendo con nuestra analogía, podríamos suponer que los operadores unitarios, binarios y ternarios serían funciones que aceptarían unos, dos o tres argumentos respectivamente y que la sobrecarga de operadores no es sino una forma encubierta de sobrecarga de funciones. &lt;br /&gt;
*Aunque las funciones [[C++|C++]] se designan con [[Identificadores|identificadores]] (nombres) que siguen las reglas generales ya señaladas, estas seudo-funciones se identifican con símbolos (+,=,&amp;amp;nbsp;::,*,-&amp;amp;gt;,etc). Muchos de ellos están compuesto de un solo [[Tokens|token]] (que puede estar repetido + y ++) aunque los hay de dos. Estos últimos son: new[], delete[], () y []. &lt;br /&gt;
*Antes de realizar la operación encomendada, los operadores pueden modificar el tipo de los operandos para que sean homogéneos, de forma que la operación pueda realizarse. Por ejemplo, al indicar i + f donde i sea un entero y f un float. Estas promociones se denominan conversiones estándar y son realizadas automáticamente por el compilador, pero deben ser tenidas en cuenta para evitar sorpresas.&lt;br /&gt;
&lt;br /&gt;
En general los operadores aceptan un tipo de operando determinado y específico, produciendo y/o modificando un valor de acuerdo con ciertas reglas, pero [[C++|C++]] permite redefinir la mayoría de ellos. Es decir, permite que puedan aceptar otro tipo de operandos y seguir otro comportamiento sin que pierdan el sentido y comportamiento originales cuando se usan con los operandos normales (los tipos básicos preconstruidos en el lenguaje). Esta circunstancia recibe el nombre de sobrecarga del operador.&amp;lt;br&amp;gt;No son sobrecargables los siguientes:&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
*( . ) Operador de selección de miembros &lt;br /&gt;
*( .* ) Operador de dereferencia &lt;br /&gt;
*(&amp;amp;nbsp;:: ) Operador de acceso a ámbito &lt;br /&gt;
*(&amp;amp;nbsp;?: ) Operador conditional &lt;br /&gt;
*( # ) Directiva de preprocesado &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Polimorfismo en los operadores&amp;lt;br&amp;gt;  ==&lt;br /&gt;
&lt;br /&gt;
Sin estar sobrecargado, dependiendo del contexto (número y tipo de operandos), un operador [[C++|C++]] puede tener más de un significado. Ejemplos:&amp;lt;br&amp;gt; El símbolo ámpersand &amp;amp;amp; puede ser interpretado como:&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
*[[Operadores_de_manejo_de_bits|AND entre bits]] A &amp;amp;amp; B &lt;br /&gt;
*Operador de referencia y = &amp;amp;amp;x &lt;br /&gt;
*Declarador de referencia int&amp;amp;amp; y = x&lt;br /&gt;
&lt;br /&gt;
El asterisco * puede ser interpretado como:&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
*Declaración de un tipo puntero-a tipo* ptr &lt;br /&gt;
*Operador de indirección x = *ptr &lt;br /&gt;
*Operador de multiplicación x * y &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Precedencia&amp;lt;br&amp;gt;  ==&lt;br /&gt;
&lt;br /&gt;
La precedencia es una regla de orden que se asocia con los operadores para establecer cual se aplicará primero en caso de aparecer varios en una misma expresión (una especie de &amp;quot;orden de importancia&amp;quot; de los operadores). Por ejemplo:&amp;lt;br&amp;gt;x = 2 + 3 * 4;&amp;lt;br&amp;gt;¿Cual será el resultado, 20 o 14? &lt;br /&gt;
&lt;br /&gt;
La primera regla en este sentido es que las expresiones se evalúan de izquierda a derecha, aunque no siempre. Por ejemplo, la regla izquierda → derecha nos conduciría a que en la expresión anterior, el valor de x es 20, lo cual no es cierto, ya que en C++ la multiplicación tiene mayor precedencia que la suma, así que el resultado es 14.&amp;lt;br&amp;gt;En C++ existen 16 niveles de precedencia, de modo que la regla izquierda → derecha solo se aplica en caso de operadores del mismo nivel &amp;lt;br&amp;gt;El operador de jerarquía más alta es el paréntesis, lo que aclara y justificada la tradicional costumbre algabráica de utilizar paréntesis para forzar el orden de las operaciones. Por ejemplo, si queremos que en la expresión anterior se ejecute primero el operador suma:&amp;lt;br&amp;gt;x = (2 + 3) * 4; // el resultado es 20&amp;lt;br&amp;gt;Aunque las reglas de precedencia se suponen conocidas por los programadores C++, aconsejamos generosidad a la hora de utilizar paréntesis en las expresiones. Además de facilitar la legibilidad evitan posibles errores. Así, aunque las dos sentencias que siguen son equivalentes, la segunda es de lectura más &amp;quot;relajante&amp;quot;.&amp;lt;br&amp;gt;x = 2 + 3 * 4;&amp;lt;br&amp;gt;x = 2 + (3 * 4); &lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]  &lt;br /&gt;
*[[Signos de puntuación (Informática)|Signos de puntuación]]&lt;br /&gt;
*[[Operadores aritméticos|Operadores aritméticos]]&lt;br /&gt;
*[[Operadores lógicos|Operadores lógicos]]&lt;br /&gt;
*[[Operadores de manejo de bits|Operadores de manejo de bits]]&lt;br /&gt;
*[[Operador condicional|Operador condicional]]&lt;br /&gt;
*[[Operador coma|Operador coma]]&lt;br /&gt;
*[[Operadores relacionales|Operadores relacionales]]&lt;br /&gt;
*[[Operadores de asignación|Operadores de asignación]]&lt;br /&gt;
*[[Operadores de modelado de tipos|Operadores de modelado de tipos]]&lt;br /&gt;
*[[Operadores añadidos a expresión|Operadores añadidos a expresión]]&lt;br /&gt;
*[[Operador de acceso a ámbito|Operador de acceso a ámbito]]&lt;br /&gt;
*[[Operadores de puntero|Operadores de puntero]]&lt;br /&gt;
*[[Operador new|Operador new]]&lt;br /&gt;
*[[Operador new con matrices|Operador new con matrices]]&lt;br /&gt;
*[[Errores con el operador new|Errores con el operador new]]&lt;br /&gt;
*[[Operador delete|Operador delete]]&lt;br /&gt;
*[[Operador sizeof|Operador sizeof]]&lt;br /&gt;
*[[Operador typeid|Operador typeid]]&lt;br /&gt;
*[[Operador de preproceso|Operador de preproceso]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Sobrecarga de enumeraciones (Informática)|Sobrecarga de enumeraciones (Informática)]] &lt;br /&gt;
== Fuente&amp;lt;br&amp;gt;  ==&lt;br /&gt;
&lt;br /&gt;
*[http://www.zator.com/Cpp/E4_9.htm www.zator.com]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
[[Category:Lenguajes_de_programación]] [[Category:Programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Historia_del_Lenguaje_C&amp;diff=3232339</id>
		<title>Historia del Lenguaje C</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Historia_del_Lenguaje_C&amp;diff=3232339"/>
		<updated>2018-11-27T16:10:54Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Ficha Software&lt;br /&gt;
|nombre= Historia del Lenguaje C&lt;br /&gt;
|familia=&lt;br /&gt;
|imagen=C.jpg&lt;br /&gt;
|tamaño=&lt;br /&gt;
|descripción=Lenguaje de Programación&lt;br /&gt;
|imagen2=&lt;br /&gt;
|tamaño2=&lt;br /&gt;
|descripción2=&lt;br /&gt;
|desarrollador=&lt;br /&gt;
|modelo de desarrollo=&lt;br /&gt;
|lanzamiento inicial=&lt;br /&gt;
|última versión estable=&lt;br /&gt;
|núcleo=&lt;br /&gt;
|tipo de núcleo=&lt;br /&gt;
|plataformas soportadas=&lt;br /&gt;
|idioma=&lt;br /&gt;
|licencia=&lt;br /&gt;
|premios=&lt;br /&gt;
|web=&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;&lt;br /&gt;
'''Historia del Lenguaje C''' .C es un [[Lenguaje de Programación|lenguaje de programación]] creado en [[1972]] por Dennis M. Ritchie en los [[Laboratorios Bell]] como evolución del anterior lenguaje B, a su vez basado en BCPL. Al igual que B, es un lenguaje orientado a la implementación de Sistemas Operativos, concretamente Unix. C es apreciado por la eficiencia del código que produce y es el lenguaje de programación más popular para crear software de sistemas, aunque también se utiliza para crear aplicaciones. &lt;br /&gt;
&lt;br /&gt;
Se trata de un lenguaje débilmente tipificado de medio nivel pero con muchas características de bajo nivel. Dispone de las estructuras típicas de los lenguajes de alto nivel pero, a su vez, dispone de construcciones del lenguaje que permiten un control a muy bajo nivel. Los compiladores suelen ofrecer extensiones al lenguaje que posibilitan mezclar código en ensamblador con código C o acceder directamente a memoria o dispositivos periféricos.&lt;br /&gt;
&lt;br /&gt;
La primera estandarización del lenguaje C fue en ANSI, con el estándar X3.159-[[1989]]. El lenguaje que define este estándar fue conocido vulgarmente como ANSI C. Posteriormente, en 1990, fue ratificado como estándar ISO (ISO/IEC 9899:[[1990]]). La adopción de este estándar es muy amplia por lo que, si los programas creados lo siguen, el código es portátil entre plataformas y/o arquitecturas.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Filosofía ==&lt;br /&gt;
&lt;br /&gt;
Uno de los objetivos de diseño del [[Lenguaje de Programación C|lenguaje C]] es que sólo sean necesarias unas pocas instrucciones en lenguaje máquina para traducir cada elemento del lenguaje, sin que haga falta un soporte intenso en tiempo de ejecución. Es muy posible escribir C a bajo nivel de abstracción; de hecho, C se usó como intermediario entre diferentes lenguajes.&lt;br /&gt;
&lt;br /&gt;
En parte a causa de ser de relativamente bajo nivel y de tener un modesto conjunto de características, se pueden desarrollar compiladores de C fácilmente. En consecuencia, el lenguaje C está disponible en un amplio abanico de plataformas (seguramente más que cualquier otro lenguaje). Además, a pesar de su naturaleza de bajo nivel, el lenguaje se desarrolló para incentivar la programación independiente de la máquina. Un programa escrito cumpliendo los estándares e intentando que sea portátil puede compilarse en muchos computadores.&lt;br /&gt;
&lt;br /&gt;
C se desarrolló originalmente (conjuntamente con el sistema operativo Unix, con el que ha estado asociado mucho tiempo) por programadores para programadores. Sin embargo, ha alcanzado una popularidad enorme, y se ha usado en contextos muy alejados de la programación de sistemas, para la que se diseñó originalmente.&lt;br /&gt;
&lt;br /&gt;
== Historia ==&lt;br /&gt;
El desarrollo inicial de C se llevó a cabo en los Laboratorios Bell de AT&amp;amp;T entre 1969 y 1973; según Ritchie, el periodo más creativo tuvo lugar en 1972. Se le dio el nombre &amp;quot;C&amp;quot; porque muchas de sus características fueron tomadas de un lenguaje anterior llamado &amp;quot;B&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Hay muchas leyendas acerca del origen de C y el sistema operativo con el que está íntimamente relacionado, Unix. Algunas de ellas son:&lt;br /&gt;
&lt;br /&gt;
El desarrollo de C fue el resultado del deseo de los programadores de jugar con Space Travel. Habían estado jugando en el mainframe de su compañía, pero debido a su poca capacidad de proceso y al tener que soportar 100 usuarios, Thompson y Ritchie no tenían suficiente control sobre la nave para evitar colisiones con los asteroides. &lt;br /&gt;
&lt;br /&gt;
Por ese motivo decidieron portar el juego a un PDP-7 de la oficina que no se utilizaba; pero esa máquina no tenía sistema operativo, así que decidieron escribir uno. Finalmente decidieron portar el sistema operativo del PDP-11 que había en su oficina, pero era muy costoso, pues todo el código estaba escrito en lenguaje ensamblador. &lt;br /&gt;
&lt;br /&gt;
Entonces decidieron usar un lenguaje de alto nivel y portátil para que el sistema operativo se pudiera portar fácilmente de un ordenador a otro. Consideraron usar B, pero carecía de las funcionalidades necesarias para aprovechar algunas características avanzadas del PDP-11. Entonces empezaron a crear un nuevo lenguaje, C.&lt;br /&gt;
&lt;br /&gt;
La justificación para obtener el ordenador original que se usó para desarrollar Unix fue crear un sistema que automatizase el archivo de patentes. La versión original de Unix se desarrolló en lenguaje ensamblador. Más tarde, el lenguaje C se desarrolló para poder reescribir el sistema operativo.&lt;br /&gt;
&lt;br /&gt;
En [[1973]], el lenguaje C se había vuelto tan potente que la mayor parte del kernel Unix, originalmente escrito en el lenguaje ensamblador PDP-11/20, fue reescrita en C. Éste fue uno de los primeros núcleos de sistema operativo implementados en un lenguaje distinto al ensamblador. (Algunos casos anteriores son el sistema Multics, escrito en PL/I, y Master Control Program para el B5000 de Burroughs, escrito en ALGOL en 1961).&lt;br /&gt;
&lt;br /&gt;
== El C de Kernighan y Ritchie ==&lt;br /&gt;
&lt;br /&gt;
En [[1978]], Ritchie y Brian Kernighan publicaron la primera edición de El lenguaje de programación C, también conocido como La biblia de C. Este libro fue durante años la especificación informal del lenguaje. El lenguaje descrito en este libro recibe habitualmente el nombre de &amp;quot;el C de Kernighan y Ritchie&amp;quot; o simplemente &amp;quot;K&amp;amp;R C&amp;quot; (La segunda edición del libro cubre el estándar ANSI C, descrito más abajo.)&lt;br /&gt;
&lt;br /&gt;
Kernighan y Ritchie introdujeron las siguientes características al lenguaje:&lt;br /&gt;
*El tipo de datos struct.&lt;br /&gt;
*El tipo de datos long int.&lt;br /&gt;
*El tipo de datos unsigned int.&lt;br /&gt;
*Los operadores (=+ y =-) fueron sustituidos por (+= y -=) para eliminar la ambigüedad sintáctica de expresiones como (i=-10), que se podría interpretar bien como (i =- 10) o bien como (i = -10).&lt;br /&gt;
&lt;br /&gt;
El C de Kernighan y Ritchie es el subconjunto más básico del lenguaje que un compilador debe de soportar. Durante muchos años, incluso tras la introducción del ANSI C, fue considerado &amp;quot;el mínimo común denominador&amp;quot; en el que los programadores debían programar cuando deseaban que sus programas fueran transportables, pues no todos los compiladores soportaban completamente ANSI, y el código razonablemente bien escrito en K&amp;amp;R C es también código ANSI C válido.&lt;br /&gt;
&lt;br /&gt;
En estas primeras versiones de C, las únicas funciones que necesitaban ser declaradas si se usaban antes de la definición de la función eran las que retornaban valores no enteros. Es decir, se presuponía que una función que se usaba sin declaración previa (prototipo) devolvería un entero.&lt;br /&gt;
&lt;br /&gt;
== Variantes ==&lt;br /&gt;
Desde el inicio del lenguaje han surgido varias ramas de evolución que han generado varios lenguajes:&lt;br /&gt;
*Objective-C es un primer intento de proporcionar soporte para la programación orientada a objetos en C, de escasa difusión, pero actualmente usado en Mac OS X y GNUstep.&lt;br /&gt;
*C++ (pronunciado C Plus Plus) diseñado por Bjarne Stroustrup fue el segundo intento de proporcionar orientación a objetos a C y es la variante más difundida y aceptada. Esta versión combina la flexibilidad y el acceso de bajo nivel de C con las características de la programación orientada a objetos como abstracción, encapsulación y ocultación.&lt;br /&gt;
&lt;br /&gt;
También se han creado numerosos lenguajes inspirados en la sintaxis de C, pero que no son compatibles con él:&lt;br /&gt;
*Java, que une una sintaxis inspirada en la del [[C++]] con una orientación a objetos más similar a la de Smalltalk y Objective C.&lt;br /&gt;
*[[JavaScript]], un lenguaje de scripting creado en Netscape e inspirado en la sintaxis de Java diseñado para dar a las páginas web mayor interactividad. A la versión estandarizada se la conoce como ECMAScript.&lt;br /&gt;
*[[C#]] (pronunciado C Sharp) es un lenguaje desarrollado por Microsoft derivado de C/C++ y [[Java]].&lt;br /&gt;
&lt;br /&gt;
== Enlaces Internos  ==&lt;br /&gt;
&lt;br /&gt;
*[[Ciencia de la Información]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Lenguaje de Programación C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
*[http://informatica-full2.blogspot.com/2009/06/historia-del-lenguaje-c.html Informática]&lt;br /&gt;
*[http://lalmada.mayo.uson.mx/cpp/La_historia_del_C++.htm Historia de C++]&lt;br /&gt;
*[http://sopa.dis.ulpgc.es/so/cpp/intro_c/ C]&lt;br /&gt;
*The Development of the C Language.&lt;br /&gt;
&lt;br /&gt;
[[Category:Informática]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Constructor_(C%2B%2B)&amp;diff=3232336</id>
		<title>Constructor (C++)</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Constructor_(C%2B%2B)&amp;diff=3232336"/>
		<updated>2018-11-27T16:10:23Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Definición&lt;br /&gt;
|nombre= Constructor en C++&lt;br /&gt;
|imagen=cODIGO.jpg.JPG&lt;br /&gt;
|tamaño=200px&lt;br /&gt;
|concepto= Los constructores son funciones miembro especiales que sirven para inicializar un objeto de una determinada clase cuando se declara.&lt;br /&gt;
}}'''Constructor en C++'''. Los constructores tienen el mismo nombre que la clase, no retornan ningún valor y no pueden ser heredados. Además deben ser públicos, no tendría ningún sentido declarar un constructor como privado, ya que siempre se usan desde el exterior de la clase, ni tampoco como protegido, ya que no puede ser heredado.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ejemplo de constructor en una clase llamada pareja==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
 #include &amp;lt;iostream.h&amp;gt;&lt;br /&gt;
 class pareja&lt;br /&gt;
 {&lt;br /&gt;
   public:&lt;br /&gt;
    //Constructor&lt;br /&gt;
    pareja(int a2, int b2);&lt;br /&gt;
    //Funciones miembros de la clase &amp;quot;pareja&amp;quot;&lt;br /&gt;
    void Lee(int &amp;amp;a2, int &amp;amp;b2);&lt;br /&gt;
    void Guardar(int a2, int b2);&lt;br /&gt;
   private:&lt;br /&gt;
    //Datos miembros de la clase &amp;quot;pareja&amp;quot;&lt;br /&gt;
    int a, b;&lt;br /&gt;
 }&lt;br /&gt;
 pareja::pareja(int a2, int b2)&lt;br /&gt;
 {&lt;br /&gt;
    a = a2;&lt;br /&gt;
    b = b2;&lt;br /&gt;
 }&lt;br /&gt;
 void pareja::Lee(int &amp;amp;a2, int &amp;amp;b2)&lt;br /&gt;
 {&lt;br /&gt;
    a2 = a;&lt;br /&gt;
    b2 = b;&lt;br /&gt;
 }&lt;br /&gt;
 void pareja::Guarda(int a2, int b2)&lt;br /&gt;
 {&lt;br /&gt;
    a = a2;&lt;br /&gt;
    b = b2;&lt;br /&gt;
 }&lt;br /&gt;
 int main(int argc, char *argv[])&lt;br /&gt;
 {&lt;br /&gt;
    pareja par1(12, 32);&lt;br /&gt;
    int x, y;&lt;br /&gt;
    par1.Lee(x, y);&lt;br /&gt;
    cout &amp;lt;&amp;lt; &amp;quot;Valor de par1.a: &amp;quot; &amp;lt;&amp;lt; x &amp;lt;&amp;lt;endl;&lt;br /&gt;
    cout &amp;lt;&amp;lt; &amp;quot;Valor de par2.b: &amp;quot; &amp;lt;&amp;lt; x &amp;lt;&amp;lt;endl;&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Sobrecarga de constructores==&lt;br /&gt;
&lt;br /&gt;
También pueden definirse varios constructores para cada clase, es decir, la función constructor puede sobrecargarse. La única limitación es que no pueden declararse varios constructores con el mismo número y el mismo tipo de argumentos.&lt;br /&gt;
&lt;br /&gt;
==Constructor copia==&lt;br /&gt;
&lt;br /&gt;
Un constructor de este tipo crea un objeto a partir de otro objeto existente. Estos constructores sólo tienen un argumento, que es una referencia a un objeto de su misma clase.&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
&lt;br /&gt;
*[[Ciencia de la Información]]&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Puntero (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
==Fuente==&lt;br /&gt;
&lt;br /&gt;
*Curso de C++. Autor: [[Salvador Pozo Coronado]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Informática]][[Category:Programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Ficheros_en_C%2B%2B&amp;diff=3232335</id>
		<title>Ficheros en C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Ficheros_en_C%2B%2B&amp;diff=3232335"/>
		<updated>2018-11-27T16:10:03Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Definición&lt;br /&gt;
|nombre= Ficheros en C++&lt;br /&gt;
|imagen=&lt;br /&gt;
|tamaño=&lt;br /&gt;
|concepto= Es una colección de elementos lógicamente relacionados y almacenados en memoria secundaria. A más bajo nivel, un fichero es una secuencia de bits almacenado en algún dispositivo externo (como por ejemplo uno de memoria secundaria).&lt;br /&gt;
}}'''Ficheros en C++'''. Es simplemente un flujo externo que se puede abrir para entrada (dando lugar a un flujo de archivo de entrada que, para simplificar, llamaremos simplemente archivo o fichero de entrada), para salida (dando lugar a un flujo de archivo de salida que, para simplificar, llamaremos simplemente archivo o fichero de salida) o para entrada-salida(archivo o fichero de entrada-salida o archivo de E/S).&lt;br /&gt;
&lt;br /&gt;
== Definición, apertura y cierre de ficheros ==&lt;br /&gt;
*Declaración de Variables de tipo &amp;quot;Fichero&amp;quot;:&lt;br /&gt;
 &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| ifstream descriptor;             // Para fichero de entrada&lt;br /&gt;
|-&lt;br /&gt;
| ofstream descriptor;            // Para ficheros de salida&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*Apertura de [[Ficheros]] de Texto (supongamos TCadena nombre)&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| in.open(nombre);                // Apertura para Lectura&lt;br /&gt;
|-&lt;br /&gt;
| out.open(nombre);   //Apertura para Escritura. (borra el contenido si lo hubiera)&lt;br /&gt;
|-&lt;br /&gt;
| out.open(nombre,ios::app);             //Apertura para añadir datos al final&lt;br /&gt;
|-&lt;br /&gt;
| in.open(nombreios::in ios::out);  //Apertura para Lectura y Escritura&lt;br /&gt;
|-&lt;br /&gt;
| out.open(nombre,ios::in ios::out); //Apertura para Lectura y Escritura&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*Cierre de ficheros: Un fichero anteriormente abierto y con un descriptor asociado a él debe ser cerrado con el fin de liberar los recursos asociados a él de la siguiente forma:&lt;br /&gt;
&lt;br /&gt;
descriptor.close( )&lt;br /&gt;
&lt;br /&gt;
== Detección de fin de fichero y otras funciones==&lt;br /&gt;
*La función eof() que devuelve true si se ha alcanzado el final del fichero y falso en cualquier otro caso. REQUIERE LECTURA ADELANTADA: Para que la función eof() devuelva un valor de verdad (actualizado).&lt;br /&gt;
*La funcioón fail() devuelve true si existe un error en una operación de flujo asociada al fichero.&lt;br /&gt;
*La función bad() devuelve true si el flujo está corrupto.&lt;br /&gt;
*La función good() que devuelve true si no existe un error en una operación de flujo y false en caso contrario.&lt;br /&gt;
Antes de empezar a leer o escribir en un fichero es siempre conveniente verificar que la operación de apertura se realizó con éxito.&lt;br /&gt;
&lt;br /&gt;
== Ficheros de texto==&lt;br /&gt;
&lt;br /&gt;
La lectura y la escritura en un archivo de texto se puede realizar directamente con los operadores y al igual que se realiza sobre los flujos estándares cin y cout.&lt;br /&gt;
&lt;br /&gt;
==Ver también==&lt;br /&gt;
&lt;br /&gt;
*[[Ciencia de la Información]]&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Puntero (C++)]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
==Fuente==&lt;br /&gt;
&lt;br /&gt;
*Laboratorio de Programación 1º A E.T.S.I. Informática Gestión&lt;br /&gt;
*[http://www.lcc.uma.es/~pastrana/LP/curso0405/P13_05.pdf Clase Práctica: Ficheros en C++]&lt;br /&gt;
*[http://www.forosuse.org/forosuse/showthread.php?t=3530 Foro Suse]&lt;br /&gt;
*[http://www.todoexpertos.com/categorias/tecnologia-e-internet/programacion/c-y-c------/respuestas/2373771/c-ficheros Todos Expertos]&lt;br /&gt;
&lt;br /&gt;
[[Category: Informática]] [[Category: Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=C%2B%2B&amp;diff=3232334</id>
		<title>C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=C%2B%2B&amp;diff=3232334"/>
		<updated>2018-11-27T16:09:36Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Ficha Software&lt;br /&gt;
|nombre=C++&lt;br /&gt;
|familia=Derivados de C&lt;br /&gt;
|imagen=C++.jpg&lt;br /&gt;
|tamaño=&lt;br /&gt;
|descripción=Lenguaje de programación&lt;br /&gt;
|imagen2=&lt;br /&gt;
|tamaño2=&lt;br /&gt;
|descripción2=&lt;br /&gt;
|creador=Bjarne Stroustrup&lt;br /&gt;
|desarrollador=&lt;br /&gt;
|diseñador=&lt;br /&gt;
|modelo de desarrollo=&lt;br /&gt;
|lanzamiento inicial=1983&lt;br /&gt;
|versiones=&lt;br /&gt;
|última versión estable=&lt;br /&gt;
|género=&lt;br /&gt;
|sistemas operativos=Multiplataforma&lt;br /&gt;
|idioma=&lt;br /&gt;
|licencia=&lt;br /&gt;
|premios=&lt;br /&gt;
|web=&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''C++''' es un lenguaje imperativo orientado a objetos derivado del C. En realidad un superconjunto de C, que nació para añadirle cualidades y características de las que carecía. El resultado es que como su ancestro, sigue muy ligado al hardware subyacente, manteniendo una considerable potencia para programación a bajo nivel, pero se la han añadido elementos que le permiten también un estilo de programación con alto nivel de abstracción. Estrictamente hablando, C no es un subconjunto de C++; de hecho es posible escribir código C que es ilegal en C++. Pero a efectos prácticos, dado el esfuerzo de compatibilidad desplegado en su diseño, puede considerarse que C++ es una extensión del C clásico. La definición &amp;quot;oficial&amp;quot; del lenguaje nos dice que C++ es un lenguaje de propósito general basado en el C, al que se han añadido nuevos tipos de datos, clases, plantillas, mecanismo de excepciones, sistema de espacios de nombres, funciones inline, sobrecarga de [[Operadores|operadores]], referencias, operadores para manejo de memoria persistente, y algunas utilidades adicionales de librería (en realidad la [[Librería|librería]] Estándar C es un subconjunto de la librería C++) &amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
== Un Poco de historia  ==&lt;br /&gt;
&lt;br /&gt;
El comité para el estándar [[ANSI|ANSI]] [[C]] fue formado en [[1983]] con el objetivo de crear un lenguaje uniforme a partir del C original, desarrollado por Kernighan y Ritchie en 1972, en la ATT. Hasta entonces el estándar lo marcaba el libro escrito en 1978 por estos dos autores1. El lenguaje C++ se comenzó a desarrollar en 1980. Su autor fue [[Bjarne Stroustrup]], también de la ATT. Al comienzo era una extensión del lenguaje C que fue denominada C with classes. Este nuevo lenguaje comenzó a ser utilizado fuera de la ATT en [[1983]]. El nombre C++ es también de ese año, y hace referencia al carácter del operador incremento de C (++). Ante la gran difusión y éxito que iba obteniendo en el mundo de los programadores, la ATT comenzó a estandarizarlo internamente en [[1987]]. En [[1989]] se formó un comité ANSI (seguido algún tiempo después por un comité [[ISO|ISO]]) para estandarizarlo a nivel americano e internacional. En la actualidad, el C++ es un lenguaje versátil, potente y general. Su éxito entre los programadores profesionales le ha llevado a ocupar el primer puesto como herramienta de desarrollo de aplicaciones. El C++ mantiene las ventajas del C en cuanto a riqueza de [[Operadores|operadores]] y expresiones, flexibilidad, concisión y eficiencia. Además, ha eliminado algunas de las dificultades y limitaciones del C original. La evolución de C++ ha continuado con la aparición de [[Java]], un lenguaje creado simplificando algunas cosas de C++ y añadiendo otras, que se utiliza para realizar aplicaciones en Internet. Hay que señalar que el C++ ha influido en algunos puntos muy importantes del ANSI C, como por ejemplo en la forma de declarar las funciones, en los punteros a void, etc. En efecto, aunque el C++ es posterior al C, sus primeras versiones son anteriores al ANSI C, y algunas de las mejoras de éste fueron tomadas del C++. C++ es a la vez un lenguaje procedural (orientado a algoritmos) y orientado a objetos. Como lenguaje procedural se asemeja al C y es compatible con él, aunque ya se ha dicho que presenta ciertas ventajas. Como lenguaje orientado a objetos se basa en una filosofía completamente diferente, que exige del programador un completo cambio de mentalidad. Las características propias de la Programación Orientada a Objetos (Object Oriented Programming, u OOP) de C++ son modificaciones mayores que sí que cambian radicalmente su naturaleza.&lt;br /&gt;
&lt;br /&gt;
==Conceptos generales de la programación orientada a objetos== &lt;br /&gt;
&lt;br /&gt;
*Clase: Es una plantilla que define la      estructura  de un conjunto de objetos, que al ser creados se llamarán las       instancias de la clase. Esta estructura está compuesta por la definición       de los atributos y la implementación de las operaciones ( métodos  ). &lt;br /&gt;
&lt;br /&gt;
*Objeto: Es la      implementación de una instancia de  clase, es decir, una ocurrencia de      esta, que tiene los atributos  definidos por la clase, y sobre la que se      puede ejecutar las  operaciones definidas en ella. &lt;br /&gt;
&lt;br /&gt;
*Identidad:      Característica de cada objeto que lo  diferencia de los demás, incluyendo      de aquellos que pudieran  pertenecer a la misma clase y tener los mismos      valores en sus  atributos.&lt;br /&gt;
&lt;br /&gt;
*Herencia: Es      la capacidad que tienen las clases para heredar propiedades y métodos de      otras clases. &lt;br /&gt;
&lt;br /&gt;
== Acerca de la POO  ==&lt;br /&gt;
&lt;br /&gt;
La [[POO|POO]] es una nueva filosofía de programación que se basa en la utilización de objetos. El objetivo de la POO no es sino la meta de cualquier modelo de programación estructurada convencional: &amp;quot;imponer&amp;quot; una serie de normas de desarrollo que aseguren y faciliten la mantenibilidad y reusabilidad del código. Los mecanismos básicos de la POO son: objetos, mensajes, métodos y clases. &lt;br /&gt;
&lt;br /&gt;
*Objetos. Un objeto es una entidad que tiene unos atributos particulares (datos) y unas formas de operar sobre ellos (los métodos o funciones miembro). Es decir, un objeto incluye, por una parte una serie de operaciones que definen su comportamiento, y una serie de variables manipuladas por esas funciones que definen su estado. Por ejemplo, una ventana Windows contendrá operaciones como &amp;quot;maximizar&amp;quot; y variables como &amp;quot;ancho&amp;quot; y &amp;quot;alto&amp;quot; de la ventana. &lt;br /&gt;
*Mensajes. En C++, un mensaje se corresponde con el nombre de uno de los métodos de un objeto. Cuando se pasa un mensaje a un objeto, este responde ejecutando el código de la función asociada. &lt;br /&gt;
*[[Método|Método]]. Un método (función miembro) se implementa dentro de un objeto y determina como tiene que actuar el objeto cuando se produce el mensaje asociado. En C++ un método se corresponde con la definición de la función miembro del objeto. La estructura más interna de un objeto está oculta, de tal manera que la única conexión con el exterior son los mensajes &lt;br /&gt;
*Clases. Una clase es la definición de un tipo de objetos. De esta manera, una clase &amp;quot;Empleado&amp;quot; representaría todos los empleados de una empresa, mientras que un objeto de esa clase (también denominado instancia) representaría a uno de esos empleados en particular.&lt;br /&gt;
&lt;br /&gt;
Las principales características de la POO son: abstracción, encapsulamiento, herencia y polimorfismo: &lt;br /&gt;
&lt;br /&gt;
*[[Abstracción|Abstracción]]. Es el mecanismo de diseño en la POO. Nos permite extraer de un conjunto de entidades datos y comportamientos comunes para almacenarlos en clases. &lt;br /&gt;
*Encapsulamiento. Mediante esta técnica conseguiremos que cada clase sea una caja negra, de tal manera que los objetos de esa clase se puedan manipular como unidades básicas. Los detalles de la implementación se encuentran dentro de la clase, mientras que desde el exterior, un objeto será simplemente una entidad que responde a una serie de mensajes públicos (también denominados interfaz de la clase). &lt;br /&gt;
*Herencia. Es el mecanismo que nos permite crear clases derivadas (especialización) a partir de clases bases (generalización). Es decir, podríamos tener la clase &amp;quot;Empleado&amp;quot; (clase base) y la clase &amp;quot;Vendedor&amp;quot; derivando de la anterior. Una librería de clases (como la MFC) no es más que un conjunto de definiciones de clases interconectadas por múltiples relaciones de herencia. &lt;br /&gt;
*Polimorfismo. Esta característica nos permite disponer de múltiples implementaciones de un mismo método de clase, dependiendo de la clase en la que se realice. Es decir, podemos acceder a una variedad de métodos distintos (con el mismo nombre) mediante el mismo mecanismo de acceso. En C++ el polimorfismo se consigue mediante la definición de clases derivadas, funciones virtuales y el uso de punteros a objetos.&lt;br /&gt;
&lt;br /&gt;
Otros dos conceptos muy importantes en la POO son relativos a la creación y destrucción de objetos. En lenguajes estructurados convencionales, cuando se define una variable se le reserva espacio en memoria y, si no se inicializa expresamente, se hace por defecto (por ejemplo, en C una variable global siempre se inicializa a 0, pero una automática no, por lo que si no se inicializa expresamente su contenido inicial será basura); por otra parte, cuando se destruye una variable (por que se abandona el ámbito de su definición - scope -) se libera la memoria que estaba ocupando. Si ahora hacemos el paralelismo obligado entre variables y objetos para los lenguajes POO nos daremos cuenta de que deben existir procedimientos especiales de construcción y destrucción de objetos. En concreto, cada clase tiene dos funciones miembro especiales denominadas constructor y destructor. &lt;br /&gt;
&lt;br /&gt;
*[[Constructor (C++)|Constructor]] -&amp;amp;gt; Función miembro que es automáticamente invocada cada vez que se define un objeto, su objetivo es la inicialización del mismo. Toma el mismo nombre que la clase, puede recibir parámetros y podemos tener varios constructores definidos. &lt;br /&gt;
*[[Destructor|Destructor]] -&amp;amp;gt; Función miembro invocada automáticamente cada vez que se destruye un objeto. Su objetivo es realizar operaciones como liberación de memoria, cerrar ficheros abiertos, etc. Toma el mismo nombre de la clase comenzado primero por el carácter &amp;quot;~&amp;quot;, no toma parámetros y no admite la sobrecarga (sólo puede existir uno en cada clase).&lt;br /&gt;
&lt;br /&gt;
En muchos casos, para las clases mas sencillas, podemos encontrar clases que no tiene constructor o destructor, ó ninguno de los dos. En C++, siempre existen constructores y destructores por defecto que realizan una inicialización/liberación estándar.&lt;br /&gt;
&lt;br /&gt;
== Acerca de Intérprete y compiladores  ==&lt;br /&gt;
&lt;br /&gt;
Antes, mencionar que tanto C como C++ son lenguajes compilados, y no interpretados. Esta diferencia es muy importante, ya que afecta mucho a muchos aspectos relacionados con la ejecución del programa. En un lenguaje interpretado, el programa está escrito en forma de texto, es el propio programa fuente. Este programa fuente es procesado por un programa externo, el intérprete, que traduce el programa, instrucción a instrucción, al tiempo que lo ejecuta. En los lenguajes interpretados no existen programas ejecutables directamente por el ordenador. El intérprete traduce, en tiempo real, cada línea del programa fuente, cada vez que se quiere ejecutar el programa. El los lenguajes compilados el proceso de traducción sólo se hace una vez. El programa compilador toma como entrada el código fuente del programa, y da como salida un fichero que puede ser ejecutado por el ordenador directamente. Una vez compilado, el programa ejecutable es autónomo, y ya no es necesario disponer del programa original ni del compilador para ejecutarlo. Cada opción tiene sus ventajas e inconvenientes, y algunas características que son consideradas una ventaja, pueden ser un inconveniente en ciertas circunstancias, y viceversa. &lt;br /&gt;
&lt;br /&gt;
*Los lenguajes interpretados son fácilmente modificables, ya que necesitamos tener el el código fuente disponible en el ordenador. En los compilados, estos ficheros no son necesarios, una vez compilados. &lt;br /&gt;
*Los lenguajes interpretados necesitan un programa externo, llamado intérprete o a veces máquina virtual, o framework. Este programa actua como intermediario entre el fuente y el sistema operativo. En los compilados ese papel lo desempeña el compilador, pero al contrario que con el intérprete, una vez ha hecho su trabajo, no es necesario que esté presente para ejecutar el programa. &lt;br /&gt;
*Estas dos características, lógicamente, hacen que los programas compilados requieran menos espacio de memoria que los interpretados (si contamos el espacio usado por el intérprete), y en general, los compilados son más rápidos, ya que sólo se compilan una vez, y el tiempo dedicado a esa tarea no se suma al de ejecución.&lt;br /&gt;
&lt;br /&gt;
Entre los lenguajes interpretados están: [[BASIC|BASIC]] (Código de instrucciones de propósito general para principiantes), Java, [[PHP|PHP]]. Muchos lenguajes de script, etc. Entre los lenguajes compilados están: C, C++, Pascal. &lt;br /&gt;
&lt;br /&gt;
== Qué se puede hacer con C++  ==&lt;br /&gt;
&lt;br /&gt;
¿Qué clase de programas y aplicaciones se pueden crear usando C y C++? La respuesta es muy sencilla: TODOS. Tanto C como C++ son lenguajes de programación de propósito general. Todo puede programarse con ellos, desde sistemas operativos y compiladores hasta aplicaciones de bases de datos y procesadores de texto, pasando por juegos, aplicaciones a medida, etc. &lt;br /&gt;
&lt;br /&gt;
=== Un ejemplo de código  ===&lt;br /&gt;
&lt;br /&gt;
Este es el clásico programa hola mundo, la idea está centrada en el nacimiento de un nuevo programa de manos de su creador. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;Hola mundo&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ¿Qué se ha hecho en C o en C++?  ==&lt;br /&gt;
&lt;br /&gt;
=== Sistemas Operativos y otros programas ===&lt;br /&gt;
&lt;br /&gt;
*Así como Unix el antecesor de este sistema operativo, [[GNU/Linux]] -a menudo denominado tan sólo como [[Linux]], que es el nombre del núcleo del SO- hace uso de un buen número de lenguajes de programación en sus distintos componentes. ¿Cuáles son esos lenguajes? Cada tipo de recurso parece tener ciertas preferencias, y es que hay lenguajes más adecuados para unas cosas. Obviamente el lenguaje de programación C sigue siendo la base, pero hay mucho más implicados. &lt;br /&gt;
*Kernel y drivers de dispositivos: Tanto los drivers como el kernel funcionan en un nivel realmente bajo de operaciones en el ordenador. Para escribir el kernel del sistema operativo y acceder a las propiedades del hardware tales como los ciclos de la memoria, buses de entrada/salida, etc., se necesita un lenguaje que pueda comunicarse con el hardware con potencia. El kernel Linux hace uso del lenguaje C (aunque en realidad no se trate de un lenguaje de bajo nivel) con una pequeña parte en lenguaje ensamblador. &lt;br /&gt;
&lt;br /&gt;
*Librerías y utilidades: Las librerías y utilidades básicas del sistema tales como mkdir, chmod, chown, head, tail, chroot, uptime, users también están escritas en lenguaje C.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
*Gestores de paquetes y programas de configuración: Los gestores de paquetes tales como yum, apt, dpkg, etcétera, también están escritos en C, que como veis es la estrella absoluta de los componentes &amp;quot;base&amp;quot; de un sistema [[GNU/Linux]].&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
*Entornos de Escritorio y gestores de ventanas: La mayoría de gente usa un entorno de escritorio, y es que a día de hoy poco queda sólo en interfaz de línea de comandos. Los gestores de ventanas tales como metacity, kwin están desarrollados en C y requieren gcc para ser compilados. El entorno de escritorio, iconos, ventanas, barras de herramientas, etc, están basados en librerías específicas (Qt para KDE, GTK+ para GNOME) y hacen uso del lenguaje mayoritario, C.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
*Aplicaciones gráficas de usuario: Este es el punto donde entran en juego una gran cantidad de lenguajes de programación, dado que básicamente es la capa más alta. Tenemos una gran variedad: C, Python, Java, Perl y otros. Hay librerías GTK+, Tcl/Tk, Qt que son un frontend gráfico a tareas que corren por detrás en línea de comando.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*El Sistema operativo [[Windows]] está hecho básicamente en C, C tiene la ventaja de que puede escalarse con ensamblador, lo cual es buena opción para optimizar ciertos módulos.&lt;br /&gt;
&lt;br /&gt;
Las versiones anteriores de Windows estaban hechas en Basic (Basic NO visual Basic) que es un lenguaje de bajo nivel de hace unos cuantos años ya. Es un lenguaje que se usa mucho en la electrónica aun. &lt;br /&gt;
&lt;br /&gt;
*Actualmente Windows 7 Mac os x Leopard y [[Linux]] usan mas de una Tecnología ya se empezó a usar [[Lenguaje de Programación C Sharp|c#]] c++ y hasta java en el caso de linux se usa phytom c y tbn ensambladores y demás cosas, y Mac siempre basado en Unix con compilación en C++ para los últimos Sistemas Operativos.&lt;br /&gt;
&lt;br /&gt;
== Ver también ==&lt;br /&gt;
&lt;br /&gt;
*[[Ciencia de la Información]]&lt;br /&gt;
*[[Puntero (C++)]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
&lt;br /&gt;
== Fuentes  ==&lt;br /&gt;
&lt;br /&gt;
*[http://mat21.etsii.upm.es/ayudainf/aprendainf/Cpp/manualcpp.pdf Manual C++]&lt;br /&gt;
*[http://www.monografias.com/trabajos5/visualcurso/visualcurso.shtml Curso Visual]&lt;br /&gt;
*[http://www.zator.com/Cpp/E1_2.htm C++]&lt;br /&gt;
*[http://es.wikipedia.org/wiki/C%2B%2B C++ en Wikipedia]&lt;br /&gt;
*[http://www.programacionfacil.com/cpp:informacion_y_conocimiento C++ en ProgramacionFacil.com]&lt;br /&gt;
*[http://www.somoslibres.org/modules.php?name=News&amp;amp;file=article&amp;amp;sid=2708 C++ en SomosLibres.org]&lt;br /&gt;
*[http://www.psicofxp.com/forums/programacion.313/374200-c-y-sistemas-operativos.html El C++ y los Sistemas Operativos]&lt;br /&gt;
*[http://es.kioskea.net/forum/affich-101630-lenguaje-en-que-fue-escrito-windows Windows está escrito en C++]&lt;br /&gt;
&lt;br /&gt;
[[Category:Programación]][[Category:Informática]]&lt;br /&gt;
[[Category:Lenguajes_de_programación_orientada_a_objetos]]&lt;br /&gt;
[[Category:Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Librer%C3%ADa_Est%C3%A1ndar_C%2B%2B&amp;diff=3232333</id>
		<title>Librería Estándar C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Librer%C3%ADa_Est%C3%A1ndar_C%2B%2B&amp;diff=3232333"/>
		<updated>2018-11-27T16:09:13Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Librería Estándar C++ |imagen=  |concepto= Una librería es un conjunto de recursos (algoritmos) prefabricados, que pueden ser utilizados por el programador para realizar determinadas operaciones }}''' Librería Estándar C++ '''. [[C++|C++]] no llega al nivel de simplicidad de su antecesor C, pero al igual que aquél, tampoco dispone de utilidades o funciones para entrada o salida implementadas en el propio lenguaje, de modo que estas y otras muchas, como manejo de cadenas de caracteres (strings), manejo de ficheros, funciones matemáticas Etc. son implementadas en forma de librerías externas.&lt;br /&gt;
== Sinopsis ==&lt;br /&gt;
Una librería es un conjunto de recursos (algoritmos) prefabricados, que pueden ser utilizados por el programador para realizar determinadas operaciones. Las declaraciones de las funciones (prototipos) utilizadas en estas librerías, junto con algunas macros y constantes predefinidas que facilitan su utilización, se agrupan en ficheros de nombres conocidos que suelen encontrarse en sitios predefinidos. Por ejemplo, en los sistemas UNIX, en  /usr/include. Estos ficheros se suelen llamar &amp;quot;de cabecera&amp;quot;, porque es tradición utilizar las primeras líneas del programa para poner las directivas #include que los incluirá en el fuente durante la fase de preprocesado.&lt;br /&gt;
== Clases de librerías ==&lt;br /&gt;
Los [[Compilador|compiladores]] [[C++|C++]] incluyen un amplio repertorio de clases, funciones y macros que permiten realizar una amplia variedad de tareas, incluyendo entradas/salidas de bajo y alto nivel; manipulación de cadenas alfanuméricas y ficheros; control de procesos (incluyendo multiproceso); manejo de memoria; cálculos matemáticos y un largo etcétera.&lt;br /&gt;
Este repertorio de recursos es denominado colectivamente como &amp;quot;Rutinas de librería&amp;quot;; &amp;quot;Librerías de ejecución&amp;quot; RTL (&amp;quot;Runtime Librarys&amp;quot;) o simplemente &amp;quot;Librerías&amp;quot;.   Puede decirse que el lenguaje aislado (tal cual) no tiene prácticamente ninguna utilidad sin la concurrencia de estas utilidades. El Estándar C++ las clasifica según su utilidad:&lt;br /&gt;
•	Soporte del lenguaje&lt;br /&gt;
•	Diagnóstico&lt;br /&gt;
•	Utilidades generales&lt;br /&gt;
•	Cadenas alfanuméricas (&amp;quot;Strings&amp;quot;)&lt;br /&gt;
•	Localización&lt;br /&gt;
•	Contenedores&lt;br /&gt;
•	Iteradores&lt;br /&gt;
•	Algoritmos&lt;br /&gt;
•	Cálculo numérico&lt;br /&gt;
•	Entrada/Salida&lt;br /&gt;
=== Librería Estándar C++ ===&lt;br /&gt;
Para poner un poco de orden, el Estándar C++ define la denominada Librería Estándar que debe acompañar a cada implementación del compilador que se adhiera al estándar. Es decir: la norma determina cuales son, como se llaman y como se utiliza este conjunto de algoritmos que deben acompañar (como mínimo) a cada implementación del compilador que quiera llamarse &amp;quot;Estándar&amp;quot;. La última versión, ISO/IEC 14882 del año 1998, especifica que se compone de 32 ficheros de cabecera de nombres fijos y conocidos agrupados según la funcionalidad de los algoritmos. Son los siguientes:&lt;br /&gt;
 &lt;br /&gt;
Ficheros	Funcionalidad/funciones&lt;br /&gt;
&lt;br /&gt;
&amp;lt;algorithm&amp;gt;	Parte de la STL que describe los algoritmos&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bitset&amp;gt;	Parte de la STL relativa a contenedores tipo bitset. Set de valores booleanos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;complex&amp;gt;	Parte de la librería numérica de la STL relativa a los complejos .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;deque&amp;gt;	Parte de la STL relativa a contenedores tipo deque;  un tipo de colas: &amp;quot;Double-ended-queue&amp;quot; .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;exception&amp;gt;	Parte de la librería de diagnóstico relativa al manejo de excepciones&lt;br /&gt;
&lt;br /&gt;
&amp;lt;fstream&amp;gt;	Flujos hacia/desde ficheros.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;functional&amp;gt;	Parte de la STL relativa a Objetos-función&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iomanip&amp;gt;	Manipuladores.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ios&amp;gt;	Supreclases para manejo de flujos de E/S.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iosfwd&amp;gt;	Contiene declaraciones adelantadas de todas las plantillas de flujos y sus typedefs estándar. Por ejemplo ostream.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iostream&amp;gt;	Parte del a STL que contiene los algoritmos estándar de E/S.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;istream&amp;gt;	Algoritmos estándar de flujos de entrada.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iterator&amp;gt;	Parte de la STL relacionada con iteradores, un tipo de puntero que permite utilizar los algoritmos de la Librería con las estructuras de datos representadas por los contenedores.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;limits&amp;gt;	Descripción de propiedades dependientes de la implementación que afectan a los tipos fundamentales.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;list&amp;gt;	Parte de la STL relativa a contenedores tipo list;  listas doblemente enlazadas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;locale&amp;gt;	Parte de la STL relativa a la internacionalización.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;map&amp;gt;	Parte de la STL relativa a contenedores tipo map.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;memory&amp;gt;	Utilidades relativas a la gestión de memoria, incluyendo asignadores  y punteros inteligentes (auto_ptr).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;new&amp;gt;	Manejo de memoria dinámica.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;numeric&amp;gt;	Parte de la librería numérica de la STL relativa a operaciones numéricas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ostream&amp;gt;	Algoritmos estándar para los flujos de salida.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;queue&amp;gt;	Parte de la STL relativa a contenedores tipo queue;  colas de objetos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;set&amp;gt;	Parte de la STL relativa a contenedores tipo set.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sstream&amp;gt;	Flujos hacia/desde cadenas alfanuméricas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;stack&amp;gt;	Parte de la STL relativa a contenedores tipo stack;  pilas de objetos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;stdexcept&amp;gt;	Parte de la STL relativa a las clases de las que derivan los objetos lanzados por las excepciones ocasionadas en los algoritmos de la propia STL y otras expresiones.  Estas clases son utilizadas para reportar errores detectados durante runtime.  Los usuarios también pueden utilizar excepciones para reportar errores en sus propios programas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;streambuf&amp;gt;	Parte de la STL relativa al Almacenamiento de flujos de E/S (&amp;quot;Stream buffers&amp;quot;).  Define los tipos que controlan la capa de transporte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;string&amp;gt;	Parte de la STL relativa a contenedores tipo string;  una generalización de las cadenas alfanuméricas para albergar cadenas de objetos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;typeinfo&amp;gt;	Mecanismo de identificación de tipos en tiempo de ejecución.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;utility&amp;gt;	Parte de la STL que contiene elementos auxiliares como [[Operadores|operadores]] y pares (pairs).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;valarray&amp;gt;	Parte de la librería numérica de la STL relativa a manejo de matrices numéricas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vector&amp;gt;	Parte de la STL relativa a los contenedores tipo vector; una generalización de las matrices unidimensionales C/C++.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Aunque generalmente las librerías no aportan ninguna característica al lenguaje (se supone que son utilidades auxiliares que no forman parte del lenguaje propiamente dicho), una pequeña porción de la Librería Estándar C++ sí aporta características que se consideran pertenecientes a este, de forma que deben estar presentes los ficheros de cabecera correspondientes si se desea usarlas. En concreto se refieren a los siguientes elementos:&lt;br /&gt;
&lt;br /&gt;
•	[[Operadores|operadores]] new, new[], delete y delete[].&lt;br /&gt;
&lt;br /&gt;
•	Clase type_info que corresponde al mecanismo RTTI de identificación de tipos en tiempo de ejecución representado por el operador typeid &lt;br /&gt;
&lt;br /&gt;
•	Rutinas de inicio y terminación.&lt;br /&gt;
&lt;br /&gt;
•	Las excepciones estándar lanzadas por los algoritmos anteriores&lt;br /&gt;
&lt;br /&gt;
=== Librería C ===&lt;br /&gt;
Además de otras nuevas, cuyo diseño e importancia cambian drásticamente la filosofía del lenguaje, C++ incluye prácticamente la totalidad de [[Función_(programación)| funciones]] de la primitiva librería estándar C. A esta librería, mantenida por compatibilidad, la denominamos Librería clásica.&lt;br /&gt;
=== Otras librerías ===&lt;br /&gt;
Además de las que proporciona el estándar y las complementarias que pueda incluir por su cuenta el fabricante del compilador, en los proyectos reales se suelen utilizar infinidad de otras librerías, comerciales o públicas, que facilitan el trabajo en áreas particulares, y en este sentido, recordar que uno de los pecados que el programador novel debe evitar, es la tendencia a querer reinventar constantemente la rueda. De forma que el consejo es utilizar en lo posible librerías que estén probadas y sean fácilmente accesibles. Aunque hay que tener cuidado, porque determinados proyectos exigen que las librerías utilizadas estén perfectamente documentadas y en ciertos casos, que se cuente con los fuentes correspondientes.&lt;br /&gt;
== Componentes ==&lt;br /&gt;
Al referirnos a las librerías C++ utilizamos la terminología siguiente:&lt;br /&gt;
&lt;br /&gt;
•	RTL  Conjunto de librerías que acompañan a un compilador (&amp;quot;Runtime Library&amp;quot;), sean o no estándar.&lt;br /&gt;
&lt;br /&gt;
•	Librería Estándar. Conjunto de librerías cuyo contenido está definido por el Estándar C++ (abreviadamente LE).&lt;br /&gt;
&lt;br /&gt;
•	Libería clásica. Parte de la Librería Estándar correspondiente al C clásico.&lt;br /&gt;
&lt;br /&gt;
•	STL (&amp;quot;Standard Templete Library&amp;quot;). Parte de la LE genuina de C++ (que no es heredada de C) y que responde a la forma &amp;quot;++&amp;quot; de hacer las cosas.&lt;br /&gt;
&lt;br /&gt;
La calidad de un compilador C++ viene determinada en gran medida por la calidad y cantidad de su RTL; por su grado de adherencia al Estándar  y por el grado de soporte que proporciona para la plataforma concreta a que se destina.&lt;br /&gt;
&lt;br /&gt;
En lo que concierne a la programación para MS Windows (las referencias a la plataforma Wintel surgen de forma constante e inevitable), los [[Compilador|compiladores]] Borland C++ y MS Visual C++ son quizás los más conocidos y utilizados.  El primero incluye una completa librería denominada VCL (Visual Component Library. La del segundo es conocida como MFC (Microsoft Foundation Classes).&lt;br /&gt;
&lt;br /&gt;
Linux dispone de su propio compilador: GNU Cpp, que comenzó siendo un compilador C y ha evolucionado a un producto que es en realidad un superconjunto de compiladores. No solo puede compilar código C y C++;  también otros lenguajes como Ada o Fortran;  de forma que es común referirse a ellos como GCC (&amp;quot;GNU Compiler Collection&amp;quot;).  La buena noticia es que existen versiones de este compilador para plataformas Windows, de forma que incluso en este ambiente &amp;quot;Propietario&amp;quot; pueden realizarse desarrollos utilizando herramientas &amp;quot;Open source&amp;quot; &lt;br /&gt;
A grandes rasgos la librería Estándar C++ comprende los siguientes módulos:&lt;br /&gt;
&lt;br /&gt;
•	La denominada Librería Estándar de Plantillas, abreviadamente STL (&amp;quot;Standard Templete Library&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
•	Librería numérica. Parte de la STL que contiene algoritmos especialmente concebidos para computación numérica. Por ejemplo, una clase valarray optimizada para matrices numéricas y una clase complex para manejo y representación estandarizada de números complejos (en realidad una plantilla con especializaciones para los tipos float, double y long double.&lt;br /&gt;
&lt;br /&gt;
•	Utilidades. Parte de la STL dedicada a elementos auxiliares tales como adaptadores y la clase auto_ptr.&lt;br /&gt;
&lt;br /&gt;
•	Unas utilidades de entrada/salida de flujos, denominadas genéricamente iostreams.&lt;br /&gt;
&lt;br /&gt;
•	Una utilidad locale para manejo de localismos.&lt;br /&gt;
&lt;br /&gt;
•	Una clase string para manejo estandarizado de cadenas de caracteres.  En realidad es una instanciación (especialización) de la plantilla basic_string para cadenas de caracteres.&lt;br /&gt;
 &lt;br /&gt;
•	Un esquema para describir de modo uniforme el entorno de ejecución mediante la utilización de una clase estándar denominada numeric_limits y especialización para cada uno de los tipos de datos fundamentales.&lt;br /&gt;
&lt;br /&gt;
•	Utilidades para manejo de memoria.&lt;br /&gt;
&lt;br /&gt;
•	Soporte para utilización de juegos de caracteres y signos de diversos idiomas.&lt;br /&gt;
&lt;br /&gt;
•	Utilidades de diagnóstico y manejo de errores. Incluyen manejo de excepciones y la macro assert.&lt;br /&gt;
&lt;br /&gt;
== Funcionalidad ==&lt;br /&gt;
Si atendemos a su funcionalidad,  las utilidades ofrecidas por la Librería Estándar pueden agruparse en:&lt;br /&gt;
&lt;br /&gt;
•	Clasificación: Clasifican caracteres ASCII, como letras, caracteres de control (no imprimibles), Mayúsculas/minúsculas etc. Se definen en la cabecera &amp;lt;ctype.h&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
•	Entradas/Salidas de Consola: Estas son las denominadas entrada/salida estándar. Por defecto se refieren al teclado y a la pantalla (no pueden utilizarse directamente en aplicaciones de interfaz gráfica).&lt;br /&gt;
&lt;br /&gt;
•	Conversión: Convierten caracteres y cadenas de caracteres desde formato alfabético a numérico de diversos tipos (float, int, long).  También realizan la conversión inversa: de formatos numéricos a representaciones alfabéticas y de mayúsculas a minúsculas y viceversa.&lt;br /&gt;
&lt;br /&gt;
•	Diagnóstico: Son rutinas destinadas a comprobaciones; a descubrir y corregir posibles errores.&lt;br /&gt;
&lt;br /&gt;
•	Directorio: Rutinas para manejo de directorios y sus direcciones (path names).&lt;br /&gt;
&lt;br /&gt;
•	En linea (Inline): Rutinas para versiones inline de funciones. El compilador genera el código correspondiente para las versiones inline cuando se utiliza #pragma intrinsic o si se solicita optimización al compilador (optimización de tiempo de ejecución).&lt;br /&gt;
&lt;br /&gt;
•	Entrada/Salida. Son rutinas que proporcionan manejo de flujos y operaciones de Entrada/Salida a bajo nivel (de Sistema Operativo).&lt;br /&gt;
&lt;br /&gt;
•	Manipulación. Manejo de cadenas y bloques de memoria: copiar, comparar, convertir y buscar.&lt;br /&gt;
&lt;br /&gt;
•	Matemáticas: Para realizar cálculos matemáticos.&lt;br /&gt;
&lt;br /&gt;
•	De Memoria: Proporcionan asignación de memoria dinámica.&lt;br /&gt;
&lt;br /&gt;
•	Miscelánea. Se agrupan aquí rutinas varias, como las que posibilitan saltos (goto) no locales y las que manejan diferencias de tipo cultural o de lenguaje. Por ejemplo representación de números, de moneda, formatos de fecha y hora, clasificación de tipo alfabético.&lt;br /&gt;
&lt;br /&gt;
•	Control de proceso. Rutinas que permiten invocar y terminar nuevos procesos desde otra rutina.&lt;br /&gt;
&lt;br /&gt;
•	Fecha y hora. Incluyen rutinas para conversión y manipulación de variables de medida del tiempo (fecha y hora).&lt;br /&gt;
&lt;br /&gt;
•	Argumentos variables. Rutinas utilizadas cuando se usan listas variables de argumentos, como en los casos de printf(), vscanf().&lt;br /&gt;
== Utilización ==&lt;br /&gt;
La utilización de la Librería Estándar C++ requiere de dos tipos de condiciones que podríamos describir como formales y conceptuales.&lt;br /&gt;
&lt;br /&gt;
1. En cuanto a las primeras (condiciones formales) y habida cuenta que las utilidades aparecen en forma de funciones, resulta evidente que su utilización exige incluirlas en nuestro programa. Para ello se necesitan tres pasos (en realidad las exigencias son las mismas que con cualquier otra función, la diferencia estriba en la forma en que se realizan los pasos b y c):&lt;br /&gt;
&lt;br /&gt;
a:  Incluir en el código fuente las invocaciones a las [[Función_(programación)| funciones]] que estamos utilizando. Ejemplo:&lt;br /&gt;
printf(&amp;quot;Esto es una llamada a la función \&amp;quot;printf\&amp;quot; de librería\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
 b:  Incluir en el código fuente los prototipos de dichas funciones.&lt;br /&gt;
&lt;br /&gt;
Puesto que los prototipos ya están incluidos en los ficheros estándar de cabecera, hay que indicar al compilador que los incluya. Esto se realiza poniendo en nuestro fuente (normalmente al principio) una directiva de preprocesado #include que señala el fichero de cabecera que se debe añadir. Por ejemplo, si el manual indica que la función printf está definida en el fichero de cabecera stdio.h ponemos en nuestro código:&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  c:  Incluir en el fuente las definiciones de las funciones utilizadas. Como alternativa se puede indicar al compilador que tales definiciones están en ficheros compilados previamente.&lt;br /&gt;
&lt;br /&gt;
En este último caso se dice que las definiciones de las funciones están en librerías de las que existen dos tipos: estáticas (.LIB, .OBJ y .BPI) y dinámicas (.DLL). Toda la información que necesita el compilador está contenida en los ficheros de cabecera, por lo que las operaciones correspondientes son realizadas de forma automática; con la sola condición de que los ficheros y librerías correspondientes sean accesibles al enlazador.&lt;br /&gt;
&lt;br /&gt;
Las entidades de la Librería Estándar C++ (que no están en ficheros de cabecera .h), se han definido en un espacio de nombres denominado std, por lo que es preciso referirse a él específicamente cuando se quieran utilizar estos recursos.&lt;br /&gt;
&lt;br /&gt;
2. Respecto a las que hemos denominado &amp;quot;condiciones conceptuales&amp;quot;, damos por sentado que la utilización de algoritmos de la Librería exige conocerlos. Pero debemos advertir que existe una gran diferencia entre las rutinas de la que hemos denominado librería clásica y los recursos de la nueva Librería Estándar de Plantillas STL.&lt;br /&gt;
&lt;br /&gt;
En general los algoritmos contenidos en la librería clásica realizan tareas muy sencillas bajo la forma de funciones que, con un cierto número de argumentos, realizan la tarea encomendada. A veces devolviendo un objeto (que puede ser una estructura). Su utilización exige poco más que repasar esta colección de funciones (209 en la última versión del Estándar) hasta encontrar la que mejor se ajusta a nuestras necesidades. Para esto lo mejor es recurrir a la clasificación temática ofrecida en la documentación que acompaña a los compiladores antes que a la lista alfabética de las mismas. A continuación estudiamos atentamente su prototipo y la explicación de funcionamiento que acompaña el manual (eventualmente incluso con un ejemplo) y ya estamos listos para utilizarla. En el peor de los casos suelen bastar un par de pruebas hasta que conseguimos ajustar los argumentos de forma que se consiga el resultado esperado.&lt;br /&gt;
&lt;br /&gt;
Como última recomendación al respecto, sobre todo si pensamos que nuestro programa tendrá una larga vida y/o pensamos portarlo a otras plataformas, aconsejaría echar un vistazo a la sección de &amp;quot;compatibilidad&amp;quot; que acompaña a la descripción de cada función en la documentación de la mayoría de compiladores. Suele ocurrir que el compilador ofrezca muchas más funciones que las estrictamente Estándar C++, y que estas no estén claramente separadas del resto, de forma que es posible que elijamos una función que resuelve nuestro problema pero no es portable, en cuyo caso aconsejaría evitarlas dentro de lo posible.&lt;br /&gt;
&lt;br /&gt;
La utilización de la nueva Librería de Plantillas (STL) exige la asimilación de un nuevo paradigma;  una nueva forma de pensar que, si se tiene experiencia en programación tradicional, exige incluso un &amp;quot;cambio de chip&amp;quot;, ya que estas herramientas conforman un mundo enteramente nuevo y singular.&lt;br /&gt;
&lt;br /&gt;
La STL ofrece un conjunto de recursos flexible, potente y altamente optimizado para resolver una gran variedad de situaciones de programación. Pero esta versatilidad y potencia tributan un precio: su alto grado de parametrización supone algo más que utilizar herramientas aisladas. Es necesario saber ensamblar entre sí los recursos disponibles, que no trabajan aisladamente y que son básicamente de tres tipos: contenedores, iteradores y algoritmos. El resultado es que el proceso de utilizar la STL es algo más complicado que la simple búsqueda de una función que resuelva nuestras necesidades;  que la curva de aprendizaje es ciertamente más ardua que en el caso de la librería clásica, y  que los conceptos involucrados son más abstractos y requieren un conocimiento más extenso de sus fundamentos para utilizarlos. Desde luego, la descripción detallada de todos sus elementos exige un libro completo, y de hecho son muchos los que se han publicado con el objeto exclusivo de describir la STL y/o sus técnicas de uso. En compensación, las contrapartidas obtenidas justifican sin duda el esfuerzo. El programador puede concentrarse más en el problema que en los detalles de su implementación en el fuente, se incremente la productividad y se gana en claridad conceptual.&lt;br /&gt;
== Funciones y macros ==&lt;br /&gt;
Algunas [[Función_(programación)| funciones]] pueden venir implementadas de dos formas: como macro y como función. Por ejemplo, la función isalnum, contenida en &amp;lt;ctype.h&amp;gt;.  Esto significa que además de estar implementada como una función en la correspondiente librería (que se utiliza con los argumentos señalados en el manual), está definida como una macro de preprocesado en &amp;lt;ctype.h&amp;gt;, de forma que salvo indicación contraria al compilador, el preprocesador transforma la llamada del programador en otra serie de sentencias equivalentes que utilizan los mismos argumentos. El resultado es que en el código resultante, que luego pasa al compilador y al enlazador, no existe nada parecido a una llamada a una función isalnum (técnicamente el proceso es una sustitución inline de la función de librería.&lt;br /&gt;
&lt;br /&gt;
Para evitar que esto ocurra y por consiguiente que la llamada a islanum nunca llegue a producirse, basta con indefinir la correspondiente directiva. Esto se hace incluyendo al principio del código, y debajo de la línea #include &amp;lt;ctype.h&amp;gt;, una línea de preprocesado adecuada, en este caso:  #undef isalnum, con lo que el #define del preprocesador quedará sin efecto, con el resultado de que todas las invocaciones a isalnum de nuestro código serán respetadas por el preprocesador. Más tarde el enlazador cargará el código de isalnum (que extrae de la librería) con el resto de nuestro programa, y colocará en cada punto de nuestro código donde aparezca una invocación a isalnum, un salto a la dirección adecuada.&lt;br /&gt;
&lt;br /&gt;
En estos casos, el resultado es el mismo en ambas modalidades: como macro (por defecto) o como función de librería. La elección de una u otra es cuestión de optimización. Para tomar una decisión es necesario comprobar y valorar dos aspectos:&lt;br /&gt;
&lt;br /&gt;
•	El tamaño del ejecutable que resulta en uno y otro caso. Posiblemente mayor si se utiliza la función muchas veces y se adopta la macro.&lt;br /&gt;
&lt;br /&gt;
•	La velocidad de ejecución. Posiblemente mayor si se utiliza la función muchas veces (en bucles muy largos) y se utiliza la macro.&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[Ciencia de la Información]]&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http://www.zator.com/Cpp/E5.htm  Librería Estándar C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Librería Estándar en C.conclase.net]&lt;br /&gt;
* [https://uvadoc.uva.es/bitstream/10324/17502/1/PID_15_156_Anexo4.pdf  Elementos de la librería estándar C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Librer%C3%ADa_Est%C3%A1ndar_C%2B%2B&amp;diff=3232332</id>
		<title>Librería Estándar C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Librer%C3%ADa_Est%C3%A1ndar_C%2B%2B&amp;diff=3232332"/>
		<updated>2018-11-27T16:08:30Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Librería Estándar C++ |imagen=  |concepto= Una librería es un conjunto de recursos (algoritmos) prefabricados, que pueden ser utilizados por el programador para realizar determinadas operaciones }}''' Librería Estándar C++ '''. [[C++|C++]] no llega al nivel de simplicidad de su antecesor C, pero al igual que aquél, tampoco dispone de utilidades o funciones para entrada o salida implementadas en el propio lenguaje, de modo que estas y otras muchas, como manejo de cadenas de caracteres (strings), manejo de ficheros, funciones matemáticas Etc. son implementadas en forma de librerías externas.&lt;br /&gt;
== Sinopsis ==&lt;br /&gt;
Una librería es un conjunto de recursos (algoritmos) prefabricados, que pueden ser utilizados por el programador para realizar determinadas operaciones. Las declaraciones de las funciones (prototipos) utilizadas en estas librerías, junto con algunas macros y constantes predefinidas que facilitan su utilización, se agrupan en ficheros de nombres conocidos que suelen encontrarse en sitios predefinidos. Por ejemplo, en los sistemas UNIX, en  /usr/include. Estos ficheros se suelen llamar &amp;quot;de cabecera&amp;quot;, porque es tradición utilizar las primeras líneas del programa para poner las directivas #include que los incluirá en el fuente durante la fase de preprocesado.&lt;br /&gt;
== Clases de librerías ==&lt;br /&gt;
Los [[Compilador|compiladores]] [[C++|C++]] incluyen un amplio repertorio de clases, funciones y macros que permiten realizar una amplia variedad de tareas, incluyendo entradas/salidas de bajo y alto nivel; manipulación de cadenas alfanuméricas y ficheros; control de procesos (incluyendo multiproceso); manejo de memoria; cálculos matemáticos y un largo etcétera.&lt;br /&gt;
Este repertorio de recursos es denominado colectivamente como &amp;quot;Rutinas de librería&amp;quot;; &amp;quot;Librerías de ejecución&amp;quot; RTL (&amp;quot;Runtime Librarys&amp;quot;) o simplemente &amp;quot;Librerías&amp;quot;.   Puede decirse que el lenguaje aislado (tal cual) no tiene prácticamente ninguna utilidad sin la concurrencia de estas utilidades. El Estándar C++ las clasifica según su utilidad:&lt;br /&gt;
•	Soporte del lenguaje&lt;br /&gt;
•	Diagnóstico&lt;br /&gt;
•	Utilidades generales&lt;br /&gt;
•	Cadenas alfanuméricas (&amp;quot;Strings&amp;quot;)&lt;br /&gt;
•	Localización&lt;br /&gt;
•	Contenedores&lt;br /&gt;
•	Iteradores&lt;br /&gt;
•	Algoritmos&lt;br /&gt;
•	Cálculo numérico&lt;br /&gt;
•	Entrada/Salida&lt;br /&gt;
=== Librería Estándar C++ ===&lt;br /&gt;
Para poner un poco de orden, el Estándar C++ define la denominada Librería Estándar que debe acompañar a cada implementación del compilador que se adhiera al estándar. Es decir: la norma determina cuales son, como se llaman y como se utiliza este conjunto de algoritmos que deben acompañar (como mínimo) a cada implementación del compilador que quiera llamarse &amp;quot;Estándar&amp;quot;. La última versión, ISO/IEC 14882 del año 1998, especifica que se compone de 32 ficheros de cabecera de nombres fijos y conocidos agrupados según la funcionalidad de los algoritmos. Son los siguientes:&lt;br /&gt;
 &lt;br /&gt;
Ficheros	Funcionalidad/funciones&lt;br /&gt;
&lt;br /&gt;
&amp;lt;algorithm&amp;gt;	Parte de la STL que describe los algoritmos&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bitset&amp;gt;	Parte de la STL relativa a contenedores tipo bitset. Set de valores booleanos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;complex&amp;gt;	Parte de la librería numérica de la STL relativa a los complejos .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;deque&amp;gt;	Parte de la STL relativa a contenedores tipo deque;  un tipo de colas: &amp;quot;Double-ended-queue&amp;quot; .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;exception&amp;gt;	Parte de la librería de diagnóstico relativa al manejo de excepciones&lt;br /&gt;
&lt;br /&gt;
&amp;lt;fstream&amp;gt;	Flujos hacia/desde ficheros.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;functional&amp;gt;	Parte de la STL relativa a Objetos-función&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iomanip&amp;gt;	Manipuladores.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ios&amp;gt;	Supreclases para manejo de flujos de E/S.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iosfwd&amp;gt;	Contiene declaraciones adelantadas de todas las plantillas de flujos y sus typedefs estándar. Por ejemplo ostream.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iostream&amp;gt;	Parte del a STL que contiene los algoritmos estándar de E/S.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;istream&amp;gt;	Algoritmos estándar de flujos de entrada.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iterator&amp;gt;	Parte de la STL relacionada con iteradores, un tipo de puntero que permite utilizar los algoritmos de la Librería con las estructuras de datos representadas por los contenedores.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;limits&amp;gt;	Descripción de propiedades dependientes de la implementación que afectan a los tipos fundamentales.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;list&amp;gt;	Parte de la STL relativa a contenedores tipo list;  listas doblemente enlazadas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;locale&amp;gt;	Parte de la STL relativa a la internacionalización.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;map&amp;gt;	Parte de la STL relativa a contenedores tipo map.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;memory&amp;gt;	Utilidades relativas a la gestión de memoria, incluyendo asignadores  y punteros inteligentes (auto_ptr).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;new&amp;gt;	Manejo de memoria dinámica.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;numeric&amp;gt;	Parte de la librería numérica de la STL relativa a operaciones numéricas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ostream&amp;gt;	Algoritmos estándar para los flujos de salida.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;queue&amp;gt;	Parte de la STL relativa a contenedores tipo queue;  colas de objetos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;set&amp;gt;	Parte de la STL relativa a contenedores tipo set.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sstream&amp;gt;	Flujos hacia/desde cadenas alfanuméricas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;stack&amp;gt;	Parte de la STL relativa a contenedores tipo stack;  pilas de objetos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;stdexcept&amp;gt;	Parte de la STL relativa a las clases de las que derivan los objetos lanzados por las excepciones ocasionadas en los algoritmos de la propia STL y otras expresiones.  Estas clases son utilizadas para reportar errores detectados durante runtime.  Los usuarios también pueden utilizar excepciones para reportar errores en sus propios programas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;streambuf&amp;gt;	Parte de la STL relativa al Almacenamiento de flujos de E/S (&amp;quot;Stream buffers&amp;quot;).  Define los tipos que controlan la capa de transporte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;string&amp;gt;	Parte de la STL relativa a contenedores tipo string;  una generalización de las cadenas alfanuméricas para albergar cadenas de objetos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;typeinfo&amp;gt;	Mecanismo de identificación de tipos en tiempo de ejecución.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;utility&amp;gt;	Parte de la STL que contiene elementos auxiliares como [[Operadores|operadores]] y pares (pairs).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;valarray&amp;gt;	Parte de la librería numérica de la STL relativa a manejo de matrices numéricas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vector&amp;gt;	Parte de la STL relativa a los contenedores tipo vector; una generalización de las matrices unidimensionales C/C++.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Aunque generalmente las librerías no aportan ninguna característica al lenguaje (se supone que son utilidades auxiliares que no forman parte del lenguaje propiamente dicho), una pequeña porción de la Librería Estándar C++ sí aporta características que se consideran pertenecientes a este, de forma que deben estar presentes los ficheros de cabecera correspondientes si se desea usarlas. En concreto se refieren a los siguientes elementos:&lt;br /&gt;
&lt;br /&gt;
•	[[Operadores|operadores]] new, new[], delete y delete[].&lt;br /&gt;
&lt;br /&gt;
•	Clase type_info que corresponde al mecanismo RTTI de identificación de tipos en tiempo de ejecución representado por el operador typeid &lt;br /&gt;
&lt;br /&gt;
•	Rutinas de inicio y terminación.&lt;br /&gt;
&lt;br /&gt;
•	Las excepciones estándar lanzadas por los algoritmos anteriores&lt;br /&gt;
&lt;br /&gt;
=== Librería C ===&lt;br /&gt;
Además de otras nuevas, cuyo diseño e importancia cambian drásticamente la filosofía del lenguaje, C++ incluye prácticamente la totalidad de [[Función_(programación)| funciones]] de la primitiva librería estándar C. A esta librería, mantenida por compatibilidad, la denominamos Librería clásica.&lt;br /&gt;
=== Otras librerías ===&lt;br /&gt;
Además de las que proporciona el estándar y las complementarias que pueda incluir por su cuenta el fabricante del compilador, en los proyectos reales se suelen utilizar infinidad de otras librerías, comerciales o públicas, que facilitan el trabajo en áreas particulares, y en este sentido, recordar que uno de los pecados que el programador novel debe evitar, es la tendencia a querer reinventar constantemente la rueda. De forma que el consejo es utilizar en lo posible librerías que estén probadas y sean fácilmente accesibles. Aunque hay que tener cuidado, porque determinados proyectos exigen que las librerías utilizadas estén perfectamente documentadas y en ciertos casos, que se cuente con los fuentes correspondientes.&lt;br /&gt;
== Componentes ==&lt;br /&gt;
Al referirnos a las librerías C++ utilizamos la terminología siguiente:&lt;br /&gt;
&lt;br /&gt;
•	RTL  Conjunto de librerías que acompañan a un compilador (&amp;quot;Runtime Library&amp;quot;), sean o no estándar.&lt;br /&gt;
&lt;br /&gt;
•	Librería Estándar. Conjunto de librerías cuyo contenido está definido por el Estándar C++ (abreviadamente LE).&lt;br /&gt;
&lt;br /&gt;
•	Libería clásica. Parte de la Librería Estándar correspondiente al C clásico.&lt;br /&gt;
&lt;br /&gt;
•	STL (&amp;quot;Standard Templete Library&amp;quot;). Parte de la LE genuina de C++ (que no es heredada de C) y que responde a la forma &amp;quot;++&amp;quot; de hacer las cosas.&lt;br /&gt;
&lt;br /&gt;
La calidad de un compilador C++ viene determinada en gran medida por la calidad y cantidad de su RTL; por su grado de adherencia al Estándar  y por el grado de soporte que proporciona para la plataforma concreta a que se destina.&lt;br /&gt;
&lt;br /&gt;
En lo que concierne a la programación para MS Windows (las referencias a la plataforma Wintel surgen de forma constante e inevitable), los [[Compilador|compiladores]] Borland C++ y MS Visual C++ son quizás los más conocidos y utilizados.  El primero incluye una completa librería denominada VCL (Visual Component Library. La del segundo es conocida como MFC (Microsoft Foundation Classes).&lt;br /&gt;
&lt;br /&gt;
Linux dispone de su propio compilador: GNU Cpp, que comenzó siendo un compilador C y ha evolucionado a un producto que es en realidad un superconjunto de compiladores. No solo puede compilar código C y C++;  también otros lenguajes como Ada o Fortran;  de forma que es común referirse a ellos como GCC (&amp;quot;GNU Compiler Collection&amp;quot;).  La buena noticia es que existen versiones de este compilador para plataformas Windows, de forma que incluso en este ambiente &amp;quot;Propietario&amp;quot; pueden realizarse desarrollos utilizando herramientas &amp;quot;Open source&amp;quot; &lt;br /&gt;
A grandes rasgos la librería Estándar C++ comprende los siguientes módulos:&lt;br /&gt;
&lt;br /&gt;
•	La denominada Librería Estándar de Plantillas, abreviadamente STL (&amp;quot;Standard Templete Library&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
•	Librería numérica. Parte de la STL que contiene algoritmos especialmente concebidos para computación numérica. Por ejemplo, una clase valarray optimizada para matrices numéricas y una clase complex para manejo y representación estandarizada de números complejos (en realidad una plantilla con especializaciones para los tipos float, double y long double.&lt;br /&gt;
&lt;br /&gt;
•	Utilidades. Parte de la STL dedicada a elementos auxiliares tales como adaptadores y la clase auto_ptr.&lt;br /&gt;
&lt;br /&gt;
•	Unas utilidades de entrada/salida de flujos, denominadas genéricamente iostreams.&lt;br /&gt;
&lt;br /&gt;
•	Una utilidad locale para manejo de localismos.&lt;br /&gt;
&lt;br /&gt;
•	Una clase string para manejo estandarizado de cadenas de caracteres.  En realidad es una instanciación (especialización) de la plantilla basic_string para cadenas de caracteres.&lt;br /&gt;
 &lt;br /&gt;
•	Un esquema para describir de modo uniforme el entorno de ejecución mediante la utilización de una clase estándar denominada numeric_limits y especialización para cada uno de los tipos de datos fundamentales.&lt;br /&gt;
&lt;br /&gt;
•	Utilidades para manejo de memoria.&lt;br /&gt;
&lt;br /&gt;
•	Soporte para utilización de juegos de caracteres y signos de diversos idiomas.&lt;br /&gt;
&lt;br /&gt;
•	Utilidades de diagnóstico y manejo de errores. Incluyen manejo de excepciones y la macro assert.&lt;br /&gt;
&lt;br /&gt;
== Funcionalidad ==&lt;br /&gt;
Si atendemos a su funcionalidad,  las utilidades ofrecidas por la Librería Estándar pueden agruparse en:&lt;br /&gt;
&lt;br /&gt;
•	Clasificación: Clasifican caracteres ASCII, como letras, caracteres de control (no imprimibles), Mayúsculas/minúsculas etc. Se definen en la cabecera &amp;lt;ctype.h&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
•	Entradas/Salidas de Consola: Estas son las denominadas entrada/salida estándar. Por defecto se refieren al teclado y a la pantalla (no pueden utilizarse directamente en aplicaciones de interfaz gráfica).&lt;br /&gt;
&lt;br /&gt;
•	Conversión: Convierten caracteres y cadenas de caracteres desde formato alfabético a numérico de diversos tipos (float, int, long).  También realizan la conversión inversa: de formatos numéricos a representaciones alfabéticas y de mayúsculas a minúsculas y viceversa.&lt;br /&gt;
&lt;br /&gt;
•	Diagnóstico: Son rutinas destinadas a comprobaciones; a descubrir y corregir posibles errores.&lt;br /&gt;
&lt;br /&gt;
•	Directorio: Rutinas para manejo de directorios y sus direcciones (path names).&lt;br /&gt;
&lt;br /&gt;
•	En linea (Inline): Rutinas para versiones inline de funciones. El compilador genera el código correspondiente para las versiones inline cuando se utiliza #pragma intrinsic o si se solicita optimización al compilador (optimización de tiempo de ejecución).&lt;br /&gt;
&lt;br /&gt;
•	Entrada/Salida. Son rutinas que proporcionan manejo de flujos y operaciones de Entrada/Salida a bajo nivel (de Sistema Operativo).&lt;br /&gt;
&lt;br /&gt;
•	Manipulación. Manejo de cadenas y bloques de memoria: copiar, comparar, convertir y buscar.&lt;br /&gt;
&lt;br /&gt;
•	Matemáticas: Para realizar cálculos matemáticos.&lt;br /&gt;
&lt;br /&gt;
•	De Memoria: Proporcionan asignación de memoria dinámica.&lt;br /&gt;
&lt;br /&gt;
•	Miscelánea. Se agrupan aquí rutinas varias, como las que posibilitan saltos (goto) no locales y las que manejan diferencias de tipo cultural o de lenguaje. Por ejemplo representación de números, de moneda, formatos de fecha y hora, clasificación de tipo alfabético.&lt;br /&gt;
&lt;br /&gt;
•	Control de proceso. Rutinas que permiten invocar y terminar nuevos procesos desde otra rutina.&lt;br /&gt;
&lt;br /&gt;
•	Fecha y hora. Incluyen rutinas para conversión y manipulación de variables de medida del tiempo (fecha y hora).&lt;br /&gt;
&lt;br /&gt;
•	Argumentos variables. Rutinas utilizadas cuando se usan listas variables de argumentos, como en los casos de printf(), vscanf().&lt;br /&gt;
== Utilización ==&lt;br /&gt;
La utilización de la Librería Estándar C++ requiere de dos tipos de condiciones que podríamos describir como formales y conceptuales.&lt;br /&gt;
&lt;br /&gt;
1. En cuanto a las primeras (condiciones formales) y habida cuenta que las utilidades aparecen en forma de funciones, resulta evidente que su utilización exige incluirlas en nuestro programa. Para ello se necesitan tres pasos (en realidad las exigencias son las mismas que con cualquier otra función, la diferencia estriba en la forma en que se realizan los pasos b y c):&lt;br /&gt;
&lt;br /&gt;
a:  Incluir en el código fuente las invocaciones a las [[Función_(programación)| funciones]] que estamos utilizando. Ejemplo:&lt;br /&gt;
printf(&amp;quot;Esto es una llamada a la función \&amp;quot;printf\&amp;quot; de librería\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
 b:  Incluir en el código fuente los prototipos de dichas funciones.&lt;br /&gt;
&lt;br /&gt;
Puesto que los prototipos ya están incluidos en los ficheros estándar de cabecera, hay que indicar al compilador que los incluya. Esto se realiza poniendo en nuestro fuente (normalmente al principio) una directiva de preprocesado #include que señala el fichero de cabecera que se debe añadir. Por ejemplo, si el manual indica que la función printf está definida en el fichero de cabecera stdio.h ponemos en nuestro código:&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  c:  Incluir en el fuente las definiciones de las funciones utilizadas. Como alternativa se puede indicar al compilador que tales definiciones están en ficheros compilados previamente.&lt;br /&gt;
&lt;br /&gt;
En este último caso se dice que las definiciones de las funciones están en librerías de las que existen dos tipos: estáticas (.LIB, .OBJ y .BPI) y dinámicas (.DLL). Toda la información que necesita el compilador está contenida en los ficheros de cabecera, por lo que las operaciones correspondientes son realizadas de forma automática; con la sola condición de que los ficheros y librerías correspondientes sean accesibles al enlazador.&lt;br /&gt;
&lt;br /&gt;
Las entidades de la Librería Estándar C++ (que no están en ficheros de cabecera .h), se han definido en un espacio de nombres denominado std, por lo que es preciso referirse a él específicamente cuando se quieran utilizar estos recursos.&lt;br /&gt;
&lt;br /&gt;
2. Respecto a las que hemos denominado &amp;quot;condiciones conceptuales&amp;quot;, damos por sentado que la utilización de algoritmos de la Librería exige conocerlos. Pero debemos advertir que existe una gran diferencia entre las rutinas de la que hemos denominado librería clásica y los recursos de la nueva Librería Estándar de Plantillas STL.&lt;br /&gt;
&lt;br /&gt;
En general los algoritmos contenidos en la librería clásica realizan tareas muy sencillas bajo la forma de funciones que, con un cierto número de argumentos, realizan la tarea encomendada. A veces devolviendo un objeto (que puede ser una estructura). Su utilización exige poco más que repasar esta colección de funciones (209 en la última versión del Estándar) hasta encontrar la que mejor se ajusta a nuestras necesidades. Para esto lo mejor es recurrir a la clasificación temática ofrecida en la documentación que acompaña a los compiladores antes que a la lista alfabética de las mismas. A continuación estudiamos atentamente su prototipo y la explicación de funcionamiento que acompaña el manual (eventualmente incluso con un ejemplo) y ya estamos listos para utilizarla. En el peor de los casos suelen bastar un par de pruebas hasta que conseguimos ajustar los argumentos de forma que se consiga el resultado esperado.&lt;br /&gt;
&lt;br /&gt;
Como última recomendación al respecto, sobre todo si pensamos que nuestro programa tendrá una larga vida y/o pensamos portarlo a otras plataformas, aconsejaría echar un vistazo a la sección de &amp;quot;compatibilidad&amp;quot; que acompaña a la descripción de cada función en la documentación de la mayoría de compiladores. Suele ocurrir que el compilador ofrezca muchas más funciones que las estrictamente Estándar C++, y que estas no estén claramente separadas del resto, de forma que es posible que elijamos una función que resuelve nuestro problema pero no es portable, en cuyo caso aconsejaría evitarlas dentro de lo posible.&lt;br /&gt;
&lt;br /&gt;
La utilización de la nueva Librería de Plantillas (STL) exige la asimilación de un nuevo paradigma;  una nueva forma de pensar que, si se tiene experiencia en programación tradicional, exige incluso un &amp;quot;cambio de chip&amp;quot;, ya que estas herramientas conforman un mundo enteramente nuevo y singular.&lt;br /&gt;
&lt;br /&gt;
La STL ofrece un conjunto de recursos flexible, potente y altamente optimizado para resolver una gran variedad de situaciones de programación. Pero esta versatilidad y potencia tributan un precio: su alto grado de parametrización supone algo más que utilizar herramientas aisladas. Es necesario saber ensamblar entre sí los recursos disponibles, que no trabajan aisladamente y que son básicamente de tres tipos: contenedores, iteradores y algoritmos. El resultado es que el proceso de utilizar la STL es algo más complicado que la simple búsqueda de una función que resuelva nuestras necesidades;  que la curva de aprendizaje es ciertamente más ardua que en el caso de la librería clásica, y  que los conceptos involucrados son más abstractos y requieren un conocimiento más extenso de sus fundamentos para utilizarlos. Desde luego, la descripción detallada de todos sus elementos exige un libro completo, y de hecho son muchos los que se han publicado con el objeto exclusivo de describir la STL y/o sus técnicas de uso. En compensación, las contrapartidas obtenidas justifican sin duda el esfuerzo. El programador puede concentrarse más en el problema que en los detalles de su implementación en el fuente, se incremente la productividad y se gana en claridad conceptual.&lt;br /&gt;
== Funciones y macros ==&lt;br /&gt;
Algunas [[Función_(programación)| funciones]] pueden venir implementadas de dos formas: como macro y como función. Por ejemplo, la función isalnum, contenida en &amp;lt;ctype.h&amp;gt;.  Esto significa que además de estar implementada como una función en la correspondiente librería (que se utiliza con los argumentos señalados en el manual), está definida como una macro de preprocesado en &amp;lt;ctype.h&amp;gt;, de forma que salvo indicación contraria al compilador, el preprocesador transforma la llamada del programador en otra serie de sentencias equivalentes que utilizan los mismos argumentos. El resultado es que en el código resultante, que luego pasa al compilador y al enlazador, no existe nada parecido a una llamada a una función isalnum (técnicamente el proceso es una sustitución inline de la función de librería.&lt;br /&gt;
&lt;br /&gt;
Para evitar que esto ocurra y por consiguiente que la llamada a islanum nunca llegue a producirse, basta con indefinir la correspondiente directiva. Esto se hace incluyendo al principio del código, y debajo de la línea #include &amp;lt;ctype.h&amp;gt;, una línea de preprocesado adecuada, en este caso:  #undef isalnum, con lo que el #define del preprocesador quedará sin efecto, con el resultado de que todas las invocaciones a isalnum de nuestro código serán respetadas por el preprocesador. Más tarde el enlazador cargará el código de isalnum (que extrae de la librería) con el resto de nuestro programa, y colocará en cada punto de nuestro código donde aparezca una invocación a isalnum, un salto a la dirección adecuada.&lt;br /&gt;
&lt;br /&gt;
En estos casos, el resultado es el mismo en ambas modalidades: como macro (por defecto) o como función de librería. La elección de una u otra es cuestión de optimización. Para tomar una decisión es necesario comprobar y valorar dos aspectos:&lt;br /&gt;
&lt;br /&gt;
•	El tamaño del ejecutable que resulta en uno y otro caso. Posiblemente mayor si se utiliza la función muchas veces y se adopta la macro.&lt;br /&gt;
&lt;br /&gt;
•	La velocidad de ejecución. Posiblemente mayor si se utiliza la función muchas veces (en bucles muy largos) y se utiliza la macro.&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[Ciencia de la Información]]&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Librería Estándar C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http://www.zator.com/Cpp/E5.htm  Librería Estándar C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Librería Estándar en C.conclase.net]&lt;br /&gt;
* [https://uvadoc.uva.es/bitstream/10324/17502/1/PID_15_156_Anexo4.pdf  Elementos de la librería estándar C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Librer%C3%ADa_Est%C3%A1ndar_C%2B%2B&amp;diff=3232328</id>
		<title>Librería Estándar C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Librer%C3%ADa_Est%C3%A1ndar_C%2B%2B&amp;diff=3232328"/>
		<updated>2018-11-27T16:06:05Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Librería Estándar C++ |imagen=  |concepto= Una librería es un conjunto de recursos (algoritmos) prefabricados, que pueden ser utilizados por el programador para realizar determinadas operaciones }}''' Librería Estándar C++ '''. [[C++|C++]] no llega al nivel de simplicidad de su antecesor C, pero al igual que aquél, tampoco dispone de utilidades o funciones para entrada o salida implementadas en el propio lenguaje, de modo que estas y otras muchas, como manejo de cadenas de caracteres (strings), manejo de ficheros, funciones matemáticas Etc. son implementadas en forma de librerías externas.&lt;br /&gt;
== Sinopsis ==&lt;br /&gt;
Una librería es un conjunto de recursos (algoritmos) prefabricados, que pueden ser utilizados por el programador para realizar determinadas operaciones. Las declaraciones de las funciones (prototipos) utilizadas en estas librerías, junto con algunas macros y constantes predefinidas que facilitan su utilización, se agrupan en ficheros de nombres conocidos que suelen encontrarse en sitios predefinidos. Por ejemplo, en los sistemas UNIX, en  /usr/include. Estos ficheros se suelen llamar &amp;quot;de cabecera&amp;quot;, porque es tradición utilizar las primeras líneas del programa para poner las directivas #include que los incluirá en el fuente durante la fase de preprocesado.&lt;br /&gt;
== Clases de librerías ==&lt;br /&gt;
Los [[Compilador|compiladores]] [[C++|C++]] incluyen un amplio repertorio de clases, funciones y macros que permiten realizar una amplia variedad de tareas, incluyendo entradas/salidas de bajo y alto nivel; manipulación de cadenas alfanuméricas y ficheros; control de procesos (incluyendo multiproceso); manejo de memoria; cálculos matemáticos y un largo etcétera.&lt;br /&gt;
Este repertorio de recursos es denominado colectivamente como &amp;quot;Rutinas de librería&amp;quot;; &amp;quot;Librerías de ejecución&amp;quot; RTL (&amp;quot;Runtime Librarys&amp;quot;) o simplemente &amp;quot;Librerías&amp;quot;.   Puede decirse que el lenguaje aislado (tal cual) no tiene prácticamente ninguna utilidad sin la concurrencia de estas utilidades. El Estándar C++ las clasifica según su utilidad:&lt;br /&gt;
•	Soporte del lenguaje&lt;br /&gt;
•	Diagnóstico&lt;br /&gt;
•	Utilidades generales&lt;br /&gt;
•	Cadenas alfanuméricas (&amp;quot;Strings&amp;quot;)&lt;br /&gt;
•	Localización&lt;br /&gt;
•	Contenedores&lt;br /&gt;
•	Iteradores&lt;br /&gt;
•	Algoritmos&lt;br /&gt;
•	Cálculo numérico&lt;br /&gt;
•	Entrada/Salida&lt;br /&gt;
=== Librería Estándar C++ ===&lt;br /&gt;
Para poner un poco de orden, el Estándar C++ define la denominada Librería Estándar que debe acompañar a cada implementación del compilador que se adhiera al estándar. Es decir: la norma determina cuales son, como se llaman y como se utiliza este conjunto de algoritmos que deben acompañar (como mínimo) a cada implementación del compilador que quiera llamarse &amp;quot;Estándar&amp;quot;. La última versión, ISO/IEC 14882 del año 1998, especifica que se compone de 32 ficheros de cabecera de nombres fijos y conocidos agrupados según la funcionalidad de los algoritmos. Son los siguientes:&lt;br /&gt;
 &lt;br /&gt;
Ficheros	Funcionalidad/funciones&lt;br /&gt;
&lt;br /&gt;
&amp;lt;algorithm&amp;gt;	Parte de la STL que describe los algoritmos&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bitset&amp;gt;	Parte de la STL relativa a contenedores tipo bitset. Set de valores booleanos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;complex&amp;gt;	Parte de la librería numérica de la STL relativa a los complejos .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;deque&amp;gt;	Parte de la STL relativa a contenedores tipo deque;  un tipo de colas: &amp;quot;Double-ended-queue&amp;quot; .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;exception&amp;gt;	Parte de la librería de diagnóstico relativa al manejo de excepciones&lt;br /&gt;
&lt;br /&gt;
&amp;lt;fstream&amp;gt;	Flujos hacia/desde ficheros.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;functional&amp;gt;	Parte de la STL relativa a Objetos-función&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iomanip&amp;gt;	Manipuladores.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ios&amp;gt;	Supreclases para manejo de flujos de E/S.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iosfwd&amp;gt;	Contiene declaraciones adelantadas de todas las plantillas de flujos y sus typedefs estándar. Por ejemplo ostream.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iostream&amp;gt;	Parte del a STL que contiene los algoritmos estándar de E/S.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;istream&amp;gt;	Algoritmos estándar de flujos de entrada.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iterator&amp;gt;	Parte de la STL relacionada con iteradores, un tipo de puntero que permite utilizar los algoritmos de la Librería con las estructuras de datos representadas por los contenedores.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;limits&amp;gt;	Descripción de propiedades dependientes de la implementación que afectan a los tipos fundamentales.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;list&amp;gt;	Parte de la STL relativa a contenedores tipo list;  listas doblemente enlazadas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;locale&amp;gt;	Parte de la STL relativa a la internacionalización.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;map&amp;gt;	Parte de la STL relativa a contenedores tipo map.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;memory&amp;gt;	Utilidades relativas a la gestión de memoria, incluyendo asignadores  y punteros inteligentes (auto_ptr).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;new&amp;gt;	Manejo de memoria dinámica.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;numeric&amp;gt;	Parte de la librería numérica de la STL relativa a operaciones numéricas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ostream&amp;gt;	Algoritmos estándar para los flujos de salida.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;queue&amp;gt;	Parte de la STL relativa a contenedores tipo queue;  colas de objetos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;set&amp;gt;	Parte de la STL relativa a contenedores tipo set.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sstream&amp;gt;	Flujos hacia/desde cadenas alfanuméricas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;stack&amp;gt;	Parte de la STL relativa a contenedores tipo stack;  pilas de objetos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;stdexcept&amp;gt;	Parte de la STL relativa a las clases de las que derivan los objetos lanzados por las excepciones ocasionadas en los algoritmos de la propia STL y otras expresiones.  Estas clases son utilizadas para reportar errores detectados durante runtime.  Los usuarios también pueden utilizar excepciones para reportar errores en sus propios programas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;streambuf&amp;gt;	Parte de la STL relativa al Almacenamiento de flujos de E/S (&amp;quot;Stream buffers&amp;quot;).  Define los tipos que controlan la capa de transporte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;string&amp;gt;	Parte de la STL relativa a contenedores tipo string;  una generalización de las cadenas alfanuméricas para albergar cadenas de objetos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;typeinfo&amp;gt;	Mecanismo de identificación de tipos en tiempo de ejecución.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;utility&amp;gt;	Parte de la STL que contiene elementos auxiliares como [[Operadores|operadores]] y pares (pairs).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;valarray&amp;gt;	Parte de la librería numérica de la STL relativa a manejo de matrices numéricas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vector&amp;gt;	Parte de la STL relativa a los contenedores tipo vector; una generalización de las matrices unidimensionales C/C++.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Aunque generalmente las librerías no aportan ninguna característica al lenguaje (se supone que son utilidades auxiliares que no forman parte del lenguaje propiamente dicho), una pequeña porción de la Librería Estándar C++ sí aporta características que se consideran pertenecientes a este, de forma que deben estar presentes los ficheros de cabecera correspondientes si se desea usarlas. En concreto se refieren a los siguientes elementos:&lt;br /&gt;
&lt;br /&gt;
•	[[Operadores|operadores]] new, new[], delete y delete[].&lt;br /&gt;
&lt;br /&gt;
•	Clase type_info que corresponde al mecanismo RTTI de identificación de tipos en tiempo de ejecución representado por el operador typeid &lt;br /&gt;
&lt;br /&gt;
•	Rutinas de inicio y terminación.&lt;br /&gt;
&lt;br /&gt;
•	Las excepciones estándar lanzadas por los algoritmos anteriores&lt;br /&gt;
&lt;br /&gt;
=== Librería C ===&lt;br /&gt;
Además de otras nuevas, cuyo diseño e importancia cambian drásticamente la filosofía del lenguaje, C++ incluye prácticamente la totalidad de [[Función_(programación)| funciones]] de la primitiva librería estándar C. A esta librería, mantenida por compatibilidad, la denominamos Librería clásica.&lt;br /&gt;
=== Otras librerías ===&lt;br /&gt;
Además de las que proporciona el estándar y las complementarias que pueda incluir por su cuenta el fabricante del compilador, en los proyectos reales se suelen utilizar infinidad de otras librerías, comerciales o públicas, que facilitan el trabajo en áreas particulares, y en este sentido, recordar que uno de los pecados que el programador novel debe evitar, es la tendencia a querer reinventar constantemente la rueda. De forma que el consejo es utilizar en lo posible librerías que estén probadas y sean fácilmente accesibles. Aunque hay que tener cuidado, porque determinados proyectos exigen que las librerías utilizadas estén perfectamente documentadas y en ciertos casos, que se cuente con los fuentes correspondientes.&lt;br /&gt;
== Componentes ==&lt;br /&gt;
Al referirnos a las librerías C++ utilizamos la terminología siguiente:&lt;br /&gt;
&lt;br /&gt;
•	RTL  Conjunto de librerías que acompañan a un compilador (&amp;quot;Runtime Library&amp;quot;), sean o no estándar.&lt;br /&gt;
&lt;br /&gt;
•	Librería Estándar. Conjunto de librerías cuyo contenido está definido por el Estándar C++ (abreviadamente LE).&lt;br /&gt;
&lt;br /&gt;
•	Libería clásica. Parte de la Librería Estándar correspondiente al C clásico.&lt;br /&gt;
&lt;br /&gt;
•	STL (&amp;quot;Standard Templete Library&amp;quot;). Parte de la LE genuina de C++ (que no es heredada de C) y que responde a la forma &amp;quot;++&amp;quot; de hacer las cosas.&lt;br /&gt;
&lt;br /&gt;
La calidad de un compilador C++ viene determinada en gran medida por la calidad y cantidad de su RTL; por su grado de adherencia al Estándar  y por el grado de soporte que proporciona para la plataforma concreta a que se destina.&lt;br /&gt;
&lt;br /&gt;
En lo que concierne a la programación para MS Windows (las referencias a la plataforma Wintel surgen de forma constante e inevitable), los [[Compilador|compiladores]] Borland C++ y MS Visual C++ son quizás los más conocidos y utilizados.  El primero incluye una completa librería denominada VCL (Visual Component Library. La del segundo es conocida como MFC (Microsoft Foundation Classes).&lt;br /&gt;
&lt;br /&gt;
Linux dispone de su propio compilador: GNU Cpp, que comenzó siendo un compilador C y ha evolucionado a un producto que es en realidad un superconjunto de compiladores. No solo puede compilar código C y C++;  también otros lenguajes como Ada o Fortran;  de forma que es común referirse a ellos como GCC (&amp;quot;GNU Compiler Collection&amp;quot;).  La buena noticia es que existen versiones de este compilador para plataformas Windows, de forma que incluso en este ambiente &amp;quot;Propietario&amp;quot; pueden realizarse desarrollos utilizando herramientas &amp;quot;Open source&amp;quot; &lt;br /&gt;
A grandes rasgos la librería Estándar C++ comprende los siguientes módulos:&lt;br /&gt;
&lt;br /&gt;
•	La denominada Librería Estándar de Plantillas, abreviadamente STL (&amp;quot;Standard Templete Library&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
•	Librería numérica. Parte de la STL que contiene algoritmos especialmente concebidos para computación numérica. Por ejemplo, una clase valarray optimizada para matrices numéricas y una clase complex para manejo y representación estandarizada de números complejos (en realidad una plantilla con especializaciones para los tipos float, double y long double.&lt;br /&gt;
&lt;br /&gt;
•	Utilidades. Parte de la STL dedicada a elementos auxiliares tales como adaptadores y la clase auto_ptr.&lt;br /&gt;
&lt;br /&gt;
•	Unas utilidades de entrada/salida de flujos, denominadas genéricamente iostreams.&lt;br /&gt;
&lt;br /&gt;
•	Una utilidad locale para manejo de localismos.&lt;br /&gt;
&lt;br /&gt;
•	Una clase string para manejo estandarizado de cadenas de caracteres.  En realidad es una instanciación (especialización) de la plantilla basic_string para cadenas de caracteres.&lt;br /&gt;
 &lt;br /&gt;
•	Un esquema para describir de modo uniforme el entorno de ejecución mediante la utilización de una clase estándar denominada numeric_limits y especialización para cada uno de los tipos de datos fundamentales.&lt;br /&gt;
&lt;br /&gt;
•	Utilidades para manejo de memoria.&lt;br /&gt;
&lt;br /&gt;
•	Soporte para utilización de juegos de caracteres y signos de diversos idiomas.&lt;br /&gt;
&lt;br /&gt;
•	Utilidades de diagnóstico y manejo de errores. Incluyen manejo de excepciones y la macro assert.&lt;br /&gt;
&lt;br /&gt;
== Funcionalidad ==&lt;br /&gt;
Si atendemos a su funcionalidad,  las utilidades ofrecidas por la Librería Estándar pueden agruparse en:&lt;br /&gt;
&lt;br /&gt;
•	Clasificación: Clasifican caracteres ASCII, como letras, caracteres de control (no imprimibles), Mayúsculas/minúsculas etc. Se definen en la cabecera &amp;lt;ctype.h&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
•	Entradas/Salidas de Consola: Estas son las denominadas entrada/salida estándar. Por defecto se refieren al teclado y a la pantalla (no pueden utilizarse directamente en aplicaciones de interfaz gráfica).&lt;br /&gt;
&lt;br /&gt;
•	Conversión: Convierten caracteres y cadenas de caracteres desde formato alfabético a numérico de diversos tipos (float, int, long).  También realizan la conversión inversa: de formatos numéricos a representaciones alfabéticas y de mayúsculas a minúsculas y viceversa.&lt;br /&gt;
&lt;br /&gt;
•	Diagnóstico: Son rutinas destinadas a comprobaciones; a descubrir y corregir posibles errores.&lt;br /&gt;
&lt;br /&gt;
•	Directorio: Rutinas para manejo de directorios y sus direcciones (path names).&lt;br /&gt;
&lt;br /&gt;
•	En linea (Inline): Rutinas para versiones inline de funciones. El compilador genera el código correspondiente para las versiones inline cuando se utiliza #pragma intrinsic o si se solicita optimización al compilador (optimización de tiempo de ejecución).&lt;br /&gt;
&lt;br /&gt;
•	Entrada/Salida. Son rutinas que proporcionan manejo de flujos y operaciones de Entrada/Salida a bajo nivel (de Sistema Operativo).&lt;br /&gt;
&lt;br /&gt;
•	Manipulación. Manejo de cadenas y bloques de memoria: copiar, comparar, convertir y buscar.&lt;br /&gt;
&lt;br /&gt;
•	Matemáticas: Para realizar cálculos matemáticos.&lt;br /&gt;
&lt;br /&gt;
•	De Memoria: Proporcionan asignación de memoria dinámica.&lt;br /&gt;
&lt;br /&gt;
•	Miscelánea. Se agrupan aquí rutinas varias, como las que posibilitan saltos (goto) no locales y las que manejan diferencias de tipo cultural o de lenguaje. Por ejemplo representación de números, de moneda, formatos de fecha y hora, clasificación de tipo alfabético.&lt;br /&gt;
&lt;br /&gt;
•	Control de proceso. Rutinas que permiten invocar y terminar nuevos procesos desde otra rutina.&lt;br /&gt;
&lt;br /&gt;
•	Fecha y hora. Incluyen rutinas para conversión y manipulación de variables de medida del tiempo (fecha y hora).&lt;br /&gt;
&lt;br /&gt;
•	Argumentos variables. Rutinas utilizadas cuando se usan listas variables de argumentos, como en los casos de printf(), vscanf().&lt;br /&gt;
== Utilización ==&lt;br /&gt;
La utilización de la Librería Estándar C++ requiere de dos tipos de condiciones que podríamos describir como formales y conceptuales.&lt;br /&gt;
&lt;br /&gt;
1. En cuanto a las primeras (condiciones formales) y habida cuenta que las utilidades aparecen en forma de funciones, resulta evidente que su utilización exige incluirlas en nuestro programa. Para ello se necesitan tres pasos (en realidad las exigencias son las mismas que con cualquier otra función, la diferencia estriba en la forma en que se realizan los pasos b y c):&lt;br /&gt;
&lt;br /&gt;
a:  Incluir en el código fuente las invocaciones a las [[Función_(programación)| funciones]] que estamos utilizando. Ejemplo:&lt;br /&gt;
printf(&amp;quot;Esto es una llamada a la función \&amp;quot;printf\&amp;quot; de librería\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
 b:  Incluir en el código fuente los prototipos de dichas funciones.&lt;br /&gt;
&lt;br /&gt;
Puesto que los prototipos ya están incluidos en los ficheros estándar de cabecera, hay que indicar al compilador que los incluya. Esto se realiza poniendo en nuestro fuente (normalmente al principio) una directiva de preprocesado #include que señala el fichero de cabecera que se debe añadir. Por ejemplo, si el manual indica que la función printf está definida en el fichero de cabecera stdio.h ponemos en nuestro código:&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  c:  Incluir en el fuente las definiciones de las funciones utilizadas. Como alternativa se puede indicar al compilador que tales definiciones están en ficheros compilados previamente.&lt;br /&gt;
&lt;br /&gt;
En este último caso se dice que las definiciones de las funciones están en librerías de las que existen dos tipos: estáticas (.LIB, .OBJ y .BPI) y dinámicas (.DLL). Toda la información que necesita el compilador está contenida en los ficheros de cabecera, por lo que las operaciones correspondientes son realizadas de forma automática; con la sola condición de que los ficheros y librerías correspondientes sean accesibles al enlazador.&lt;br /&gt;
&lt;br /&gt;
Las entidades de la Librería Estándar C++ (que no están en ficheros de cabecera .h), se han definido en un espacio de nombres denominado std, por lo que es preciso referirse a él específicamente cuando se quieran utilizar estos recursos.&lt;br /&gt;
&lt;br /&gt;
2. Respecto a las que hemos denominado &amp;quot;condiciones conceptuales&amp;quot;, damos por sentado que la utilización de algoritmos de la Librería exige conocerlos. Pero debemos advertir que existe una gran diferencia entre las rutinas de la que hemos denominado librería clásica y los recursos de la nueva Librería Estándar de Plantillas STL.&lt;br /&gt;
&lt;br /&gt;
En general los algoritmos contenidos en la librería clásica realizan tareas muy sencillas bajo la forma de funciones que, con un cierto número de argumentos, realizan la tarea encomendada. A veces devolviendo un objeto (que puede ser una estructura). Su utilización exige poco más que repasar esta colección de funciones (209 en la última versión del Estándar) hasta encontrar la que mejor se ajusta a nuestras necesidades. Para esto lo mejor es recurrir a la clasificación temática ofrecida en la documentación que acompaña a los compiladores antes que a la lista alfabética de las mismas. A continuación estudiamos atentamente su prototipo y la explicación de funcionamiento que acompaña el manual (eventualmente incluso con un ejemplo) y ya estamos listos para utilizarla. En el peor de los casos suelen bastar un par de pruebas hasta que conseguimos ajustar los argumentos de forma que se consiga el resultado esperado.&lt;br /&gt;
&lt;br /&gt;
Como última recomendación al respecto, sobre todo si pensamos que nuestro programa tendrá una larga vida y/o pensamos portarlo a otras plataformas, aconsejaría echar un vistazo a la sección de &amp;quot;compatibilidad&amp;quot; que acompaña a la descripción de cada función en la documentación de la mayoría de compiladores. Suele ocurrir que el compilador ofrezca muchas más funciones que las estrictamente Estándar C++, y que estas no estén claramente separadas del resto, de forma que es posible que elijamos una función que resuelve nuestro problema pero no es portable, en cuyo caso aconsejaría evitarlas dentro de lo posible.&lt;br /&gt;
&lt;br /&gt;
La utilización de la nueva Librería de Plantillas (STL) exige la asimilación de un nuevo paradigma;  una nueva forma de pensar que, si se tiene experiencia en programación tradicional, exige incluso un &amp;quot;cambio de chip&amp;quot;, ya que estas herramientas conforman un mundo enteramente nuevo y singular.&lt;br /&gt;
&lt;br /&gt;
La STL ofrece un conjunto de recursos flexible, potente y altamente optimizado para resolver una gran variedad de situaciones de programación. Pero esta versatilidad y potencia tributan un precio: su alto grado de parametrización supone algo más que utilizar herramientas aisladas. Es necesario saber ensamblar entre sí los recursos disponibles, que no trabajan aisladamente y que son básicamente de tres tipos: contenedores, iteradores y algoritmos. El resultado es que el proceso de utilizar la STL es algo más complicado que la simple búsqueda de una función que resuelva nuestras necesidades;  que la curva de aprendizaje es ciertamente más ardua que en el caso de la librería clásica, y  que los conceptos involucrados son más abstractos y requieren un conocimiento más extenso de sus fundamentos para utilizarlos. Desde luego, la descripción detallada de todos sus elementos exige un libro completo, y de hecho son muchos los que se han publicado con el objeto exclusivo de describir la STL y/o sus técnicas de uso. En compensación, las contrapartidas obtenidas justifican sin duda el esfuerzo. El programador puede concentrarse más en el problema que en los detalles de su implementación en el fuente, se incremente la productividad y se gana en claridad conceptual.&lt;br /&gt;
== Funciones y macros ==&lt;br /&gt;
Algunas [[Función_(programación)| funciones]] pueden venir implementadas de dos formas: como macro y como función. Por ejemplo, la función isalnum, contenida en &amp;lt;ctype.h&amp;gt;.  Esto significa que además de estar implementada como una función en la correspondiente librería (que se utiliza con los argumentos señalados en el manual), está definida como una macro de preprocesado en &amp;lt;ctype.h&amp;gt;, de forma que salvo indicación contraria al compilador, el preprocesador transforma la llamada del programador en otra serie de sentencias equivalentes que utilizan los mismos argumentos. El resultado es que en el código resultante, que luego pasa al compilador y al enlazador, no existe nada parecido a una llamada a una función isalnum (técnicamente el proceso es una sustitución inline de la función de librería.&lt;br /&gt;
&lt;br /&gt;
Para evitar que esto ocurra y por consiguiente que la llamada a islanum nunca llegue a producirse, basta con indefinir la correspondiente directiva. Esto se hace incluyendo al principio del código, y debajo de la línea #include &amp;lt;ctype.h&amp;gt;, una línea de preprocesado adecuada, en este caso:  #undef isalnum, con lo que el #define del preprocesador quedará sin efecto, con el resultado de que todas las invocaciones a isalnum de nuestro código serán respetadas por el preprocesador. Más tarde el enlazador cargará el código de isalnum (que extrae de la librería) con el resto de nuestro programa, y colocará en cada punto de nuestro código donde aparezca una invocación a isalnum, un salto a la dirección adecuada.&lt;br /&gt;
&lt;br /&gt;
En estos casos, el resultado es el mismo en ambas modalidades: como macro (por defecto) o como función de librería. La elección de una u otra es cuestión de optimización. Para tomar una decisión es necesario comprobar y valorar dos aspectos:&lt;br /&gt;
&lt;br /&gt;
•	El tamaño del ejecutable que resulta en uno y otro caso. Posiblemente mayor si se utiliza la función muchas veces y se adopta la macro.&lt;br /&gt;
&lt;br /&gt;
•	La velocidad de ejecución. Posiblemente mayor si se utiliza la función muchas veces (en bucles muy largos) y se utiliza la macro.&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[Ciencia de la Información]]&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http://www.zator.com/Cpp/E5.htm  Librería Estándar C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Librería Estándar en C.conclase.net]&lt;br /&gt;
* [https://uvadoc.uva.es/bitstream/10324/17502/1/PID_15_156_Anexo4.pdf  Elementos de la librería estándar C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Librer%C3%ADa_Est%C3%A1ndar_C%2B%2B&amp;diff=3232325</id>
		<title>Librería Estándar C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Librer%C3%ADa_Est%C3%A1ndar_C%2B%2B&amp;diff=3232325"/>
		<updated>2018-11-27T16:03:35Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Librería Estándar C++ |imagen=  |concepto= Una librería es un conjunto de recursos (algoritmos) prefabricados, que pueden ser utilizados por el programador para realizar determinadas operaciones }}''' Librería Estándar C++ '''. [[C++|C++]] no llega al nivel de simplicidad de su antecesor C, pero al igual que aquél, tampoco dispone de utilidades o funciones para entrada o salida implementadas en el propio lenguaje, de modo que estas y otras muchas, como manejo de cadenas de caracteres (strings), manejo de ficheros, funciones matemáticas Etc. son implementadas en forma de librerías externas.&lt;br /&gt;
== Sinopsis ==&lt;br /&gt;
Una librería es un conjunto de recursos (algoritmos) prefabricados, que pueden ser utilizados por el programador para realizar determinadas operaciones. Las declaraciones de las funciones (prototipos) utilizadas en estas librerías, junto con algunas macros y constantes predefinidas que facilitan su utilización, se agrupan en ficheros de nombres conocidos que suelen encontrarse en sitios predefinidos. Por ejemplo, en los sistemas UNIX, en  /usr/include. Estos ficheros se suelen llamar &amp;quot;de cabecera&amp;quot;, porque es tradición utilizar las primeras líneas del programa para poner las directivas #include que los incluirá en el fuente durante la fase de preprocesado.&lt;br /&gt;
== Clases de librerías ==&lt;br /&gt;
Los [[Compilador|compiladores]] [[C++|C++]] incluyen un amplio repertorio de clases, funciones y macros que permiten realizar una amplia variedad de tareas, incluyendo entradas/salidas de bajo y alto nivel; manipulación de cadenas alfanuméricas y ficheros; control de procesos (incluyendo multiproceso); manejo de memoria; cálculos matemáticos y un largo etcétera.&lt;br /&gt;
Este repertorio de recursos es denominado colectivamente como &amp;quot;Rutinas de librería&amp;quot;; &amp;quot;Librerías de ejecución&amp;quot; RTL (&amp;quot;Runtime Librarys&amp;quot;) o simplemente &amp;quot;Librerías&amp;quot;.   Puede decirse que el lenguaje aislado (tal cual) no tiene prácticamente ninguna utilidad sin la concurrencia de estas utilidades. El Estándar C++ las clasifica según su utilidad:&lt;br /&gt;
•	Soporte del lenguaje&lt;br /&gt;
•	Diagnóstico&lt;br /&gt;
•	Utilidades generales&lt;br /&gt;
•	Cadenas alfanuméricas (&amp;quot;Strings&amp;quot;)&lt;br /&gt;
•	Localización&lt;br /&gt;
•	Contenedores&lt;br /&gt;
•	Iteradores&lt;br /&gt;
•	Algoritmos&lt;br /&gt;
•	Cálculo numérico&lt;br /&gt;
•	Entrada/Salida&lt;br /&gt;
=== Librería Estándar C++ ===&lt;br /&gt;
Para poner un poco de orden, el Estándar C++ define la denominada Librería Estándar que debe acompañar a cada implementación del compilador que se adhiera al estándar. Es decir: la norma determina cuales son, como se llaman y como se utiliza este conjunto de algoritmos que deben acompañar (como mínimo) a cada implementación del compilador que quiera llamarse &amp;quot;Estándar&amp;quot;. La última versión, ISO/IEC 14882 del año 1998, especifica que se compone de 32 ficheros de cabecera de nombres fijos y conocidos agrupados según la funcionalidad de los algoritmos. Son los siguientes:&lt;br /&gt;
 &lt;br /&gt;
Ficheros	Funcionalidad/funciones&lt;br /&gt;
&lt;br /&gt;
&amp;lt;algorithm&amp;gt;	Parte de la STL que describe los algoritmos&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bitset&amp;gt;	Parte de la STL relativa a contenedores tipo bitset. Set de valores booleanos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;complex&amp;gt;	Parte de la librería numérica de la STL relativa a los complejos .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;deque&amp;gt;	Parte de la STL relativa a contenedores tipo deque;  un tipo de colas: &amp;quot;Double-ended-queue&amp;quot; .&lt;br /&gt;
&lt;br /&gt;
&amp;lt;exception&amp;gt;	Parte de la librería de diagnóstico relativa al manejo de excepciones&lt;br /&gt;
&lt;br /&gt;
&amp;lt;fstream&amp;gt;	Flujos hacia/desde ficheros.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;functional&amp;gt;	Parte de la STL relativa a Objetos-función&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iomanip&amp;gt;	Manipuladores.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ios&amp;gt;	Supreclases para manejo de flujos de E/S.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iosfwd&amp;gt;	Contiene declaraciones adelantadas de todas las plantillas de flujos y sus typedefs estándar. Por ejemplo ostream.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iostream&amp;gt;	Parte del a STL que contiene los algoritmos estándar de E/S.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;istream&amp;gt;	Algoritmos estándar de flujos de entrada.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iterator&amp;gt;	Parte de la STL relacionada con iteradores, un tipo de puntero que permite utilizar los algoritmos de la Librería con las estructuras de datos representadas por los contenedores.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;limits&amp;gt;	Descripción de propiedades dependientes de la implementación que afectan a los tipos fundamentales.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;list&amp;gt;	Parte de la STL relativa a contenedores tipo list;  listas doblemente enlazadas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;locale&amp;gt;	Parte de la STL relativa a la internacionalización.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;map&amp;gt;	Parte de la STL relativa a contenedores tipo map.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;memory&amp;gt;	Utilidades relativas a la gestión de memoria, incluyendo asignadores  y punteros inteligentes (auto_ptr).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;new&amp;gt;	Manejo de memoria dinámica.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;numeric&amp;gt;	Parte de la librería numérica de la STL relativa a operaciones numéricas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ostream&amp;gt;	Algoritmos estándar para los flujos de salida.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;queue&amp;gt;	Parte de la STL relativa a contenedores tipo queue;  colas de objetos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;set&amp;gt;	Parte de la STL relativa a contenedores tipo set.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;sstream&amp;gt;	Flujos hacia/desde cadenas alfanuméricas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;stack&amp;gt;	Parte de la STL relativa a contenedores tipo stack;  pilas de objetos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;stdexcept&amp;gt;	Parte de la STL relativa a las clases de las que derivan los objetos lanzados por las excepciones ocasionadas en los algoritmos de la propia STL y otras expresiones.  Estas clases son utilizadas para reportar errores detectados durante runtime.  Los usuarios también pueden utilizar excepciones para reportar errores en sus propios programas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;streambuf&amp;gt;	Parte de la STL relativa al Almacenamiento de flujos de E/S (&amp;quot;Stream buffers&amp;quot;).  Define los tipos que controlan la capa de transporte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;string&amp;gt;	Parte de la STL relativa a contenedores tipo string;  una generalización de las cadenas alfanuméricas para albergar cadenas de objetos.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;typeinfo&amp;gt;	Mecanismo de identificación de tipos en tiempo de ejecución.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;utility&amp;gt;	Parte de la STL que contiene elementos auxiliares como [[Operadores|operadores]] y pares (pairs).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;valarray&amp;gt;	Parte de la librería numérica de la STL relativa a manejo de matrices numéricas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;vector&amp;gt;	Parte de la STL relativa a los contenedores tipo vector; una generalización de las matrices unidimensionales C/C++.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Aunque generalmente las librerías no aportan ninguna característica al lenguaje (se supone que son utilidades auxiliares que no forman parte del lenguaje propiamente dicho), una pequeña porción de la Librería Estándar C++ sí aporta características que se consideran pertenecientes a este, de forma que deben estar presentes los ficheros de cabecera correspondientes si se desea usarlas. En concreto se refieren a los siguientes elementos:&lt;br /&gt;
&lt;br /&gt;
•	[[Operadores|operadores]] new, new[], delete y delete[].&lt;br /&gt;
&lt;br /&gt;
•	Clase type_info que corresponde al mecanismo RTTI de identificación de tipos en tiempo de ejecución representado por el operador typeid &lt;br /&gt;
&lt;br /&gt;
•	Rutinas de inicio y terminación.&lt;br /&gt;
&lt;br /&gt;
•	Las excepciones estándar lanzadas por los algoritmos anteriores&lt;br /&gt;
&lt;br /&gt;
=== Librería C ===&lt;br /&gt;
Además de otras nuevas, cuyo diseño e importancia cambian drásticamente la filosofía del lenguaje, C++ incluye prácticamente la totalidad de [[Función_(programación)| funciones]] de la primitiva librería estándar C. A esta librería, mantenida por compatibilidad, la denominamos Librería clásica.&lt;br /&gt;
=== Otras librerías ===&lt;br /&gt;
Además de las que proporciona el estándar y las complementarias que pueda incluir por su cuenta el fabricante del compilador, en los proyectos reales se suelen utilizar infinidad de otras librerías, comerciales o públicas, que facilitan el trabajo en áreas particulares, y en este sentido, recordar que uno de los pecados que el programador novel debe evitar, es la tendencia a querer reinventar constantemente la rueda. De forma que el consejo es utilizar en lo posible librerías que estén probadas y sean fácilmente accesibles. Aunque hay que tener cuidado, porque determinados proyectos exigen que las librerías utilizadas estén perfectamente documentadas y en ciertos casos, que se cuente con los fuentes correspondientes.&lt;br /&gt;
== Componentes ==&lt;br /&gt;
Al referirnos a las librerías C++ utilizamos la terminología siguiente:&lt;br /&gt;
&lt;br /&gt;
•	RTL  Conjunto de librerías que acompañan a un compilador (&amp;quot;Runtime Library&amp;quot;), sean o no estándar.&lt;br /&gt;
&lt;br /&gt;
•	Librería Estándar. Conjunto de librerías cuyo contenido está definido por el Estándar C++ (abreviadamente LE).&lt;br /&gt;
&lt;br /&gt;
•	Libería clásica. Parte de la Librería Estándar correspondiente al C clásico.&lt;br /&gt;
&lt;br /&gt;
•	STL (&amp;quot;Standard Templete Library&amp;quot;). Parte de la LE genuina de C++ (que no es heredada de C) y que responde a la forma &amp;quot;++&amp;quot; de hacer las cosas.&lt;br /&gt;
&lt;br /&gt;
La calidad de un compilador C++ viene determinada en gran medida por la calidad y cantidad de su RTL; por su grado de adherencia al Estándar  y por el grado de soporte que proporciona para la plataforma concreta a que se destina.&lt;br /&gt;
&lt;br /&gt;
En lo que concierne a la programación para MS Windows (las referencias a la plataforma Wintel surgen de forma constante e inevitable), los [[Compilador|compiladores]] Borland C++ y MS Visual C++ son quizás los más conocidos y utilizados.  El primero incluye una completa librería denominada VCL (Visual Component Library. La del segundo es conocida como MFC (Microsoft Foundation Classes).&lt;br /&gt;
&lt;br /&gt;
Linux dispone de su propio compilador: GNU Cpp, que comenzó siendo un compilador C y ha evolucionado a un producto que es en realidad un superconjunto de compiladores. No solo puede compilar código C y C++;  también otros lenguajes como Ada o Fortran;  de forma que es común referirse a ellos como GCC (&amp;quot;GNU Compiler Collection&amp;quot;).  La buena noticia es que existen versiones de este compilador para plataformas Windows, de forma que incluso en este ambiente &amp;quot;Propietario&amp;quot; pueden realizarse desarrollos utilizando herramientas &amp;quot;Open source&amp;quot; &lt;br /&gt;
A grandes rasgos la librería Estándar C++ comprende los siguientes módulos:&lt;br /&gt;
&lt;br /&gt;
•	La denominada Librería Estándar de Plantillas, abreviadamente STL (&amp;quot;Standard Templete Library&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
•	Librería numérica. Parte de la STL que contiene algoritmos especialmente concebidos para computación numérica. Por ejemplo, una clase valarray optimizada para matrices numéricas y una clase complex para manejo y representación estandarizada de números complejos (en realidad una plantilla con especializaciones para los tipos float, double y long double.&lt;br /&gt;
&lt;br /&gt;
•	Utilidades. Parte de la STL dedicada a elementos auxiliares tales como adaptadores y la clase auto_ptr.&lt;br /&gt;
&lt;br /&gt;
•	Unas utilidades de entrada/salida de flujos, denominadas genéricamente iostreams.&lt;br /&gt;
&lt;br /&gt;
•	Una utilidad locale para manejo de localismos.&lt;br /&gt;
&lt;br /&gt;
•	Una clase string para manejo estandarizado de cadenas de caracteres.  En realidad es una instanciación (especialización) de la plantilla basic_string para cadenas de caracteres.&lt;br /&gt;
 &lt;br /&gt;
•	Un esquema para describir de modo uniforme el entorno de ejecución mediante la utilización de una clase estándar denominada numeric_limits y especialización para cada uno de los tipos de datos fundamentales.&lt;br /&gt;
&lt;br /&gt;
•	Utilidades para manejo de memoria.&lt;br /&gt;
&lt;br /&gt;
•	Soporte para utilización de juegos de caracteres y signos de diversos idiomas.&lt;br /&gt;
&lt;br /&gt;
•	Utilidades de diagnóstico y manejo de errores. Incluyen manejo de excepciones y la macro assert.&lt;br /&gt;
&lt;br /&gt;
== Funcionalidad ==&lt;br /&gt;
Si atendemos a su funcionalidad,  las utilidades ofrecidas por la Librería Estándar pueden agruparse en:&lt;br /&gt;
&lt;br /&gt;
•	Clasificación: Clasifican caracteres ASCII, como letras, caracteres de control (no imprimibles), Mayúsculas/minúsculas etc. Se definen en la cabecera &amp;lt;ctype.h&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
•	Entradas/Salidas de Consola: Estas son las denominadas entrada/salida estándar. Por defecto se refieren al teclado y a la pantalla (no pueden utilizarse directamente en aplicaciones de interfaz gráfica).&lt;br /&gt;
&lt;br /&gt;
•	Conversión: Convierten caracteres y cadenas de caracteres desde formato alfabético a numérico de diversos tipos (float, int, long).  También realizan la conversión inversa: de formatos numéricos a representaciones alfabéticas y de mayúsculas a minúsculas y viceversa.&lt;br /&gt;
&lt;br /&gt;
•	Diagnóstico: Son rutinas destinadas a comprobaciones; a descubrir y corregir posibles errores.&lt;br /&gt;
&lt;br /&gt;
•	Directorio: Rutinas para manejo de directorios y sus direcciones (path names).&lt;br /&gt;
&lt;br /&gt;
•	En linea (Inline): Rutinas para versiones inline de funciones. El compilador genera el código correspondiente para las versiones inline cuando se utiliza #pragma intrinsic o si se solicita optimización al compilador (optimización de tiempo de ejecución).&lt;br /&gt;
&lt;br /&gt;
•	Entrada/Salida. Son rutinas que proporcionan manejo de flujos y operaciones de Entrada/Salida a bajo nivel (de Sistema Operativo).&lt;br /&gt;
&lt;br /&gt;
•	Manipulación. Manejo de cadenas y bloques de memoria: copiar, comparar, convertir y buscar.&lt;br /&gt;
&lt;br /&gt;
•	Matemáticas: Para realizar cálculos matemáticos.&lt;br /&gt;
&lt;br /&gt;
•	De Memoria: Proporcionan asignación de memoria dinámica.&lt;br /&gt;
&lt;br /&gt;
•	Miscelánea. Se agrupan aquí rutinas varias, como las que posibilitan saltos (goto) no locales y las que manejan diferencias de tipo cultural o de lenguaje. Por ejemplo representación de números, de moneda, formatos de fecha y hora, clasificación de tipo alfabético.&lt;br /&gt;
&lt;br /&gt;
•	Control de proceso. Rutinas que permiten invocar y terminar nuevos procesos desde otra rutina.&lt;br /&gt;
&lt;br /&gt;
•	Fecha y hora. Incluyen rutinas para conversión y manipulación de variables de medida del tiempo (fecha y hora).&lt;br /&gt;
&lt;br /&gt;
•	Argumentos variables. Rutinas utilizadas cuando se usan listas variables de argumentos, como en los casos de printf(), vscanf().&lt;br /&gt;
== Utilización ==&lt;br /&gt;
La utilización de la Librería Estándar C++ requiere de dos tipos de condiciones que podríamos describir como formales y conceptuales.&lt;br /&gt;
&lt;br /&gt;
1. En cuanto a las primeras (condiciones formales) y habida cuenta que las utilidades aparecen en forma de funciones, resulta evidente que su utilización exige incluirlas en nuestro programa. Para ello se necesitan tres pasos (en realidad las exigencias son las mismas que con cualquier otra función, la diferencia estriba en la forma en que se realizan los pasos b y c):&lt;br /&gt;
&lt;br /&gt;
a:  Incluir en el código fuente las invocaciones a las [[Función_(programación)| funciones]] que estamos utilizando. Ejemplo:&lt;br /&gt;
printf(&amp;quot;Esto es una llamada a la función \&amp;quot;printf\&amp;quot; de librería\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
 b:  Incluir en el código fuente los prototipos de dichas funciones.&lt;br /&gt;
&lt;br /&gt;
Puesto que los prototipos ya están incluidos en los ficheros estándar de cabecera, hay que indicar al compilador que los incluya. Esto se realiza poniendo en nuestro fuente (normalmente al principio) una directiva de preprocesado #include que señala el fichero de cabecera que se debe añadir. Por ejemplo, si el manual indica que la función printf está definida en el fichero de cabecera stdio.h ponemos en nuestro código:&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  c:  Incluir en el fuente las definiciones de las funciones utilizadas. Como alternativa se puede indicar al compilador que tales definiciones están en ficheros compilados previamente.&lt;br /&gt;
&lt;br /&gt;
En este último caso se dice que las definiciones de las funciones están en librerías de las que existen dos tipos: estáticas (.LIB, .OBJ y .BPI) y dinámicas (.DLL). Toda la información que necesita el compilador está contenida en los ficheros de cabecera, por lo que las operaciones correspondientes son realizadas de forma automática; con la sola condición de que los ficheros y librerías correspondientes sean accesibles al enlazador.&lt;br /&gt;
&lt;br /&gt;
Las entidades de la Librería Estándar C++ (que no están en ficheros de cabecera .h), se han definido en un espacio de nombres denominado std, por lo que es preciso referirse a él específicamente cuando se quieran utilizar estos recursos.&lt;br /&gt;
&lt;br /&gt;
2. Respecto a las que hemos denominado &amp;quot;condiciones conceptuales&amp;quot;, damos por sentado que la utilización de algoritmos de la Librería exige conocerlos. Pero debemos advertir que existe una gran diferencia entre las rutinas de la que hemos denominado librería clásica y los recursos de la nueva Librería Estándar de Plantillas STL.&lt;br /&gt;
&lt;br /&gt;
En general los algoritmos contenidos en la librería clásica realizan tareas muy sencillas bajo la forma de funciones que, con un cierto número de argumentos, realizan la tarea encomendada. A veces devolviendo un objeto (que puede ser una estructura). Su utilización exige poco más que repasar esta colección de funciones (209 en la última versión del Estándar) hasta encontrar la que mejor se ajusta a nuestras necesidades. Para esto lo mejor es recurrir a la clasificación temática ofrecida en la documentación que acompaña a los compiladores antes que a la lista alfabética de las mismas. A continuación estudiamos atentamente su prototipo y la explicación de funcionamiento que acompaña el manual (eventualmente incluso con un ejemplo) y ya estamos listos para utilizarla. En el peor de los casos suelen bastar un par de pruebas hasta que conseguimos ajustar los argumentos de forma que se consiga el resultado esperado.&lt;br /&gt;
&lt;br /&gt;
Como última recomendación al respecto, sobre todo si pensamos que nuestro programa tendrá una larga vida y/o pensamos portarlo a otras plataformas, aconsejaría echar un vistazo a la sección de &amp;quot;compatibilidad&amp;quot; que acompaña a la descripción de cada función en la documentación de la mayoría de compiladores. Suele ocurrir que el compilador ofrezca muchas más funciones que las estrictamente Estándar C++, y que estas no estén claramente separadas del resto, de forma que es posible que elijamos una función que resuelve nuestro problema pero no es portable, en cuyo caso aconsejaría evitarlas dentro de lo posible.&lt;br /&gt;
&lt;br /&gt;
La utilización de la nueva Librería de Plantillas (STL) exige la asimilación de un nuevo paradigma;  una nueva forma de pensar que, si se tiene experiencia en programación tradicional, exige incluso un &amp;quot;cambio de chip&amp;quot;, ya que estas herramientas conforman un mundo enteramente nuevo y singular.&lt;br /&gt;
&lt;br /&gt;
La STL ofrece un conjunto de recursos flexible, potente y altamente optimizado para resolver una gran variedad de situaciones de programación. Pero esta versatilidad y potencia tributan un precio: su alto grado de parametrización supone algo más que utilizar herramientas aisladas. Es necesario saber ensamblar entre sí los recursos disponibles, que no trabajan aisladamente y que son básicamente de tres tipos: contenedores, iteradores y algoritmos. El resultado es que el proceso de utilizar la STL es algo más complicado que la simple búsqueda de una función que resuelva nuestras necesidades;  que la curva de aprendizaje es ciertamente más ardua que en el caso de la librería clásica, y  que los conceptos involucrados son más abstractos y requieren un conocimiento más extenso de sus fundamentos para utilizarlos. Desde luego, la descripción detallada de todos sus elementos exige un libro completo, y de hecho son muchos los que se han publicado con el objeto exclusivo de describir la STL y/o sus técnicas de uso. En compensación, las contrapartidas obtenidas justifican sin duda el esfuerzo. El programador puede concentrarse más en el problema que en los detalles de su implementación en el fuente, se incremente la productividad y se gana en claridad conceptual.&lt;br /&gt;
== Funciones y macros ==&lt;br /&gt;
Algunas [[Función_(programación)| funciones]] pueden venir implementadas de dos formas: como macro y como función. Por ejemplo, la función isalnum, contenida en &amp;lt;ctype.h&amp;gt;.  Esto significa que además de estar implementada como una función en la correspondiente librería (que se utiliza con los argumentos señalados en el manual), está definida como una macro de preprocesado en &amp;lt;ctype.h&amp;gt;, de forma que salvo indicación contraria al compilador, el preprocesador transforma la llamada del programador en otra serie de sentencias equivalentes que utilizan los mismos argumentos. El resultado es que en el código resultante, que luego pasa al compilador y al enlazador, no existe nada parecido a una llamada a una función isalnum (técnicamente el proceso es una sustitución inline de la función de librería.&lt;br /&gt;
&lt;br /&gt;
Para evitar que esto ocurra y por consiguiente que la llamada a islanum nunca llegue a producirse, basta con indefinir la correspondiente directiva. Esto se hace incluyendo al principio del código, y debajo de la línea #include &amp;lt;ctype.h&amp;gt;, una línea de preprocesado adecuada, en este caso:  #undef isalnum, con lo que el #define del preprocesador quedará sin efecto, con el resultado de que todas las invocaciones a isalnum de nuestro código serán respetadas por el preprocesador. Más tarde el enlazador cargará el código de isalnum (que extrae de la librería) con el resto de nuestro programa, y colocará en cada punto de nuestro código donde aparezca una invocación a isalnum, un salto a la dirección adecuada.&lt;br /&gt;
&lt;br /&gt;
En estos casos, el resultado es el mismo en ambas modalidades: como macro (por defecto) o como función de librería. La elección de una u otra es cuestión de optimización. Para tomar una decisión es necesario comprobar y valorar dos aspectos:&lt;br /&gt;
&lt;br /&gt;
•	El tamaño del ejecutable que resulta en uno y otro caso. Posiblemente mayor si se utiliza la función muchas veces y se adopta la macro.&lt;br /&gt;
&lt;br /&gt;
•	La velocidad de ejecución. Posiblemente mayor si se utiliza la función muchas veces (en bucles muy largos) y se utiliza la macro.&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[Ciencia de la Información]]&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http:// www.zator.com/Cpp/E5.htm Librería Estándar C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Librería Estándar en C.conclase.net]&lt;br /&gt;
* [https://uvadoc.uva.es/bitstream/10324/17502/1/PID_15_156_Anexo4.pdf  Elementos de la librería estándar C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]] [[Category:Progr&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Librer%C3%ADa_Est%C3%A1ndar_C%2B%2B&amp;diff=3232314</id>
		<title>Librería Estándar C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Librer%C3%ADa_Est%C3%A1ndar_C%2B%2B&amp;diff=3232314"/>
		<updated>2018-11-27T15:58:21Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Librería Estándar C++ |imagen=  |concepto= Una librería es un conjunto de recursos (algoritmos) prefabricados, que pueden ser utilizados por el programador para realizar determinadas operaciones }}''' Librería Estándar C++ '''. [[C++|C++]] no llega al nivel de simplicidad de su antecesor C, pero al igual que aquél, tampoco dispone de utilidades o funciones para entrada o salida implementadas en el propio lenguaje, de modo que estas y otras muchas, como manejo de cadenas de caracteres (strings), manejo de ficheros, funciones matemáticas Etc. son implementadas en forma de librerías externas.&lt;br /&gt;
== Sinopsis ==&lt;br /&gt;
Una librería es un conjunto de recursos (algoritmos) prefabricados, que pueden ser utilizados por el programador para realizar determinadas operaciones. Las declaraciones de las funciones (prototipos) utilizadas en estas librerías, junto con algunas macros y constantes predefinidas que facilitan su utilización, se agrupan en ficheros de nombres conocidos que suelen encontrarse en sitios predefinidos. Por ejemplo, en los sistemas UNIX, en  /usr/include. Estos ficheros se suelen llamar &amp;quot;de cabecera&amp;quot;, porque es tradición utilizar las primeras líneas del programa para poner las directivas #include que los incluirá en el fuente durante la fase de preprocesado.&lt;br /&gt;
== Clases de librerías ==&lt;br /&gt;
Los [[Compilador|compiladores]] [[C++|C++]] incluyen un amplio repertorio de clases, funciones y macros que permiten realizar una amplia variedad de tareas, incluyendo entradas/salidas de bajo y alto nivel; manipulación de cadenas alfanuméricas y ficheros; control de procesos (incluyendo multiproceso); manejo de memoria; cálculos matemáticos y un largo etcétera.&lt;br /&gt;
Este repertorio de recursos es denominado colectivamente como &amp;quot;Rutinas de librería&amp;quot;; &amp;quot;Librerías de ejecución&amp;quot; RTL (&amp;quot;Runtime Librarys&amp;quot;) o simplemente &amp;quot;Librerías&amp;quot;.   Puede decirse que el lenguaje aislado (tal cual) no tiene prácticamente ninguna utilidad sin la concurrencia de estas utilidades. El Estándar C++ las clasifica según su utilidad:&lt;br /&gt;
•	Soporte del lenguaje&lt;br /&gt;
•	Diagnóstico&lt;br /&gt;
•	Utilidades generales&lt;br /&gt;
•	Cadenas alfanuméricas (&amp;quot;Strings&amp;quot;)&lt;br /&gt;
•	Localización&lt;br /&gt;
•	Contenedores&lt;br /&gt;
•	Iteradores&lt;br /&gt;
•	Algoritmos&lt;br /&gt;
•	Cálculo numérico&lt;br /&gt;
•	Entrada/Salida&lt;br /&gt;
=== Librería Estándar C++ ===&lt;br /&gt;
Para poner un poco de orden, el Estándar C++ define la denominada Librería Estándar que debe acompañar a cada implementación del compilador que se adhiera al estándar. Es decir: la norma determina cuales son, como se llaman y como se utiliza este conjunto de algoritmos que deben acompañar (como mínimo) a cada implementación del compilador que quiera llamarse &amp;quot;Estándar&amp;quot;. La última versión, ISO/IEC 14882 del año 1998, especifica que se compone de 32 ficheros de cabecera de nombres fijos y conocidos agrupados según la funcionalidad de los algoritmos. Son los siguientes:&lt;br /&gt;
 &lt;br /&gt;
Ficheros	Funcionalidad/funciones&lt;br /&gt;
&lt;br /&gt;
&amp;lt;algorithm&amp;gt;	Parte de la STL que describe los algoritmos&lt;br /&gt;
&amp;lt;bitset&amp;gt;	Parte de la STL relativa a contenedores tipo bitset. Set de valores booleanos.&lt;br /&gt;
&amp;lt;complex&amp;gt;	Parte de la librería numérica de la STL relativa a los complejos .&lt;br /&gt;
&amp;lt;deque&amp;gt;	Parte de la STL relativa a contenedores tipo deque;  un tipo de colas: &amp;quot;Double-ended-queue&amp;quot; .&lt;br /&gt;
&amp;lt;exception&amp;gt;	Parte de la librería de diagnóstico relativa al manejo de excepciones&lt;br /&gt;
&amp;lt;fstream&amp;gt;	Flujos hacia/desde ficheros.&lt;br /&gt;
&amp;lt;functional&amp;gt;	Parte de la STL relativa a Objetos-función&lt;br /&gt;
&amp;lt;iomanip&amp;gt;	Manipuladores.&lt;br /&gt;
&amp;lt;ios&amp;gt;	Supreclases para manejo de flujos de E/S.&lt;br /&gt;
&amp;lt;iosfwd&amp;gt;	Contiene declaraciones adelantadas de todas las plantillas de flujos y sus typedefs estándar. Por ejemplo ostream.&lt;br /&gt;
&amp;lt;iostream&amp;gt;	Parte del a STL que contiene los algoritmos estándar de E/S.&lt;br /&gt;
&amp;lt;istream&amp;gt;	Algoritmos estándar de flujos de entrada.&lt;br /&gt;
&amp;lt;iterator&amp;gt;	Parte de la STL relacionada con iteradores, un tipo de puntero que permite utilizar los algoritmos de la Librería con las estructuras de datos representadas por los contenedores.&lt;br /&gt;
&amp;lt;limits&amp;gt;	Descripción de propiedades dependientes de la implementación que afectan a los tipos fundamentales.&lt;br /&gt;
&amp;lt;list&amp;gt;	Parte de la STL relativa a contenedores tipo list;  listas doblemente enlazadas&lt;br /&gt;
&amp;lt;locale&amp;gt;	Parte de la STL relativa a la internacionalización.&lt;br /&gt;
&amp;lt;map&amp;gt;	Parte de la STL relativa a contenedores tipo map.&lt;br /&gt;
&amp;lt;memory&amp;gt;	Utilidades relativas a la gestión de memoria, incluyendo asignadores  y punteros inteligentes (auto_ptr).&lt;br /&gt;
&amp;lt;new&amp;gt;	Manejo de memoria dinámica&lt;br /&gt;
&amp;lt;numeric&amp;gt;	Parte de la librería numérica de la STL relativa a operaciones numéricas.&lt;br /&gt;
&amp;lt;ostream&amp;gt;	Algoritmos estándar para los flujos de salida.&lt;br /&gt;
&amp;lt;queue&amp;gt;	Parte de la STL relativa a contenedores tipo queue;  colas de objetos.&lt;br /&gt;
&amp;lt;set&amp;gt;	Parte de la STL relativa a contenedores tipo set .&lt;br /&gt;
&amp;lt;sstream&amp;gt;	Flujos hacia/desde cadenas alfanuméricas.&lt;br /&gt;
&amp;lt;stack&amp;gt;	Parte de la STL relativa a contenedores tipo stack;  pilas de objetos.&lt;br /&gt;
&amp;lt;stdexcept&amp;gt;	Parte de la STL relativa a las clases de las que derivan los objetos lanzados por las excepciones ocasionadas en los algoritmos de la propia STL y otras expresiones.  Estas clases son utilizadas para reportar errores detectados durante runtime.  Los usuarios también pueden utilizar excepciones para reportar errores en sus propios programas.&lt;br /&gt;
&amp;lt;streambuf&amp;gt;	Parte de la STL relativa al Almacenamiento de flujos de E/S (&amp;quot;Stream buffers&amp;quot;).  Define los tipos que controlan la capa de transporte.&lt;br /&gt;
&amp;lt;string&amp;gt;	Parte de la STL relativa a contenedores tipo string;  una generalización de las cadenas alfanuméricas para albergar cadenas de objetos.&lt;br /&gt;
&amp;lt;typeinfo&amp;gt;	Mecanismo de identificación de tipos en tiempo de ejecución.&lt;br /&gt;
&amp;lt;utility&amp;gt;	Parte de la STL que contiene elementos auxiliares como [[Operadores|operadores]] y pares (pairs).&lt;br /&gt;
&amp;lt;valarray&amp;gt;	Parte de la librería numérica de la STL relativa a manejo de matrices numéricas&lt;br /&gt;
&amp;lt;vector&amp;gt;	Parte de la STL relativa a los contenedores tipo vector; una generalización de las matrices unidimensionales C/C++&lt;br /&gt;
&lt;br /&gt;
Es digno de mención que aunque generalmente las librerías no aportan ninguna característica al lenguaje (se supone que son utilidades auxiliares que no forman parte del lenguaje propiamente dicho), una pequeña porción de la Librería Estándar C++ sí aporta características que se consideran pertenecientes a este, de forma que deben estar presentes los ficheros de cabecera correspondientes si se desea usarlas. En concreto se refieren a los siguientes elementos:&lt;br /&gt;
•	[[Operadores|operadores]] new, new[], delete y delete[].&lt;br /&gt;
•	Clase type_info que corresponde al mecanismo RTTI de identificación de tipos en tiempo de ejecución representado por el operador typeid &lt;br /&gt;
•	Rutinas de inicio y terminación.&lt;br /&gt;
•	Las excepciones estándar lanzadas por los algoritmos anteriores&lt;br /&gt;
=== Librería C ===&lt;br /&gt;
Además de otras nuevas, cuyo diseño e importancia cambian drásticamente la filosofía del lenguaje, C++ incluye prácticamente la totalidad de [[Función_(programación)| funciones]] de la primitiva librería estándar C. A esta librería, mantenida por compatibilidad, la denominamos Librería clásica.&lt;br /&gt;
=== Otras librerías ===&lt;br /&gt;
Además de las que proporciona el estándar y las complementarias que pueda incluir por su cuenta el fabricante del compilador, en los proyectos reales se suelen utilizar infinidad de otras librerías, comerciales o públicas, que facilitan el trabajo en áreas particulares, y en este sentido, recordar que uno de los pecados que el programador novel debe evitar, es la tendencia a querer reinventar constantemente la rueda. De forma que el consejo es utilizar en lo posible librerías que estén probadas y sean fácilmente accesibles. Aunque hay que tener cuidado, porque determinados proyectos exigen que las librerías utilizadas estén perfectamente documentadas y en ciertos casos, que se cuente con los fuentes correspondientes.&lt;br /&gt;
== Componentes ==&lt;br /&gt;
Al referirnos a las librerías C++ utilizamos la terminología siguiente:&lt;br /&gt;
•	RTL  Conjunto de librerías que acompañan a un compilador (&amp;quot;Runtime Library&amp;quot;), sean o no estándar.&lt;br /&gt;
•	Librería Estándar. Conjunto de librerías cuyo contenido está definido por el Estándar C++ (abreviadamente LE)&lt;br /&gt;
•	Libería clásica. Parte de la Librería Estándar correspondiente al C clásico.&lt;br /&gt;
•	STL (&amp;quot;Standard Templete Library&amp;quot;). Parte de la LE genuina de C++ (que no es heredada de C) y que responde a la forma &amp;quot;++&amp;quot; de hacer las cosas.&lt;br /&gt;
La calidad de un compilador C++ viene determinada en gran medida por la calidad y cantidad de su RTL; por su grado de adherencia al Estándar  y por el grado de soporte que proporciona para la plataforma concreta a que se destina.&lt;br /&gt;
Nota: en lo que concierne a la programación para MS Windows (las referencias a la plataforma Wintel surgen de forma constante e inevitable), los [[Compilador|compiladores]] Borland C++ y MS Visual C++ son quizás los más conocidos y utilizados.  El primero incluye una completa librería denominada VCL (Visual Component Library. La del segundo es conocida como MFC (Microsoft Foundation Classes).&lt;br /&gt;
&lt;br /&gt;
Linux dispone de su propio compilador: GNU Cpp, que comenzó siendo un compilador C y ha evolucionado a un producto que es en realidad un superconjunto de compiladores. No solo puede compilar código C y C++;  también otros lenguajes como Ada o Fortran;  de forma que es común referirse a ellos como GCC (&amp;quot;GNU Compiler Collection&amp;quot;).  La buena noticia es que existen versiones de este compilador para plataformas Windows, de forma que incluso en este ambiente &amp;quot;Propietario&amp;quot; pueden realizarse desarrollos utilizando herramientas &amp;quot;Open source&amp;quot; &lt;br /&gt;
A grandes rasgos la librería Estándar C++ comprende los siguientes módulos:&lt;br /&gt;
•	La denominada Librería Estándar de Plantillas, abreviadamente STL (&amp;quot;Standard Templete Library&amp;quot;).&lt;br /&gt;
o	Librería numérica. Parte de la STL que contiene algoritmos especialmente concebidos para computación numérica. Por ejemplo, una clase valarray optimizada para matrices numéricas y una clase complex para manejo y representación estandarizada de números complejos (en realidad una plantilla con especializaciones para los tipos float, double y long double).&lt;br /&gt;
o	Utilidades. Parte de la STL dedicada a elementos auxiliares tales como adaptadores y la clase auto_ptr.&lt;br /&gt;
•	Unas utilidades de entrada/salida de flujos, denominadas genéricamente iostreams.&lt;br /&gt;
•	Una utilidad locale para manejo de localismos.&lt;br /&gt;
•	Una clase string para manejo estandarizado de cadenas de caracteres.  En realidad es una instanciación (especialización) de la plantilla basic_string para cadenas de caracteres. &lt;br /&gt;
•	Un esquema para describir de modo uniforme el entorno de ejecución mediante la utilización de una clase estándar denominada numeric_limits y especialización para cada uno de los tipos de datos fundamentales.&lt;br /&gt;
•	Utilidades para manejo de memoria.&lt;br /&gt;
•	Soporte para utilización de juegos de caracteres y signos de diversos idiomas.&lt;br /&gt;
•	Utilidades de diagnóstico y manejo de errores. Incluyen manejo de excepciones y la macro assert.&lt;br /&gt;
== Funcionalidad ==&lt;br /&gt;
Si atendemos a su funcionalidad,  las utilidades ofrecidas por la Librería Estándar pueden agruparse en:&lt;br /&gt;
•	Clasificación: Clasifican caracteres ASCII, como letras, caracteres de control (no imprimibles), Mayúsculas/minúsculas etc. Se definen en la cabecera &amp;lt;ctype.h&amp;gt;.&lt;br /&gt;
•	Entradas/Salidas de Consola: Estas son las denominadas entrada/salida estándar. Por defecto se refieren al teclado y a la pantalla (no pueden utilizarse directamente en aplicaciones de interfaz gráfica).&lt;br /&gt;
•	Conversión: Convierten caracteres y cadenas de caracteres desde formato alfabético a numérico de diversos tipos (float, int, long).  También realizan la conversión inversa: de formatos numéricos a representaciones alfabéticas y de mayúsculas a minúsculas y viceversa.&lt;br /&gt;
•	Diagnóstico: Son rutinas destinadas a comprobaciones; a descubrir y corregir posibles errores.&lt;br /&gt;
•	Directorio: Rutinas para manejo de directorios y sus direcciones (path names).&lt;br /&gt;
•	En linea (Inline): Rutinas para versiones inline de funciones. El compilador genera el código correspondiente para las versiones inline cuando se utiliza #pragma intrinsic o si se solicita optimización al compilador (optimización de tiempo de ejecución).&lt;br /&gt;
•	Entrada/Salida. Son rutinas que proporcionan manejo de flujos y operaciones de Entrada/Salida a bajo nivel (de Sistema Operativo).&lt;br /&gt;
•	Manipulación. Manejo de cadenas y bloques de memoria: copiar, comparar, convertir y buscar.&lt;br /&gt;
•	Matemáticas: Para realizar cálculos matemáticos.&lt;br /&gt;
•	De Memoria: Proporcionan asignación de memoria dinámica.&lt;br /&gt;
•	Miscelánea. Se agrupan aquí rutinas varias, como las que posibilitan saltos (goto) no locales y las que manejan diferencias de tipo cultural o de lenguaje. Por ejemplo representación de números, de moneda, formatos de fecha y hora, clasificación de tipo alfabético, etc.&lt;br /&gt;
•	Control de proceso. Rutinas que permiten invocar y terminar nuevos procesos desde otra rutina.&lt;br /&gt;
•	Fecha y hora. Incluyen rutinas para conversión y manipulación de variables de medida del tiempo (fecha y hora).&lt;br /&gt;
•	Argumentos variables. Rutinas utilizadas cuando se usan listas variables de argumentos, como en los casos de printf(), vscanf(), etc.&lt;br /&gt;
== Utilización ==&lt;br /&gt;
La utilización de la Librería Estándar C++ requiere de dos tipos de condiciones que podríamos describir como formales y conceptuales.&lt;br /&gt;
&lt;br /&gt;
1. En cuanto a las primeras (condiciones formales) y habida cuenta que las utilidades aparecen en forma de funciones, resulta evidente que su utilización exige incluirlas en nuestro programa. Para ello se necesitan tres pasos (en realidad las exigencias son las mismas que con cualquier otra función, la diferencia estriba en la forma en que se realizan los pasos b y c):&lt;br /&gt;
a:  Incluir en el código fuente las invocaciones a las [[Función_(programación)| funciones]] que estamos utilizando. Ejemplo:&lt;br /&gt;
printf(&amp;quot;Esto es una llamada a la función \&amp;quot;printf\&amp;quot; de librería\n&amp;quot;);&lt;br /&gt;
 b:  Incluir en el código fuente los prototipos de dichas funciones.&lt;br /&gt;
Puesto que los prototipos ya están incluidos en los ficheros estándar de cabecera, hay que indicar al compilador que los incluya. Esto se realiza poniendo en nuestro fuente (normalmente al principio) una directiva de preprocesado #include que señala el fichero de cabecera que se debe añadir. Por ejemplo, si el manual indica que la función printf está definida en el fichero de cabecera stdio.h ponemos en nuestro código:&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  c:  Incluir en el fuente las definiciones de las funciones utilizadas. Como alternativa se puede indicar al compilador que tales definiciones están en ficheros compilados previamente.&lt;br /&gt;
En este último caso se dice que las definiciones de las funciones están en librerías de las que existen dos tipos: estáticas (.LIB, .OBJ y .BPI) y dinámicas (.DLL). Toda la información que necesita el compilador está contenida en los ficheros de cabecera, por lo que las operaciones correspondientes son realizadas de forma automática; con la sola condición de que los ficheros y librerías correspondientes sean accesibles al enlazador.&lt;br /&gt;
&lt;br /&gt;
No olvidar que la entidades de la Librería Estándar C++ (que no están en ficheros de cabecera .h), se han definido en un espacio de nombres denominado std, por lo que es preciso referirse a él específicamente cuando se quieran utilizar estos recursos.&lt;br /&gt;
&lt;br /&gt;
2. Respecto a las que hemos denominado &amp;quot;condiciones conceptuales&amp;quot;, damos por sentado que la utilización de algoritmos de la Librería exige conocerlos. Pero debemos advertir que existe una gran diferencia entre las rutinas de la que hemos denominado librería clásica y los recursos de la nueva Librería Estándar de Plantillas STL.&lt;br /&gt;
En general los algoritmos contenidos en la librería clásica realizan tareas muy sencillas bajo la forma de funciones que, con un cierto número de argumentos, realizan la tarea encomendada. A veces devolviendo un objeto (que puede ser una estructura). Su utilización exige poco más que repasar esta colección de funciones (209 en la última versión del Estándar) hasta encontrar la que mejor se ajusta a nuestras necesidades. Para esto lo mejor es recurrir a la clasificación temática ofrecida en la documentación que acompaña a los compiladores antes que a la lista alfabética de las mismas. A continuación estudiamos atentamente su prototipo y la explicación de funcionamiento que acompaña el manual (eventualmente incluso con un ejemplo) y ya estamos listos para utilizarla. En el peor de los casos suelen bastar un par de pruebas hasta que conseguimos ajustar los argumentos de forma que se consiga el resultado esperado.&lt;br /&gt;
Como última recomendación al respecto, sobre todo si pensamos que nuestro programa tendrá una larga vida y/o pensamos portarlo a otras plataformas, aconsejaría echar un vistazo a la sección de &amp;quot;compatibilidad&amp;quot; que acompaña a la descripción de cada función en la documentación de la mayoría de compiladores. Suele ocurrir que el compilador ofrezca muchas más funciones que las estrictamente Estándar C++, y que estas no estén claramente separadas del resto, de forma que es posible que elijamos una función que resuelve nuestro problema pero no es portable, en cuyo caso aconsejaría evitarlas dentro de lo posible.&lt;br /&gt;
La utilización de la nueva Librería de Plantillas (STL) exige la asimilación de un nuevo paradigma;  una nueva forma de pensar que, si se tiene experiencia en programación tradicional, exige incluso un &amp;quot;cambio de chip&amp;quot;, ya que estas herramientas conforman un mundo enteramente nuevo y singular.&lt;br /&gt;
La STL ofrece un conjunto de recursos flexible, potente y altamente optimizado para resolver una gran variedad de situaciones de programación. Pero esta versatilidad y potencia tributan un precio: su alto grado de parametrización supone algo más que utilizar herramientas aisladas. Es necesario saber ensamblar entre sí los recursos disponibles, que no trabajan aisladamente y que son básicamente de tres tipos: contenedores, iteradores y algoritmos. El resultado es que el proceso de utilizar la STL es algo más complicado que la simple búsqueda de una función que resuelva nuestras necesidades;  que la curva de aprendizaje es ciertamente más ardua que en el caso de la librería clásica, y  que los conceptos involucrados son más abstractos y requieren un conocimiento más extenso de sus fundamentos para utilizarlos. Desde luego, la descripción detallada de todos sus elementos exige un libro completo, y de hecho son muchos los que se han publicado con el objeto exclusivo de describir la STL y/o sus técnicas de uso. En compensación, las contrapartidas obtenidas justifican sin duda el esfuerzo. El programador puede concentrarse más en el problema que en los detalles de su implementación en el fuente, se incremente la productividad y se gana en claridad conceptual.&lt;br /&gt;
== Funciones y macros ==&lt;br /&gt;
Algunas [[Función_(programación)| funciones]] pueden venir implementadas de dos formas: como macro y como función. Por ejemplo, la función isalnum, contenida en &amp;lt;ctype.h&amp;gt;.  Esto significa que además de estar implementada como una función en la correspondiente librería (que se utiliza con los argumentos señalados en el manual), está definida como una macro de preprocesado en &amp;lt;ctype.h&amp;gt;, de forma que salvo indicación contraria al compilador, el preprocesador transforma la llamada del programador en otra serie de sentencias equivalentes que utilizan los mismos argumentos. El resultado es que en el código resultante, que luego pasa al compilador y al enlazador, no existe nada parecido a una llamada a una función isalnum (técnicamente el proceso es una sustitución inline de la función de librería.&lt;br /&gt;
Para evitar que esto ocurra y por consiguiente que la llamada a islanum nunca llegue a producirse, basta con indefinir la correspondiente directiva. Esto se hace incluyendo al principio del código, y debajo de la línea #include &amp;lt;ctype.h&amp;gt;, una línea de preprocesado adecuada, en este caso:  #undef isalnum, con lo que el #define del preprocesador quedará sin efecto, con el resultado de que todas las invocaciones a isalnum de nuestro código serán respetadas por el preprocesador. Más tarde el enlazador cargará el código de isalnum (que extrae de la librería) con el resto de nuestro programa, y colocará en cada punto de nuestro código donde aparezca una invocación a isalnum, un salto a la dirección adecuada.&lt;br /&gt;
En estos casos, el resultado es el mismo en ambas modalidades: como macro (por defecto) o como función de librería. La elección de una u otra es cuestión de optimización. Para tomar una decisión es necesario comprobar y valorar dos aspectos:&lt;br /&gt;
•	El tamaño del ejecutable que resulta en uno y otro caso. Posiblemente mayor si se utiliza la función muchas veces y se adopta la macro.&lt;br /&gt;
•	La velocidad de ejecución. Posiblemente mayor si se utiliza la función muchas veces (en bucles muy largos) y se utiliza la macro.&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[Ciencia de la Información]]&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http:// www.zator.com/Cpp/E5.htm Librería Estándar C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Librería Estándar en C.conclase.net]&lt;br /&gt;
* [https://uvadoc.uva.es/bitstream/10324/17502/1/PID_15_156_Anexo4.pdf  Elementos de la librería estándar C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]] [[Category:Progr&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Librer%C3%ADa_Est%C3%A1ndar_C%2B%2B&amp;diff=3232310</id>
		<title>Librería Estándar C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Librer%C3%ADa_Est%C3%A1ndar_C%2B%2B&amp;diff=3232310"/>
		<updated>2018-11-27T15:57:29Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Librería Estándar C++ |imagen=  |concepto= Una librería es un conjunto de recursos (algoritmos) prefabricados, que pueden ser utilizados por el programador para realizar determinadas operaciones }}''' Librería Estándar C++ '''. [[C++|C++]] no llega al nivel de simplicidad de su antecesor C, pero al igual que aquél, tampoco dispone de utilidades o funciones para entrada o salida implementadas en el propio lenguaje, de modo que estas y otras muchas, como manejo de cadenas de caracteres (strings), manejo de ficheros, funciones matemáticas Etc. son implementadas en forma de librerías externas.&lt;br /&gt;
== Sinopsis ==&lt;br /&gt;
Una librería es un conjunto de recursos (algoritmos) prefabricados, que pueden ser utilizados por el programador para realizar determinadas operaciones. Las declaraciones de las funciones (prototipos) utilizadas en estas librerías, junto con algunas macros y constantes predefinidas que facilitan su utilización, se agrupan en ficheros de nombres conocidos que suelen encontrarse en sitios predefinidos. Por ejemplo, en los sistemas UNIX, en  /usr/include. Estos ficheros se suelen llamar &amp;quot;de cabecera&amp;quot;, porque es tradición utilizar las primeras líneas del programa para poner las directivas #include que los incluirá en el fuente durante la fase de preprocesado.&lt;br /&gt;
== Clases de librerías ==&lt;br /&gt;
Los [[Compilador|compiladores]] [[C++|C++]] incluyen un amplio repertorio de clases, funciones y macros que permiten realizar una amplia variedad de tareas, incluyendo entradas/salidas de bajo y alto nivel; manipulación de cadenas alfanuméricas y ficheros; control de procesos (incluyendo multiproceso); manejo de memoria; cálculos matemáticos y un largo etcétera.&lt;br /&gt;
Este repertorio de recursos es denominado colectivamente como &amp;quot;Rutinas de librería&amp;quot;; &amp;quot;Librerías de ejecución&amp;quot; RTL (&amp;quot;Runtime Librarys&amp;quot;) o simplemente &amp;quot;Librerías&amp;quot;.   Puede decirse que el lenguaje aislado (tal cual) no tiene prácticamente ninguna utilidad sin la concurrencia de estas utilidades. El Estándar C++ las clasifica según su utilidad:&lt;br /&gt;
•	Soporte del lenguaje&lt;br /&gt;
•	Diagnóstico&lt;br /&gt;
•	Utilidades generales&lt;br /&gt;
•	Cadenas alfanuméricas (&amp;quot;Strings&amp;quot;)&lt;br /&gt;
•	Localización&lt;br /&gt;
•	Contenedores&lt;br /&gt;
•	Iteradores&lt;br /&gt;
•	Algoritmos&lt;br /&gt;
•	Cálculo numérico&lt;br /&gt;
•	Entrada/Salida&lt;br /&gt;
=== Librería Estándar C++ ===&lt;br /&gt;
Para poner un poco de orden, el Estándar C++ define la denominada Librería Estándar que debe acompañar a cada implementación del compilador que se adhiera al estándar. Es decir: la norma determina cuales son, como se llaman y como se utiliza este conjunto de algoritmos que deben acompañar (como mínimo) a cada implementación del compilador que quiera llamarse &amp;quot;Estándar&amp;quot;. La última versión, ISO/IEC 14882 del año 1998, especifica que se compone de 32 ficheros de cabecera de nombres fijos y conocidos agrupados según la funcionalidad de los algoritmos. Son los siguientes: &lt;br /&gt;
Ficheros	Funcionalidad/funciones&lt;br /&gt;
&amp;lt;algorithm&amp;gt;	Parte de la STL que describe los algoritmos&lt;br /&gt;
&amp;lt;bitset&amp;gt;	Parte de la STL relativa a contenedores tipo bitset. Set de valores booleanos.&lt;br /&gt;
&amp;lt;complex&amp;gt;	Parte de la librería numérica de la STL relativa a los complejos .&lt;br /&gt;
&amp;lt;deque&amp;gt;	Parte de la STL relativa a contenedores tipo deque;  un tipo de colas: &amp;quot;Double-ended-queue&amp;quot; .&lt;br /&gt;
&amp;lt;exception&amp;gt;	Parte de la librería de diagnóstico relativa al manejo de excepciones&lt;br /&gt;
&amp;lt;fstream&amp;gt;	Flujos hacia/desde ficheros.&lt;br /&gt;
&amp;lt;functional&amp;gt;	Parte de la STL relativa a Objetos-función&lt;br /&gt;
&amp;lt;iomanip&amp;gt;	Manipuladores.&lt;br /&gt;
&amp;lt;ios&amp;gt;	Supreclases para manejo de flujos de E/S.&lt;br /&gt;
&amp;lt;iosfwd&amp;gt;	Contiene declaraciones adelantadas de todas las plantillas de flujos y sus typedefs estándar. Por ejemplo ostream.&lt;br /&gt;
&amp;lt;iostream&amp;gt;	Parte del a STL que contiene los algoritmos estándar de E/S.&lt;br /&gt;
&amp;lt;istream&amp;gt;	Algoritmos estándar de flujos de entrada.&lt;br /&gt;
&amp;lt;iterator&amp;gt;	Parte de la STL relacionada con iteradores, un tipo de puntero que permite utilizar los algoritmos de la Librería con las estructuras de datos representadas por los contenedores.&lt;br /&gt;
&amp;lt;limits&amp;gt;	Descripción de propiedades dependientes de la implementación que afectan a los tipos fundamentales.&lt;br /&gt;
&amp;lt;list&amp;gt;	Parte de la STL relativa a contenedores tipo list;  listas doblemente enlazadas&lt;br /&gt;
&amp;lt;locale&amp;gt;	Parte de la STL relativa a la internacionalización.&lt;br /&gt;
&amp;lt;map&amp;gt;	Parte de la STL relativa a contenedores tipo map.&lt;br /&gt;
&amp;lt;memory&amp;gt;	Utilidades relativas a la gestión de memoria, incluyendo asignadores  y punteros inteligentes (auto_ptr).&lt;br /&gt;
&amp;lt;new&amp;gt;	Manejo de memoria dinámica&lt;br /&gt;
&amp;lt;numeric&amp;gt;	Parte de la librería numérica de la STL relativa a operaciones numéricas.&lt;br /&gt;
&amp;lt;ostream&amp;gt;	Algoritmos estándar para los flujos de salida.&lt;br /&gt;
&amp;lt;queue&amp;gt;	Parte de la STL relativa a contenedores tipo queue;  colas de objetos.&lt;br /&gt;
&amp;lt;set&amp;gt;	Parte de la STL relativa a contenedores tipo set .&lt;br /&gt;
&amp;lt;sstream&amp;gt;	Flujos hacia/desde cadenas alfanuméricas.&lt;br /&gt;
&amp;lt;stack&amp;gt;	Parte de la STL relativa a contenedores tipo stack;  pilas de objetos.&lt;br /&gt;
&amp;lt;stdexcept&amp;gt;	Parte de la STL relativa a las clases de las que derivan los objetos lanzados por las excepciones ocasionadas en los algoritmos de la propia STL y otras expresiones.  Estas clases son utilizadas para reportar errores detectados durante runtime.  Los usuarios también pueden utilizar excepciones para reportar errores en sus propios programas.&lt;br /&gt;
&amp;lt;streambuf&amp;gt;	Parte de la STL relativa al Almacenamiento de flujos de E/S (&amp;quot;Stream buffers&amp;quot;).  Define los tipos que controlan la capa de transporte.&lt;br /&gt;
&amp;lt;string&amp;gt;	Parte de la STL relativa a contenedores tipo string;  una generalización de las cadenas alfanuméricas para albergar cadenas de objetos.&lt;br /&gt;
&amp;lt;typeinfo&amp;gt;	Mecanismo de identificación de tipos en tiempo de ejecución.&lt;br /&gt;
&amp;lt;utility&amp;gt;	Parte de la STL que contiene elementos auxiliares como [[Operadores|operadores]] y pares (pairs).&lt;br /&gt;
&amp;lt;valarray&amp;gt;	Parte de la librería numérica de la STL relativa a manejo de matrices numéricas&lt;br /&gt;
&amp;lt;vector&amp;gt;	Parte de la STL relativa a los contenedores tipo vector; una generalización de las matrices unidimensionales C/C++&lt;br /&gt;
&lt;br /&gt;
Es digno de mención que aunque generalmente las librerías no aportan ninguna característica al lenguaje (se supone que son utilidades auxiliares que no forman parte del lenguaje propiamente dicho), una pequeña porción de la Librería Estándar C++ sí aporta características que se consideran pertenecientes a este, de forma que deben estar presentes los ficheros de cabecera correspondientes si se desea usarlas. En concreto se refieren a los siguientes elementos:&lt;br /&gt;
•	[[Operadores|operadores]] new, new[], delete y delete[].&lt;br /&gt;
•	Clase type_info que corresponde al mecanismo RTTI de identificación de tipos en tiempo de ejecución representado por el operador typeid &lt;br /&gt;
•	Rutinas de inicio y terminación.&lt;br /&gt;
•	Las excepciones estándar lanzadas por los algoritmos anteriores&lt;br /&gt;
=== Librería C ===&lt;br /&gt;
Además de otras nuevas, cuyo diseño e importancia cambian drásticamente la filosofía del lenguaje, C++ incluye prácticamente la totalidad de [[Función_(programación)| funciones]] de la primitiva librería estándar C. A esta librería, mantenida por compatibilidad, la denominamos Librería clásica.&lt;br /&gt;
=== Otras librerías ===&lt;br /&gt;
Además de las que proporciona el estándar y las complementarias que pueda incluir por su cuenta el fabricante del compilador, en los proyectos reales se suelen utilizar infinidad de otras librerías, comerciales o públicas, que facilitan el trabajo en áreas particulares, y en este sentido, recordar que uno de los pecados que el programador novel debe evitar, es la tendencia a querer reinventar constantemente la rueda. De forma que el consejo es utilizar en lo posible librerías que estén probadas y sean fácilmente accesibles. Aunque hay que tener cuidado, porque determinados proyectos exigen que las librerías utilizadas estén perfectamente documentadas y en ciertos casos, que se cuente con los fuentes correspondientes.&lt;br /&gt;
== Componentes ==&lt;br /&gt;
Al referirnos a las librerías C++ utilizamos la terminología siguiente:&lt;br /&gt;
•	RTL  Conjunto de librerías que acompañan a un compilador (&amp;quot;Runtime Library&amp;quot;), sean o no estándar.&lt;br /&gt;
•	Librería Estándar. Conjunto de librerías cuyo contenido está definido por el Estándar C++ (abreviadamente LE)&lt;br /&gt;
•	Libería clásica. Parte de la Librería Estándar correspondiente al C clásico.&lt;br /&gt;
•	STL (&amp;quot;Standard Templete Library&amp;quot;). Parte de la LE genuina de C++ (que no es heredada de C) y que responde a la forma &amp;quot;++&amp;quot; de hacer las cosas.&lt;br /&gt;
La calidad de un compilador C++ viene determinada en gran medida por la calidad y cantidad de su RTL; por su grado de adherencia al Estándar  y por el grado de soporte que proporciona para la plataforma concreta a que se destina.&lt;br /&gt;
Nota: en lo que concierne a la programación para MS Windows (las referencias a la plataforma Wintel surgen de forma constante e inevitable), los [[Compilador|compiladores]] Borland C++ y MS Visual C++ son quizás los más conocidos y utilizados.  El primero incluye una completa librería denominada VCL (Visual Component Library. La del segundo es conocida como MFC (Microsoft Foundation Classes).&lt;br /&gt;
&lt;br /&gt;
Linux dispone de su propio compilador: GNU Cpp, que comenzó siendo un compilador C y ha evolucionado a un producto que es en realidad un superconjunto de compiladores. No solo puede compilar código C y C++;  también otros lenguajes como Ada o Fortran;  de forma que es común referirse a ellos como GCC (&amp;quot;GNU Compiler Collection&amp;quot;).  La buena noticia es que existen versiones de este compilador para plataformas Windows, de forma que incluso en este ambiente &amp;quot;Propietario&amp;quot; pueden realizarse desarrollos utilizando herramientas &amp;quot;Open source&amp;quot; &lt;br /&gt;
A grandes rasgos la librería Estándar C++ comprende los siguientes módulos:&lt;br /&gt;
•	La denominada Librería Estándar de Plantillas, abreviadamente STL (&amp;quot;Standard Templete Library&amp;quot;).&lt;br /&gt;
o	Librería numérica. Parte de la STL que contiene algoritmos especialmente concebidos para computación numérica. Por ejemplo, una clase valarray optimizada para matrices numéricas y una clase complex para manejo y representación estandarizada de números complejos (en realidad una plantilla con especializaciones para los tipos float, double y long double).&lt;br /&gt;
o	Utilidades. Parte de la STL dedicada a elementos auxiliares tales como adaptadores y la clase auto_ptr.&lt;br /&gt;
•	Unas utilidades de entrada/salida de flujos, denominadas genéricamente iostreams.&lt;br /&gt;
•	Una utilidad locale para manejo de localismos.&lt;br /&gt;
•	Una clase string para manejo estandarizado de cadenas de caracteres.  En realidad es una instanciación (especialización) de la plantilla basic_string para cadenas de caracteres. &lt;br /&gt;
•	Un esquema para describir de modo uniforme el entorno de ejecución mediante la utilización de una clase estándar denominada numeric_limits y especialización para cada uno de los tipos de datos fundamentales.&lt;br /&gt;
•	Utilidades para manejo de memoria.&lt;br /&gt;
•	Soporte para utilización de juegos de caracteres y signos de diversos idiomas.&lt;br /&gt;
•	Utilidades de diagnóstico y manejo de errores. Incluyen manejo de excepciones y la macro assert.&lt;br /&gt;
== Funcionalidad ==&lt;br /&gt;
Si atendemos a su funcionalidad,  las utilidades ofrecidas por la Librería Estándar pueden agruparse en:&lt;br /&gt;
•	Clasificación: Clasifican caracteres ASCII, como letras, caracteres de control (no imprimibles), Mayúsculas/minúsculas etc. Se definen en la cabecera &amp;lt;ctype.h&amp;gt;.&lt;br /&gt;
•	Entradas/Salidas de Consola: Estas son las denominadas entrada/salida estándar. Por defecto se refieren al teclado y a la pantalla (no pueden utilizarse directamente en aplicaciones de interfaz gráfica).&lt;br /&gt;
•	Conversión: Convierten caracteres y cadenas de caracteres desde formato alfabético a numérico de diversos tipos (float, int, long).  También realizan la conversión inversa: de formatos numéricos a representaciones alfabéticas y de mayúsculas a minúsculas y viceversa.&lt;br /&gt;
•	Diagnóstico: Son rutinas destinadas a comprobaciones; a descubrir y corregir posibles errores.&lt;br /&gt;
•	Directorio: Rutinas para manejo de directorios y sus direcciones (path names).&lt;br /&gt;
•	En linea (Inline): Rutinas para versiones inline de funciones. El compilador genera el código correspondiente para las versiones inline cuando se utiliza #pragma intrinsic o si se solicita optimización al compilador (optimización de tiempo de ejecución).&lt;br /&gt;
•	Entrada/Salida. Son rutinas que proporcionan manejo de flujos y operaciones de Entrada/Salida a bajo nivel (de Sistema Operativo).&lt;br /&gt;
•	Manipulación. Manejo de cadenas y bloques de memoria: copiar, comparar, convertir y buscar.&lt;br /&gt;
•	Matemáticas: Para realizar cálculos matemáticos.&lt;br /&gt;
•	De Memoria: Proporcionan asignación de memoria dinámica.&lt;br /&gt;
•	Miscelánea. Se agrupan aquí rutinas varias, como las que posibilitan saltos (goto) no locales y las que manejan diferencias de tipo cultural o de lenguaje. Por ejemplo representación de números, de moneda, formatos de fecha y hora, clasificación de tipo alfabético, etc.&lt;br /&gt;
•	Control de proceso. Rutinas que permiten invocar y terminar nuevos procesos desde otra rutina.&lt;br /&gt;
•	Fecha y hora. Incluyen rutinas para conversión y manipulación de variables de medida del tiempo (fecha y hora).&lt;br /&gt;
•	Argumentos variables. Rutinas utilizadas cuando se usan listas variables de argumentos, como en los casos de printf(), vscanf(), etc.&lt;br /&gt;
== Utilización ==&lt;br /&gt;
La utilización de la Librería Estándar C++ requiere de dos tipos de condiciones que podríamos describir como formales y conceptuales.&lt;br /&gt;
&lt;br /&gt;
1. En cuanto a las primeras (condiciones formales) y habida cuenta que las utilidades aparecen en forma de funciones, resulta evidente que su utilización exige incluirlas en nuestro programa. Para ello se necesitan tres pasos (en realidad las exigencias son las mismas que con cualquier otra función, la diferencia estriba en la forma en que se realizan los pasos b y c):&lt;br /&gt;
a:  Incluir en el código fuente las invocaciones a las [[Función_(programación)| funciones]] que estamos utilizando. Ejemplo:&lt;br /&gt;
printf(&amp;quot;Esto es una llamada a la función \&amp;quot;printf\&amp;quot; de librería\n&amp;quot;);&lt;br /&gt;
 b:  Incluir en el código fuente los prototipos de dichas funciones.&lt;br /&gt;
Puesto que los prototipos ya están incluidos en los ficheros estándar de cabecera, hay que indicar al compilador que los incluya. Esto se realiza poniendo en nuestro fuente (normalmente al principio) una directiva de preprocesado #include que señala el fichero de cabecera que se debe añadir. Por ejemplo, si el manual indica que la función printf está definida en el fichero de cabecera stdio.h ponemos en nuestro código:&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  c:  Incluir en el fuente las definiciones de las funciones utilizadas. Como alternativa se puede indicar al compilador que tales definiciones están en ficheros compilados previamente.&lt;br /&gt;
En este último caso se dice que las definiciones de las funciones están en librerías de las que existen dos tipos: estáticas (.LIB, .OBJ y .BPI) y dinámicas (.DLL). Toda la información que necesita el compilador está contenida en los ficheros de cabecera, por lo que las operaciones correspondientes son realizadas de forma automática; con la sola condición de que los ficheros y librerías correspondientes sean accesibles al enlazador.&lt;br /&gt;
&lt;br /&gt;
No olvidar que la entidades de la Librería Estándar C++ (que no están en ficheros de cabecera .h), se han definido en un espacio de nombres denominado std, por lo que es preciso referirse a él específicamente cuando se quieran utilizar estos recursos.&lt;br /&gt;
&lt;br /&gt;
2. Respecto a las que hemos denominado &amp;quot;condiciones conceptuales&amp;quot;, damos por sentado que la utilización de algoritmos de la Librería exige conocerlos. Pero debemos advertir que existe una gran diferencia entre las rutinas de la que hemos denominado librería clásica y los recursos de la nueva Librería Estándar de Plantillas STL.&lt;br /&gt;
En general los algoritmos contenidos en la librería clásica realizan tareas muy sencillas bajo la forma de funciones que, con un cierto número de argumentos, realizan la tarea encomendada. A veces devolviendo un objeto (que puede ser una estructura). Su utilización exige poco más que repasar esta colección de funciones (209 en la última versión del Estándar) hasta encontrar la que mejor se ajusta a nuestras necesidades. Para esto lo mejor es recurrir a la clasificación temática ofrecida en la documentación que acompaña a los compiladores antes que a la lista alfabética de las mismas. A continuación estudiamos atentamente su prototipo y la explicación de funcionamiento que acompaña el manual (eventualmente incluso con un ejemplo) y ya estamos listos para utilizarla. En el peor de los casos suelen bastar un par de pruebas hasta que conseguimos ajustar los argumentos de forma que se consiga el resultado esperado.&lt;br /&gt;
Como última recomendación al respecto, sobre todo si pensamos que nuestro programa tendrá una larga vida y/o pensamos portarlo a otras plataformas, aconsejaría echar un vistazo a la sección de &amp;quot;compatibilidad&amp;quot; que acompaña a la descripción de cada función en la documentación de la mayoría de compiladores. Suele ocurrir que el compilador ofrezca muchas más funciones que las estrictamente Estándar C++, y que estas no estén claramente separadas del resto, de forma que es posible que elijamos una función que resuelve nuestro problema pero no es portable, en cuyo caso aconsejaría evitarlas dentro de lo posible.&lt;br /&gt;
La utilización de la nueva Librería de Plantillas (STL) exige la asimilación de un nuevo paradigma;  una nueva forma de pensar que, si se tiene experiencia en programación tradicional, exige incluso un &amp;quot;cambio de chip&amp;quot;, ya que estas herramientas conforman un mundo enteramente nuevo y singular.&lt;br /&gt;
La STL ofrece un conjunto de recursos flexible, potente y altamente optimizado para resolver una gran variedad de situaciones de programación. Pero esta versatilidad y potencia tributan un precio: su alto grado de parametrización supone algo más que utilizar herramientas aisladas. Es necesario saber ensamblar entre sí los recursos disponibles, que no trabajan aisladamente y que son básicamente de tres tipos: contenedores, iteradores y algoritmos. El resultado es que el proceso de utilizar la STL es algo más complicado que la simple búsqueda de una función que resuelva nuestras necesidades;  que la curva de aprendizaje es ciertamente más ardua que en el caso de la librería clásica, y  que los conceptos involucrados son más abstractos y requieren un conocimiento más extenso de sus fundamentos para utilizarlos. Desde luego, la descripción detallada de todos sus elementos exige un libro completo, y de hecho son muchos los que se han publicado con el objeto exclusivo de describir la STL y/o sus técnicas de uso. En compensación, las contrapartidas obtenidas justifican sin duda el esfuerzo. El programador puede concentrarse más en el problema que en los detalles de su implementación en el fuente, se incremente la productividad y se gana en claridad conceptual.&lt;br /&gt;
== Funciones y macros ==&lt;br /&gt;
Algunas [[Función_(programación)| funciones]] pueden venir implementadas de dos formas: como macro y como función. Por ejemplo, la función isalnum, contenida en &amp;lt;ctype.h&amp;gt;.  Esto significa que además de estar implementada como una función en la correspondiente librería (que se utiliza con los argumentos señalados en el manual), está definida como una macro de preprocesado en &amp;lt;ctype.h&amp;gt;, de forma que salvo indicación contraria al compilador, el preprocesador transforma la llamada del programador en otra serie de sentencias equivalentes que utilizan los mismos argumentos. El resultado es que en el código resultante, que luego pasa al compilador y al enlazador, no existe nada parecido a una llamada a una función isalnum (técnicamente el proceso es una sustitución inline de la función de librería.&lt;br /&gt;
Para evitar que esto ocurra y por consiguiente que la llamada a islanum nunca llegue a producirse, basta con indefinir la correspondiente directiva. Esto se hace incluyendo al principio del código, y debajo de la línea #include &amp;lt;ctype.h&amp;gt;, una línea de preprocesado adecuada, en este caso:  #undef isalnum, con lo que el #define del preprocesador quedará sin efecto, con el resultado de que todas las invocaciones a isalnum de nuestro código serán respetadas por el preprocesador. Más tarde el enlazador cargará el código de isalnum (que extrae de la librería) con el resto de nuestro programa, y colocará en cada punto de nuestro código donde aparezca una invocación a isalnum, un salto a la dirección adecuada.&lt;br /&gt;
En estos casos, el resultado es el mismo en ambas modalidades: como macro (por defecto) o como función de librería. La elección de una u otra es cuestión de optimización. Para tomar una decisión es necesario comprobar y valorar dos aspectos:&lt;br /&gt;
•	El tamaño del ejecutable que resulta en uno y otro caso. Posiblemente mayor si se utiliza la función muchas veces y se adopta la macro.&lt;br /&gt;
•	La velocidad de ejecución. Posiblemente mayor si se utiliza la función muchas veces (en bucles muy largos) y se utiliza la macro.&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[Ciencia de la Información]]&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http:// www.zator.com/Cpp/E5.htm Librería Estándar C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Librería Estándar en C.conclase.net]&lt;br /&gt;
* [https://uvadoc.uva.es/bitstream/10324/17502/1/PID_15_156_Anexo4.pdf  Elementos de la librería estándar C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]] [[Category:Progr&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Librer%C3%ADa_Est%C3%A1ndar_C%2B%2B&amp;diff=3232306</id>
		<title>Librería Estándar C++</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Librer%C3%ADa_Est%C3%A1ndar_C%2B%2B&amp;diff=3232306"/>
		<updated>2018-11-27T15:54:53Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: Página creada con «&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Librería Estándar C++ |imagen=  |concepto= Una librería es un conjunto de recursos (algoritmos) prefabricados, que pueden ser...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Librería Estándar C++ |imagen=  |concepto= Una librería es un conjunto de recursos (algoritmos) prefabricados, que pueden ser utilizados por el programador para realizar determinadas operaciones }}''' Librería Estándar C++ '''. C++ no llega al nivel de simplicidad de su antecesor C, pero al igual que aquél, tampoco dispone de utilidades o funciones para entrada o salida implementadas en el propio lenguaje, de modo que estas y otras muchas, como manejo de cadenas de caracteres (strings), manejo de ficheros, funciones matemáticas Etc. son implementadas en forma de librerías externas.&lt;br /&gt;
== Sinopsis ==&lt;br /&gt;
Una librería es un conjunto de recursos (algoritmos) prefabricados, que pueden ser utilizados por el programador para realizar determinadas operaciones. Las declaraciones de las funciones (prototipos) utilizadas en estas librerías, junto con algunas macros y constantes predefinidas que facilitan su utilización, se agrupan en ficheros de nombres conocidos que suelen encontrarse en sitios predefinidos. Por ejemplo, en los sistemas UNIX, en  /usr/include. Estos ficheros se suelen llamar &amp;quot;de cabecera&amp;quot;, porque es tradición utilizar las primeras líneas del programa para poner las directivas #include que los incluirá en el fuente durante la fase de preprocesado.&lt;br /&gt;
== Clases de librerías ==&lt;br /&gt;
Los [[Compilador|compiladores]] C++ incluyen un amplio repertorio de clases, funciones y macros que permiten realizar una amplia variedad de tareas, incluyendo entradas/salidas de bajo y alto nivel; manipulación de cadenas alfanuméricas y ficheros; control de procesos (incluyendo multiproceso); manejo de memoria; cálculos matemáticos y un largo etcétera.&lt;br /&gt;
Este repertorio de recursos es denominado colectivamente como &amp;quot;Rutinas de librería&amp;quot;; &amp;quot;Librerías de ejecución&amp;quot; RTL (&amp;quot;Runtime Librarys&amp;quot;) o simplemente &amp;quot;Librerías&amp;quot;.   Puede decirse que el lenguaje aislado (tal cual) no tiene prácticamente ninguna utilidad sin la concurrencia de estas utilidades. El Estándar C++ las clasifica según su utilidad:&lt;br /&gt;
•	Soporte del lenguaje&lt;br /&gt;
•	Diagnóstico&lt;br /&gt;
•	Utilidades generales&lt;br /&gt;
•	Cadenas alfanuméricas (&amp;quot;Strings&amp;quot;)&lt;br /&gt;
•	Localización&lt;br /&gt;
•	Contenedores&lt;br /&gt;
•	Iteradores&lt;br /&gt;
•	Algoritmos&lt;br /&gt;
•	Cálculo numérico&lt;br /&gt;
•	Entrada/Salida&lt;br /&gt;
=== Librería Estándar C++ ===&lt;br /&gt;
Para poner un poco de orden, el Estándar C++ define la denominada Librería Estándar que debe acompañar a cada implementación del compilador que se adhiera al estándar. Es decir: la norma determina cuales son, como se llaman y como se utiliza este conjunto de algoritmos que deben acompañar (como mínimo) a cada implementación del compilador que quiera llamarse &amp;quot;Estándar&amp;quot;. La última versión, ISO/IEC 14882 del año 1998, especifica que se compone de 32 ficheros de cabecera de nombres fijos y conocidos agrupados según la funcionalidad de los algoritmos. Son los siguientes: &lt;br /&gt;
Ficheros	Funcionalidad/funciones&lt;br /&gt;
&amp;lt;algorithm&amp;gt;	Parte de la STL que describe los algoritmos&lt;br /&gt;
&amp;lt;bitset&amp;gt;	Parte de la STL relativa a contenedores tipo bitset. Set de valores booleanos.&lt;br /&gt;
&amp;lt;complex&amp;gt;	Parte de la librería numérica de la STL relativa a los complejos .&lt;br /&gt;
&amp;lt;deque&amp;gt;	Parte de la STL relativa a contenedores tipo deque;  un tipo de colas: &amp;quot;Double-ended-queue&amp;quot; .&lt;br /&gt;
&amp;lt;exception&amp;gt;	Parte de la librería de diagnóstico relativa al manejo de excepciones&lt;br /&gt;
&amp;lt;fstream&amp;gt;	Flujos hacia/desde ficheros.&lt;br /&gt;
&amp;lt;functional&amp;gt;	Parte de la STL relativa a Objetos-función&lt;br /&gt;
&amp;lt;iomanip&amp;gt;	Manipuladores.&lt;br /&gt;
&amp;lt;ios&amp;gt;	Supreclases para manejo de flujos de E/S.&lt;br /&gt;
&amp;lt;iosfwd&amp;gt;	Contiene declaraciones adelantadas de todas las plantillas de flujos y sus typedefs estándar. Por ejemplo ostream.&lt;br /&gt;
&amp;lt;iostream&amp;gt;	Parte del a STL que contiene los algoritmos estándar de E/S.&lt;br /&gt;
&amp;lt;istream&amp;gt;	Algoritmos estándar de flujos de entrada.&lt;br /&gt;
&amp;lt;iterator&amp;gt;	Parte de la STL relacionada con iteradores, un tipo de puntero que permite utilizar los algoritmos de la Librería con las estructuras de datos representadas por los contenedores.&lt;br /&gt;
&amp;lt;limits&amp;gt;	Descripción de propiedades dependientes de la implementación que afectan a los tipos fundamentales.&lt;br /&gt;
&amp;lt;list&amp;gt;	Parte de la STL relativa a contenedores tipo list;  listas doblemente enlazadas&lt;br /&gt;
&amp;lt;locale&amp;gt;	Parte de la STL relativa a la internacionalización.&lt;br /&gt;
&amp;lt;map&amp;gt;	Parte de la STL relativa a contenedores tipo map.&lt;br /&gt;
&amp;lt;memory&amp;gt;	Utilidades relativas a la gestión de memoria, incluyendo asignadores  y punteros inteligentes (auto_ptr).&lt;br /&gt;
&amp;lt;new&amp;gt;	Manejo de memoria dinámica&lt;br /&gt;
&amp;lt;numeric&amp;gt;	Parte de la librería numérica de la STL relativa a operaciones numéricas.&lt;br /&gt;
&amp;lt;ostream&amp;gt;	Algoritmos estándar para los flujos de salida.&lt;br /&gt;
&amp;lt;queue&amp;gt;	Parte de la STL relativa a contenedores tipo queue;  colas de objetos.&lt;br /&gt;
&amp;lt;set&amp;gt;	Parte de la STL relativa a contenedores tipo set .&lt;br /&gt;
&amp;lt;sstream&amp;gt;	Flujos hacia/desde cadenas alfanuméricas.&lt;br /&gt;
&amp;lt;stack&amp;gt;	Parte de la STL relativa a contenedores tipo stack;  pilas de objetos.&lt;br /&gt;
&amp;lt;stdexcept&amp;gt;	Parte de la STL relativa a las clases de las que derivan los objetos lanzados por las excepciones ocasionadas en los algoritmos de la propia STL y otras expresiones.  Estas clases son utilizadas para reportar errores detectados durante runtime.  Los usuarios también pueden utilizar excepciones para reportar errores en sus propios programas.&lt;br /&gt;
&amp;lt;streambuf&amp;gt;	Parte de la STL relativa al Almacenamiento de flujos de E/S (&amp;quot;Stream buffers&amp;quot;).  Define los tipos que controlan la capa de transporte.&lt;br /&gt;
&amp;lt;string&amp;gt;	Parte de la STL relativa a contenedores tipo string;  una generalización de las cadenas alfanuméricas para albergar cadenas de objetos.&lt;br /&gt;
&amp;lt;typeinfo&amp;gt;	Mecanismo de identificación de tipos en tiempo de ejecución.&lt;br /&gt;
&amp;lt;utility&amp;gt;	Parte de la STL que contiene elementos auxiliares como [[Operadores|operadores]] y pares (pairs).&lt;br /&gt;
&amp;lt;valarray&amp;gt;	Parte de la librería numérica de la STL relativa a manejo de matrices numéricas&lt;br /&gt;
&amp;lt;vector&amp;gt;	Parte de la STL relativa a los contenedores tipo vector; una generalización de las matrices unidimensionales C/C++&lt;br /&gt;
&lt;br /&gt;
Es digno de mención que aunque generalmente las librerías no aportan ninguna característica al lenguaje (se supone que son utilidades auxiliares que no forman parte del lenguaje propiamente dicho), una pequeña porción de la Librería Estándar C++ sí aporta características que se consideran pertenecientes a este, de forma que deben estar presentes los ficheros de cabecera correspondientes si se desea usarlas. En concreto se refieren a los siguientes elementos:&lt;br /&gt;
•	[[Operadores|operadores]] new, new[], delete y delete[].&lt;br /&gt;
•	Clase type_info que corresponde al mecanismo RTTI de identificación de tipos en tiempo de ejecución representado por el operador typeid &lt;br /&gt;
•	Rutinas de inicio y terminación.&lt;br /&gt;
•	Las excepciones estándar lanzadas por los algoritmos anteriores&lt;br /&gt;
=== Librería C ===&lt;br /&gt;
Además de otras nuevas, cuyo diseño e importancia cambian drásticamente la filosofía del lenguaje, C++ incluye prácticamente la totalidad de [[Función_(programación)| funciones]] de la primitiva librería estándar C. A esta librería, mantenida por compatibilidad, la denominamos Librería clásica.&lt;br /&gt;
=== Otras librerías ===&lt;br /&gt;
Además de las que proporciona el estándar y las complementarias que pueda incluir por su cuenta el fabricante del compilador, en los proyectos reales se suelen utilizar infinidad de otras librerías, comerciales o públicas, que facilitan el trabajo en áreas particulares, y en este sentido, recordar que uno de los pecados que el programador novel debe evitar, es la tendencia a querer reinventar constantemente la rueda. De forma que el consejo es utilizar en lo posible librerías que estén probadas y sean fácilmente accesibles. Aunque hay que tener cuidado, porque determinados proyectos exigen que las librerías utilizadas estén perfectamente documentadas y en ciertos casos, que se cuente con los fuentes correspondientes.&lt;br /&gt;
== Componentes ==&lt;br /&gt;
Al referirnos a las librerías C++ utilizamos la terminología siguiente:&lt;br /&gt;
•	RTL  Conjunto de librerías que acompañan a un compilador (&amp;quot;Runtime Library&amp;quot;), sean o no estándar.&lt;br /&gt;
•	Librería Estándar. Conjunto de librerías cuyo contenido está definido por el Estándar C++ (abreviadamente LE)&lt;br /&gt;
•	Libería clásica. Parte de la Librería Estándar correspondiente al C clásico.&lt;br /&gt;
•	STL (&amp;quot;Standard Templete Library&amp;quot;). Parte de la LE genuina de C++ (que no es heredada de C) y que responde a la forma &amp;quot;++&amp;quot; de hacer las cosas.&lt;br /&gt;
La calidad de un compilador C++ viene determinada en gran medida por la calidad y cantidad de su RTL; por su grado de adherencia al Estándar  y por el grado de soporte que proporciona para la plataforma concreta a que se destina.&lt;br /&gt;
Nota: en lo que concierne a la programación para MS Windows (las referencias a la plataforma Wintel surgen de forma constante e inevitable), los [[Compilador|compiladores]] Borland C++ y MS Visual C++ son quizás los más conocidos y utilizados.  El primero incluye una completa librería denominada VCL (Visual Component Library. La del segundo es conocida como MFC (Microsoft Foundation Classes).&lt;br /&gt;
&lt;br /&gt;
Linux dispone de su propio compilador: GNU Cpp, que comenzó siendo un compilador C y ha evolucionado a un producto que es en realidad un superconjunto de compiladores. No solo puede compilar código C y C++;  también otros lenguajes como Ada o Fortran;  de forma que es común referirse a ellos como GCC (&amp;quot;GNU Compiler Collection&amp;quot;).  La buena noticia es que existen versiones de este compilador para plataformas Windows, de forma que incluso en este ambiente &amp;quot;Propietario&amp;quot; pueden realizarse desarrollos utilizando herramientas &amp;quot;Open source&amp;quot; &lt;br /&gt;
A grandes rasgos la librería Estándar C++ comprende los siguientes módulos:&lt;br /&gt;
•	La denominada Librería Estándar de Plantillas, abreviadamente STL (&amp;quot;Standard Templete Library&amp;quot;).&lt;br /&gt;
o	Librería numérica. Parte de la STL que contiene algoritmos especialmente concebidos para computación numérica. Por ejemplo, una clase valarray optimizada para matrices numéricas y una clase complex para manejo y representación estandarizada de números complejos (en realidad una plantilla con especializaciones para los tipos float, double y long double).&lt;br /&gt;
o	Utilidades. Parte de la STL dedicada a elementos auxiliares tales como adaptadores y la clase auto_ptr.&lt;br /&gt;
•	Unas utilidades de entrada/salida de flujos, denominadas genéricamente iostreams.&lt;br /&gt;
•	Una utilidad locale para manejo de localismos.&lt;br /&gt;
•	Una clase string para manejo estandarizado de cadenas de caracteres.  En realidad es una instanciación (especialización) de la plantilla basic_string para cadenas de caracteres. &lt;br /&gt;
•	Un esquema para describir de modo uniforme el entorno de ejecución mediante la utilización de una clase estándar denominada numeric_limits y especialización para cada uno de los tipos de datos fundamentales.&lt;br /&gt;
•	Utilidades para manejo de memoria.&lt;br /&gt;
•	Soporte para utilización de juegos de caracteres y signos de diversos idiomas.&lt;br /&gt;
•	Utilidades de diagnóstico y manejo de errores. Incluyen manejo de excepciones y la macro assert.&lt;br /&gt;
== Funcionalidad ==&lt;br /&gt;
Si atendemos a su funcionalidad,  las utilidades ofrecidas por la Librería Estándar pueden agruparse en:&lt;br /&gt;
•	Clasificación: Clasifican caracteres ASCII, como letras, caracteres de control (no imprimibles), Mayúsculas/minúsculas etc. Se definen en la cabecera &amp;lt;ctype.h&amp;gt;.&lt;br /&gt;
•	Entradas/Salidas de Consola: Estas son las denominadas entrada/salida estándar. Por defecto se refieren al teclado y a la pantalla (no pueden utilizarse directamente en aplicaciones de interfaz gráfica).&lt;br /&gt;
•	Conversión: Convierten caracteres y cadenas de caracteres desde formato alfabético a numérico de diversos tipos (float, int, long).  También realizan la conversión inversa: de formatos numéricos a representaciones alfabéticas y de mayúsculas a minúsculas y viceversa.&lt;br /&gt;
•	Diagnóstico: Son rutinas destinadas a comprobaciones; a descubrir y corregir posibles errores.&lt;br /&gt;
•	Directorio: Rutinas para manejo de directorios y sus direcciones (path names).&lt;br /&gt;
•	En linea (Inline): Rutinas para versiones inline de funciones. El compilador genera el código correspondiente para las versiones inline cuando se utiliza #pragma intrinsic o si se solicita optimización al compilador (optimización de tiempo de ejecución).&lt;br /&gt;
•	Entrada/Salida. Son rutinas que proporcionan manejo de flujos y operaciones de Entrada/Salida a bajo nivel (de Sistema Operativo).&lt;br /&gt;
•	Manipulación. Manejo de cadenas y bloques de memoria: copiar, comparar, convertir y buscar.&lt;br /&gt;
•	Matemáticas: Para realizar cálculos matemáticos.&lt;br /&gt;
•	De Memoria: Proporcionan asignación de memoria dinámica.&lt;br /&gt;
•	Miscelánea. Se agrupan aquí rutinas varias, como las que posibilitan saltos (goto) no locales y las que manejan diferencias de tipo cultural o de lenguaje. Por ejemplo representación de números, de moneda, formatos de fecha y hora, clasificación de tipo alfabético, etc.&lt;br /&gt;
•	Control de proceso. Rutinas que permiten invocar y terminar nuevos procesos desde otra rutina.&lt;br /&gt;
•	Fecha y hora. Incluyen rutinas para conversión y manipulación de variables de medida del tiempo (fecha y hora).&lt;br /&gt;
•	Argumentos variables. Rutinas utilizadas cuando se usan listas variables de argumentos, como en los casos de printf(), vscanf(), etc.&lt;br /&gt;
== Utilización ==&lt;br /&gt;
La utilización de la Librería Estándar C++ requiere de dos tipos de condiciones que podríamos describir como formales y conceptuales.&lt;br /&gt;
&lt;br /&gt;
1. En cuanto a las primeras (condiciones formales) y habida cuenta que las utilidades aparecen en forma de funciones, resulta evidente que su utilización exige incluirlas en nuestro programa. Para ello se necesitan tres pasos (en realidad las exigencias son las mismas que con cualquier otra función, la diferencia estriba en la forma en que se realizan los pasos b y c):&lt;br /&gt;
a:  Incluir en el código fuente las invocaciones a las [[Función_(programación)| funciones]] que estamos utilizando. Ejemplo:&lt;br /&gt;
printf(&amp;quot;Esto es una llamada a la función \&amp;quot;printf\&amp;quot; de librería\n&amp;quot;);&lt;br /&gt;
 b:  Incluir en el código fuente los prototipos de dichas funciones.&lt;br /&gt;
Puesto que los prototipos ya están incluidos en los ficheros estándar de cabecera, hay que indicar al compilador que los incluya. Esto se realiza poniendo en nuestro fuente (normalmente al principio) una directiva de preprocesado #include que señala el fichero de cabecera que se debe añadir. Por ejemplo, si el manual indica que la función printf está definida en el fichero de cabecera stdio.h ponemos en nuestro código:&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
  c:  Incluir en el fuente las definiciones de las funciones utilizadas. Como alternativa se puede indicar al compilador que tales definiciones están en ficheros compilados previamente.&lt;br /&gt;
En este último caso se dice que las definiciones de las funciones están en librerías de las que existen dos tipos: estáticas (.LIB, .OBJ y .BPI) y dinámicas (.DLL). Toda la información que necesita el compilador está contenida en los ficheros de cabecera, por lo que las operaciones correspondientes son realizadas de forma automática; con la sola condición de que los ficheros y librerías correspondientes sean accesibles al enlazador.&lt;br /&gt;
&lt;br /&gt;
No olvidar que la entidades de la Librería Estándar C++ (que no están en ficheros de cabecera .h), se han definido en un espacio de nombres denominado std, por lo que es preciso referirse a él específicamente cuando se quieran utilizar estos recursos.&lt;br /&gt;
&lt;br /&gt;
2. Respecto a las que hemos denominado &amp;quot;condiciones conceptuales&amp;quot;, damos por sentado que la utilización de algoritmos de la Librería exige conocerlos. Pero debemos advertir que existe una gran diferencia entre las rutinas de la que hemos denominado librería clásica y los recursos de la nueva Librería Estándar de Plantillas STL.&lt;br /&gt;
En general los algoritmos contenidos en la librería clásica realizan tareas muy sencillas bajo la forma de funciones que, con un cierto número de argumentos, realizan la tarea encomendada. A veces devolviendo un objeto (que puede ser una estructura). Su utilización exige poco más que repasar esta colección de funciones (209 en la última versión del Estándar) hasta encontrar la que mejor se ajusta a nuestras necesidades. Para esto lo mejor es recurrir a la clasificación temática ofrecida en la documentación que acompaña a los compiladores antes que a la lista alfabética de las mismas. A continuación estudiamos atentamente su prototipo y la explicación de funcionamiento que acompaña el manual (eventualmente incluso con un ejemplo) y ya estamos listos para utilizarla. En el peor de los casos suelen bastar un par de pruebas hasta que conseguimos ajustar los argumentos de forma que se consiga el resultado esperado.&lt;br /&gt;
Como última recomendación al respecto, sobre todo si pensamos que nuestro programa tendrá una larga vida y/o pensamos portarlo a otras plataformas, aconsejaría echar un vistazo a la sección de &amp;quot;compatibilidad&amp;quot; que acompaña a la descripción de cada función en la documentación de la mayoría de compiladores. Suele ocurrir que el compilador ofrezca muchas más funciones que las estrictamente Estándar C++, y que estas no estén claramente separadas del resto, de forma que es posible que elijamos una función que resuelve nuestro problema pero no es portable, en cuyo caso aconsejaría evitarlas dentro de lo posible.&lt;br /&gt;
La utilización de la nueva Librería de Plantillas (STL) exige la asimilación de un nuevo paradigma;  una nueva forma de pensar que, si se tiene experiencia en programación tradicional, exige incluso un &amp;quot;cambio de chip&amp;quot;, ya que estas herramientas conforman un mundo enteramente nuevo y singular.&lt;br /&gt;
La STL ofrece un conjunto de recursos flexible, potente y altamente optimizado para resolver una gran variedad de situaciones de programación. Pero esta versatilidad y potencia tributan un precio: su alto grado de parametrización supone algo más que utilizar herramientas aisladas. Es necesario saber ensamblar entre sí los recursos disponibles, que no trabajan aisladamente y que son básicamente de tres tipos: contenedores, iteradores y algoritmos. El resultado es que el proceso de utilizar la STL es algo más complicado que la simple búsqueda de una función que resuelva nuestras necesidades;  que la curva de aprendizaje es ciertamente más ardua que en el caso de la librería clásica, y  que los conceptos involucrados son más abstractos y requieren un conocimiento más extenso de sus fundamentos para utilizarlos. Desde luego, la descripción detallada de todos sus elementos exige un libro completo, y de hecho son muchos los que se han publicado con el objeto exclusivo de describir la STL y/o sus técnicas de uso. En compensación, las contrapartidas obtenidas justifican sin duda el esfuerzo. El programador puede concentrarse más en el problema que en los detalles de su implementación en el fuente, se incremente la productividad y se gana en claridad conceptual.&lt;br /&gt;
== Funciones y macros ==&lt;br /&gt;
Algunas [[Función_(programación)| funciones]] pueden venir implementadas de dos formas: como macro y como función. Por ejemplo, la función isalnum, contenida en &amp;lt;ctype.h&amp;gt;.  Esto significa que además de estar implementada como una función en la correspondiente librería (que se utiliza con los argumentos señalados en el manual), está definida como una macro de preprocesado en &amp;lt;ctype.h&amp;gt;, de forma que salvo indicación contraria al compilador, el preprocesador transforma la llamada del programador en otra serie de sentencias equivalentes que utilizan los mismos argumentos. El resultado es que en el código resultante, que luego pasa al compilador y al enlazador, no existe nada parecido a una llamada a una función isalnum (técnicamente el proceso es una sustitución inline de la función de librería.&lt;br /&gt;
Para evitar que esto ocurra y por consiguiente que la llamada a islanum nunca llegue a producirse, basta con indefinir la correspondiente directiva. Esto se hace incluyendo al principio del código, y debajo de la línea #include &amp;lt;ctype.h&amp;gt;, una línea de preprocesado adecuada, en este caso:  #undef isalnum, con lo que el #define del preprocesador quedará sin efecto, con el resultado de que todas las invocaciones a isalnum de nuestro código serán respetadas por el preprocesador. Más tarde el enlazador cargará el código de isalnum (que extrae de la librería) con el resto de nuestro programa, y colocará en cada punto de nuestro código donde aparezca una invocación a isalnum, un salto a la dirección adecuada.&lt;br /&gt;
En estos casos, el resultado es el mismo en ambas modalidades: como macro (por defecto) o como función de librería. La elección de una u otra es cuestión de optimización. Para tomar una decisión es necesario comprobar y valorar dos aspectos:&lt;br /&gt;
•	El tamaño del ejecutable que resulta en uno y otro caso. Posiblemente mayor si se utiliza la función muchas veces y se adopta la macro.&lt;br /&gt;
•	La velocidad de ejecución. Posiblemente mayor si se utiliza la función muchas veces (en bucles muy largos) y se utiliza la macro.&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[Ciencia de la Información]]&lt;br /&gt;
*[[C++]]&lt;br /&gt;
*[[Puntero (C++)]]&lt;br /&gt;
*[[Constructor (C++)]]&lt;br /&gt;
*[[Ficheros en C++]]&lt;br /&gt;
*[[Programación de Computadoras]]&lt;br /&gt;
*[[Programación Orientada a Objetos]]&lt;br /&gt;
*[[Lenguaje de Programación C Sharp|Programación C Sharp]]&lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
*[[Code_Blocks]]&lt;br /&gt;
*[[Operadores|Operadores]] &lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Ámbito (Programación)|Ámbito (Programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Historia del Lenguaje C]]&lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://http:// www.zator.com/Cpp/E5.htm Librería Estándar C++]&lt;br /&gt;
* [http://c.conclase.net/curso/index.php  Librería Estándar en C.conclase.net]&lt;br /&gt;
* [https://uvadoc.uva.es/bitstream/10324/17502/1/PID_15_156_Anexo4.pdf  Elementos de la librería estándar C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]] [[Category:Progr&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Funciones_virtuales&amp;diff=3024830</id>
		<title>Funciones virtuales</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Funciones_virtuales&amp;diff=3024830"/>
		<updated>2017-12-12T18:17:49Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Funciones virtuales |imagen=   |concepto=&lt;br /&gt;
Las funciones virtuales permiten que clases derivadas de una misma base (clases hermanas) puedan tener diferentes versiones de un método. Se utiliza la palabra-clave virtual para avisar al compilador que un método será polimórfico y que en las clases derivadas existen distintas definiciones del mismo}}&lt;br /&gt;
''' Funciones virtuales '''. Las funciones virtuales permiten que clases derivadas de una misma base (clases hermanas) puedan tener diferentes versiones de un método. Se utiliza la palabra-clave virtual para avisar al compilador que un método será polimórfico y que en las clases derivadas existen distintas definiciones del mismo. En respuesta, el &amp;quot;Linker&amp;quot; utiliza para ella una técnica especial, enlazado retrasado. La declaración de virtual en un método de una clase, implica que esta es polimórfica, y que probablemente no se utilizará directamente para instanciar objetos, sino como super-clase de una jerarquía.&lt;br /&gt;
&lt;br /&gt;
Esta posibilidad, que un mismo método puede exhibir distintos comportamientos en los descendientes de una base común, es precisamente lo que posibilita y define el polimorfismo. En estos casos se dice que las descendientes de la función virtual solapan o sobrecontrolan (&amp;quot;Override&amp;quot;) la versión de la superclase, pero esta versión de la superclase puede no existir en absoluto. Es probable que en ella solo exista una declaración del tipo: vitual void foo(); sin que exista una definición de la misma. Para que pueda existir la declaración de un método sin que exista la definición correspondiente, el método debe ser virtual puro  (un tipo particular dentro de los virtuales).&lt;br /&gt;
&lt;br /&gt;
Utilizaremos la siguiente terminología:  &amp;quot;función sobrecontrolada&amp;quot; o &amp;quot;solapada&amp;quot;, para referirnos a la versión en la superclase y &amp;quot;función sobrecontroladora&amp;quot; o &amp;quot;que solapa&amp;quot; para referirnos a la nueva versión en la clase derivada. Cualquier referencia al sobrecontrol o solapamiento (&amp;quot;Overriding&amp;quot;) indica que se está utilizando el mecanismo C++ de las funciones virtuales. Parecido pero no idéntico al de sobrecarga; conviene no confundir ambos conceptos. Más adelante intentamos aclarar sus diferencias .&lt;br /&gt;
== Sintaxis ==&lt;br /&gt;
Para declarar que un método de una clase base es virtual, su prototipo se declara como siempre, pero anteponiendo la palabra-clave virtual, que indica al compilador algo así como: &amp;quot;Será definido más tarde en una clase derivada&amp;quot;. Ejemplo:&lt;br /&gt;
virtual void dibujar();&lt;br /&gt;
Cuando se aplica a métodos de clase, el especificador virtual debe ser utilizado en la declaración, pero no en la definición si esta se realiza offline (fuera del cuerpo de la clase). Ejemplo:&lt;br /&gt;
class CL {&lt;br /&gt;
  ...&lt;br /&gt;
  virtual void func1();&lt;br /&gt;
  virtual void func2();&lt;br /&gt;
  virtual void func3() { ... }    // Ok. definición inline&lt;br /&gt;
};&lt;br /&gt;
virtual void CL::func1() { ... }  // Error!!&lt;br /&gt;
void CL::func2() { ... }          // Ok. definición offline&lt;br /&gt;
== Descripción ==&lt;br /&gt;
Al tratar del enlazado se indicaron las causas que justifican la existencia de este tipo de funciones en los lenguajes orientados a objeto (que aconsejamos repasar ahora. Para ayudarnos a comprender el problema que se pretende resolver con este tipo de funciones, exponemos una continuación del ejemplo de la clase Poligono al que nos referimos al tratar de las clases polimórficas:&lt;br /&gt;
&lt;br /&gt;
class Color { public: int R, G, B; };   // clase auxiliar&lt;br /&gt;
class Punto { public: float x, y; };    // clase auxiliar&lt;br /&gt;
&lt;br /&gt;
class Poligono {        // clase-base (polimórfica)&lt;br /&gt;
  protected:            // interfaz para las clases derivadas&lt;br /&gt;
  Punto centro;&lt;br /&gt;
  Color col;&lt;br /&gt;
  ...&lt;br /&gt;
  public:               // interfaz para los usuarios de poligonos&lt;br /&gt;
  virtual void dibujar() const;&lt;br /&gt;
  virtual void rotar(int grados);&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class Circulo : public Poligono {       // Un tipo de polígono&lt;br /&gt;
  protected:&lt;br /&gt;
  int radio;&lt;br /&gt;
  ...&lt;br /&gt;
  public:&lt;br /&gt;
  void dibujar() const;&lt;br /&gt;
  void rotar(int) { }&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class Triangulo : public Poligono {     // Otro tipo de pológono&lt;br /&gt;
  protected:&lt;br /&gt;
  Punto a, b, c;&lt;br /&gt;
  ...&lt;br /&gt;
  public:&lt;br /&gt;
  void dibujar() const;&lt;br /&gt;
  void rotar(int);&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Lo que se pretende con este tipo de jerarquía es que los usuarios de subclases manejen los distintos polígonos a través de su interfaz pública (sus miembros públicos), mientras que los implementadores (creadores de los diversos tipos de polígonos que puedan existir en la aplicación), compartan los aspectos representados por los miembros protegidos.&lt;br /&gt;
Los miembros protegidos son utilizados también para aquellos aspectos que son dependientes de la implementación. Por ejemplo, aunque la propiedad color será compartida por todas las clases de polígonos, posiblemente su definición dependa de aspectos concretos de la implementación, es decir, del concepto de &amp;quot;color&amp;quot; del sistema operativo, que probablemente estará en definiciones en ficheros de cabecera.&lt;br /&gt;
Los miembros en la superclase (polimórfica) representan las partes que son comunes a todos los miembros (a todos los polígonos) pero en la mayoría de los casos no es sencillo decidir cuáles serán estos miembros (propiedades o métodos) compartidos por todas las clases derivadas. Por ejemplo, aunque se puede definir un centro para cualquier polígono, mantener su valor puede ser una molestia innecesaria en la mayoría de los polígonos y sobre todo en los triángulos, mientras es imprescindible en los círculos y muy útil en el resto de polígonos equiláteros.&lt;br /&gt;
=== Ejemplo ===&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {                 // L.4:  Clase-base&lt;br /&gt;
  public: virtual int fun(int x) {return x * x;}   // L.5 virtual&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {     // Clase derivada-1&lt;br /&gt;
  public:  int fun (int x) {return x + 10;}        // L.8 virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {     // Clase derivada-2&lt;br /&gt;
  public:  int fun (int x) {return x + 15;}        // L.11 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {          // =========&lt;br /&gt;
  B b; D1 d1; D2 d2;      // M.1&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; b.fun(10)     &amp;lt;&amp;lt; endl;  // M.2:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.fun(10)    &amp;lt;&amp;lt; endl;  // M.3:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.fun(10)    &amp;lt;&amp;lt; endl;  // M.4:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.B::fun(10) &amp;lt;&amp;lt; endl;  // M.5:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.B::fun(10) &amp;lt;&amp;lt; endl;  // M.6:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
Comentario&lt;br /&gt;
Definimos una clase-base B, en la que definimos una función virtual fun; a continuación derivamos de ella dos subclases D1 y D2, en las que definimos sendas versiones de fun que solapan la versión existente en la clase-base.&lt;br /&gt;
Las versiones de fun en L.8 y L.11 son virtuales, a pesar de no tener el declarador virtual indicado explícitamente. Estas versiones son un caso de polimorfismo, y solapan a la versión definida en la clase-base.&lt;br /&gt;
La línea M.1 instancia tres objetos de las clases anteriormente definidas.  En las líneas M.2 a M.4 comprobamos sus valores, que son los esperados (en cada caso se ha utilizado la versión de fun adecuada al objeto correspondiente).  Observe que la elección de la función adecuada no se realiza por el análisis de los argumentos pasados a la función como en el caso de la sobrecarga (aquí los argumentos son iguales en todos los casos), sino por la &amp;quot;naturaleza&amp;quot; del objeto que invoca la función;  esta es precisamente la característica distintiva del del polimorfismo.&lt;br /&gt;
Las líneas M.5 y M.6 sirven para recordarnos que a pesar del solapamiento, la versión de fun de la superclase sigue existiendo, y es accesible en los objetos de las clases derivadas utilizando el sobrecontrol adecuado.&lt;br /&gt;
Nota: la utilización del operador :: de acceso a ámbito anula el mecanismo de funciones virtuales, pero es aconsejable no usarlo en demasía, pues conduce a programas más difíciles de mantener. Como regla general, este tipo de calificación solo debe utilizarse para acceder a miembros del subobjeto heredado como es el caso del ejemplo.&lt;br /&gt;
Ejemplo-2&lt;br /&gt;
Hagamos ahora de abogados del diablo compilando el ejemplo anterior con la única modificación de que el método fun de B no sea virtual, sino un método normal. Es decir, la sentencia L.5, quedaría como:&lt;br /&gt;
public: int fun(int x) {return x * x;}    // L.5b no virtual!!&lt;br /&gt;
En este caso, comprobamos que el resultado coincide exactamente con el anterior, lo que nos induciría a preguntar ¿Para qué diablos sirven entonces las funciones virtuales?&lt;br /&gt;
Ejemplo-3&lt;br /&gt;
La explicación podemos encontrala fácilmente mediante una pequeña modificación en el programa: en vez de acceder directamente a los miembros de los objetos utilizando el selector directo de miembro, en las sentencias de salida, realizaremos el acceso mediante punteros a las clases correspondientes. De estos punteros declararemos dos tipos: a la superclase y a las clases derivadas (por brevedad hemos suprimido las sentencias de comprobación M.5 y M.6).&lt;br /&gt;
El nuevo diseño sería el siguiente:&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {                 // L.4: Clase-base&lt;br /&gt;
  public: virtual int fun(int x) {return x * x;}  // L.5 virtual&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {     // Clase derivada-1&lt;br /&gt;
  public: int fun (int x) {return x + 10;}        // L.8 virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {     // Clase derivada-2&lt;br /&gt;
  public: int fun (int x) {return x + 15;}        // L.11 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {          // =========&lt;br /&gt;
  B b; D1 d1; D2 d2;      // M.1&lt;br /&gt;
  B* bp = &amp;amp;b; B* bp1 = &amp;amp;d1; B* bp2 = &amp;amp;d2;           // M.1a&lt;br /&gt;
  D1* d1p = &amp;amp;d1; D2* d2p = &amp;amp;d2;                     // M.1b&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;   // M.2a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp1-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.3a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp2-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.3b:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1p-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.4a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2p-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.4b:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
Comentario&lt;br /&gt;
La sentencia M.1a define tres punteros a la clase-base. No obstante, dos de ellos se utilizan para señalar objetos de las sub-clases. Esto es típico de los punteros en jerarquías de clases. Precisamente se introdujo esta &amp;quot;relajación&amp;quot; en el control de tipos, para facilitar ciertas funcionalidades de las clases polimórficas.&lt;br /&gt;
La sentencia M.1b define sendos punteros a subclase, que en este caso si son aplicados a entidades de su mismo tipo.&lt;br /&gt;
Teniendo en cuenta las modificaciones efectuadas, y como no podía ser menos, las nuevas salidas son exactamente análogas a las del ejemplo inicial.&lt;br /&gt;
Ejemplo-4&lt;br /&gt;
Si suprimimos la declaración de virtual para la sentencia L.5 y volvemos a compilar el programa, se obtienen los resultados siguientes:&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
En ausencia de enlazado retrasado, las sentencias M.3a y M.3b, que acceden a métodos de objetos a través de punteros a la superclase, se refieren a los métodos heredados (que se definieron en la superclase). En este contexto pueden considerarse equivalentes los siguientes pares de expresiones:&lt;br /&gt;
bp1-&amp;gt;fun(10)  ==  d1.B::fun(10)&lt;br /&gt;
bp2-&amp;gt;fun(10)  ==  d2.B::fun(10)&lt;br /&gt;
&lt;br /&gt;
Hay ocasiones es que este comportamiento no interesa. Precisamente en las clases abstractas, en las que la definición de B::fun() no existe en absoluto, y expresiones como M.3a y M.3b conducirían a error si fun() no fuese declarada virtual pura en B.&lt;br /&gt;
Ejemplo-5&lt;br /&gt;
Presentamos una variación muy interesante del primer ejemplo, en el que simplemente hemos eliminado la línea 11, de forma que no existe definición específica de fun en la subclase D2.&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {                 // L.4:  Clase-base&lt;br /&gt;
  public:  virtual int fun(int x) {return x * x;}   // L.5 virtual&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {     // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 10;}         // L.8 virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B { };  // Clase derivada&lt;br /&gt;
&lt;br /&gt;
int main(void) {          // =========&lt;br /&gt;
  B b; D1 d1; D2 d2;      // M.1&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; b.fun(10)     &amp;lt;&amp;lt; endl;  // M.2:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.fun(10)    &amp;lt;&amp;lt; endl;  // M.3:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.fun(10)    &amp;lt;&amp;lt; endl;  // M.4:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.B::fun(10) &amp;lt;&amp;lt; endl;  // M.5:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.B::fun(10) &amp;lt;&amp;lt; endl;  // M.6:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
Comentario&lt;br /&gt;
El objeto d2 no dispone ahora de una definición específica de la función virtual fun, por lo que cualquier invocación a la misma supone utilizar la versión heredada de la superclase. En este caso las invocaciones en M.4 y M.6 utilizan la misma (y única) versión de dicha función.&lt;br /&gt;
&lt;br /&gt;
No confundir el mecanismo de las funciones virtuales con el de sobrecarga y ocultación. Sea el caso siguiente:&lt;br /&gt;
class Base {&lt;br /&gt;
  public:&lt;br /&gt;
  void fun (int);    // No virtual!!&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
class Derivada : public Base {&lt;br /&gt;
  public:&lt;br /&gt;
  void fun (int);    // Oculta a Base::fun&lt;br /&gt;
  void fun (char);   // versión sobrecargada de la anterior&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
Aquí pueden declararse las funciones void Base::fun(int) y void Derivada::fun(int); incluso sin ser virtuales. En este caso, se dice que void Derivada::fun(int) oculta cualquier otra versión de fun(int) que exista en cualquiera de sus ancestros. Además, si la clase Derivada define otras versiones de fun(), es decir, existen versiones de Derivada::fun() con diferentes definiciones, entonces se dice de estas últimas son versiones sobrecargadas de Derivada::fun(). Por supuesto, estas versiones sobrecargadas deberán seguir las reglas correspondientes.&lt;br /&gt;
Ejemplo-6&lt;br /&gt;
Para ilustrar el mecanismo de ocultación en un ejemplo ejecutable, utilizaremos una pequeña variación del ejemplo anterior (Ejemplo-3  ):&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {                // L.4: Clase-base&lt;br /&gt;
  public: virtual int fun(int x) {return x * x;}    // L.5 virtual&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {    // Clase derivada-1&lt;br /&gt;
  public: int fun (int x, int y) {return x + 10;}   // L.8 NO virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {    // Clase derivada-2&lt;br /&gt;
  public: int fun (int x) {return x + 15;}          // L.11 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {         // =========&lt;br /&gt;
  B b; D1 d1; D2 d2;     // M.1&lt;br /&gt;
  B* bp = &amp;amp;b; B* bp1 = &amp;amp;d1; B* bp2 = &amp;amp;d2;           // M.1a&lt;br /&gt;
  D1* d1p = &amp;amp;d1; D2* d2p = &amp;amp;d2;     // M.1b&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;   // M.2a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp1-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.3a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp2-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.3b:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1p-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.4a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2p-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.4b:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
En este caso nos hemos limitado a añadir un segundo argumento a la definición de D1::fun de la clase derivada-1 (L8). Como consecuencia, la nueva función no es virtual, ya que no cumple con las condiciones exigidas . El resultado es que en las instancias de D1, la definición B::fun de la superclase queda ocultada por la nueva definición , con la consecuencia de que la sentencia M.4a, que antes de la modificación funcionaba correctamente, produce ahora un error de compilación porque los argumentos actuales (un entero) no concuerdan con los argumentos formales esperados por la función (dos enteros).&lt;br /&gt;
Además el compilador nos advierte de la ocultación mediante una advertecia; en Borland C++: 'D1::fun(int,int)' hides virtual function 'B::fun(int)'.&lt;br /&gt;
&lt;br /&gt;
Cuando se declare una función como virtual tenga en mente que:&lt;br /&gt;
•	Solo pueden ser métodos (funciones-miembro).&lt;br /&gt;
•	No pueden ser declaradas friend de otras clases.&lt;br /&gt;
•	No pueden ser miembros estáticos &lt;br /&gt;
•	Los constructores no pueden ser declarados virtuales &lt;br /&gt;
•	Los destructores sí pueden ser virtuales.&lt;br /&gt;
&lt;br /&gt;
Las funciones virtuales no necesitan ser redefinidas en todas las clases derivadas. Puede existir una definición en la clase base y todas, o algunas de las subclases, pueden llamar a la función-base.&lt;br /&gt;
Para redefinir una función virtual en una clase derivada, las declaraciones en la clase base y en la derivada deben coincidir en cuanto a número y tipo de los parámetros. Excepcionalmente pueden diferir en el tipo devuelto; este caso es discutido más adelante.&lt;br /&gt;
&lt;br /&gt;
Una función virtual redefinida, que solapa la función de la superclase, sigue siendo virtual y no necesita el especificador virtual en su declaración en la subclase. La propiedad virtual es heredada automáticamente por las funciones de la subclase. Aunque si la subclase va a ser derivada de nuevo, entonces sí es necesario el especificador.&lt;br /&gt;
Ejemplo:&lt;br /&gt;
class B {       // Superclase&lt;br /&gt;
   public:&lt;br /&gt;
   virtual int func();&lt;br /&gt;
};&lt;br /&gt;
...&lt;br /&gt;
class D1 : public B {     // Derivada&lt;br /&gt;
  public:&lt;br /&gt;
  int fun ();             // virtual por defecto&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {     // Derivada&lt;br /&gt;
  public:&lt;br /&gt;
  virtual int fun ();     // virtual explícita&lt;br /&gt;
};&lt;br /&gt;
class D1a : public D1 {   // Derivada&lt;br /&gt;
  public:&lt;br /&gt;
  int fun ();             // No virtual!!&lt;br /&gt;
};&lt;br /&gt;
class D2a : public D2 {   // Derivada&lt;br /&gt;
  public:&lt;br /&gt;
  int fun ();             // Ok Virtual!!&lt;br /&gt;
  int fun (char);         // No virtual!!&lt;br /&gt;
};&lt;br /&gt;
De la simple inspección de las dos últimas líneas, no es posible deducir que el método fun de la clase D2a es un método virtual. Esto representa en ocasiones un problema y puede ser motivo de confusión, ya que es muy frecuente que las definiciones de las superclases se encuentren en ficheros de cabecera, y el programador que utiliza tales superclases para derivar versiones específicas debe consultar dichos ficheros. Sobre todo, porque como se indicó en el epígrafe anterior, la declaración en la subclase debe coincidir en cuanto a número y tipo de los parámetros. En caso contrario se trataría de una nueva definición, con lo que estamos ante un caso de sobrecarga y se ignora el mecanismo de enlazado retrasado.&lt;br /&gt;
== Invocación de funciones virtuales ==&lt;br /&gt;
Lo que realmente caracteriza a las funciones virtuales es la forma muy especial que utiliza el compilador para invocarlas; forma que es posible gracias a su tipo de enlazado. Por lo demás, el mecanismo externo (la sintaxis utilizada) es exactamente igual que la del resto de funciones miembro. He aquí un resumen de esta sintaxis:&lt;br /&gt;
class CB {              // Clase-base&lt;br /&gt;
   public:&lt;br /&gt;
   void fun1(){...}     // definición-10&lt;br /&gt;
   void virtual fun2(){...}    // definición-20&lt;br /&gt;
   ...&lt;br /&gt;
};&lt;br /&gt;
class D1 : public CB {  // Derivada-1&lt;br /&gt;
   public:&lt;br /&gt;
   void fun1() {...}    // definición-11&lt;br /&gt;
   void fun2() {...}    // definición-12&lt;br /&gt;
};&lt;br /&gt;
class D2 : public CB {  // Derivada-2&lt;br /&gt;
   public:&lt;br /&gt;
   void fun1() {...}    // definición-21&lt;br /&gt;
   void fun2() {...}    // definición-22&lt;br /&gt;
};&lt;br /&gt;
...&lt;br /&gt;
CB obj; D1 obj1;  D2 obj2;     // se instancian objetos de las clases&lt;br /&gt;
...&lt;br /&gt;
obj.fun1();             // invoca definición-10&lt;br /&gt;
obj.fun2();             // invoca definición-20&lt;br /&gt;
obj1.fun1();            // invoca definición-11&lt;br /&gt;
obj1.fun2();            // invoca definición-12&lt;br /&gt;
obj1.CB::fun1();        // invoca definición-10&lt;br /&gt;
obj1.CB::fun2();        // invoca definición-20&lt;br /&gt;
obj2.fun1();            // invoca definición-21&lt;br /&gt;
obj2.fun2();            // invoca definición-22&lt;br /&gt;
obj2.CB::fun1();        // invoca definición-10&lt;br /&gt;
obj2.CB::fun2();        // invoca definición-20&lt;br /&gt;
La dierencia entre las invocaciones obj.fun1() y obj1.CB::fun1(), estriba en que la misma función se ejecuta sobre distinto juego de variables. Por contra, en obj.fun1() y obj.fun2(), funciones distintas se ejecutan sobre el mismo juego de variables.&lt;br /&gt;
CB* ptr = &amp;amp;obj;         // se definen punteros a los objetos&lt;br /&gt;
D1* ptr1= &amp;amp;obj1;&lt;br /&gt;
D2* ptr2= &amp;amp;obj2;&lt;br /&gt;
...&lt;br /&gt;
ptr-&amp;gt;fun1();            // invoca definición-10&lt;br /&gt;
ptr1-&amp;gt;fun1();           // invoca definición-11&lt;br /&gt;
ptr2-&amp;gt;fun1();           // invoca definición-21&lt;br /&gt;
&lt;br /&gt;
Cuando desde un objeto se invoca un método (virtual o no) utilizando el nombre del objeto mediante los operadores de acceso a miembros, directo, o indirecto,  se invoca el código de la función correspondiente a la clase de la que se instancia el objeto. Es decir, el código invocado solo depende del tipo de objeto (y de la sintaxis de la invocación). Esta información puede conocerse en tiempo de compilación, en cuyo caso se utilizaría enlazado estático. En otros casos este dato solo es conocido en tiempo de ejecución, por lo que debería emplearse enlazado dinámico.&lt;br /&gt;
Cualquiera que sea el mecanismo para referenciar al objeto que invoca a la función (operador de acceso directo -1- o indirecto -2-):&lt;br /&gt;
obj.fun1()      // -1-&lt;br /&gt;
ptr-&amp;gt;fun1()     // -2-&lt;br /&gt;
La función conoce cuál es el objeto que la invoca -que juego de variables debe utilizar- a través del argumento implícito this.&lt;br /&gt;
== Invocación en jerarquías de clases ==&lt;br /&gt;
Sea B es una clase base, y otra D derivada públicamente de B. Cada una contiene una función virtual vf, entonces si vf es invocada por un objeto de D, la llamada que se realiza es D::vf(), incluso cuando el acceso se realiza vía un puntero o referencia a la superclase B. Ejemplo:&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class C {               // Clase-base&lt;br /&gt;
  public: virtual int get() {return 10;}&lt;br /&gt;
};&lt;br /&gt;
class D : public C {    // Derivada&lt;br /&gt;
  public: virtual int get() {return 100;}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {        // =========&lt;br /&gt;
  D d;&lt;br /&gt;
  C* cptr = &amp;amp;d;&lt;br /&gt;
  C&amp;amp; cref = d;&lt;br /&gt;
  cout &amp;lt;&amp;lt; d.get()     &amp;lt;&amp;lt; endl;&lt;br /&gt;
  cout &amp;lt;&amp;lt; cptr-&amp;gt;get() &amp;lt;&amp;lt; endl;&lt;br /&gt;
  cout &amp;lt;&amp;lt; cref.get()  &amp;lt;&amp;lt; endl;&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
100&lt;br /&gt;
100&lt;br /&gt;
100&lt;br /&gt;
&lt;br /&gt;
==  Tabla de funciones virtuales ==&lt;br /&gt;
Las funciones virtuales pagan un tributo por su versatilidad. Cada objeto de la clase derivada tiene que incluir un puntero (vfptr) a una tabla de direcciones de funciones virtuales, conocida como vtable. La utilización de dicho puntero permite seleccionar desde el objeto, la función correspondiente en tiempo de ejecución. Como resultado, el mecanismo de invocación de estas funciones  es mucho menos eficiente que el de los métodos normales (enlazado estático), por lo que debe reservarse su utilización a los casos estrictamente necesarios.&lt;br /&gt;
Es fácil poner en evidencia la existencia del puntero vfptr mediante un sencillo experimento que utiliza el operador sizeof&lt;br /&gt;
struct S1 {&lt;br /&gt;
  int n;&lt;br /&gt;
  double get() { return n; } // método auxiliar normal&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct S2 {&lt;br /&gt;
  int n;&lt;br /&gt;
  virtual double get() { return n; } // método virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
size_t tamS1 = sizeof(S1);  // -&amp;gt; 4&lt;br /&gt;
size_t tamS2 = sizeof(S2);  // -&amp;gt; 8&lt;br /&gt;
Comentario&lt;br /&gt;
El resultado del tamaño de ambos tipos es respectivamente 4 y 8 en cualquiera de los compiladores comprobados: Borland C++ 5.5 y gcc-g++ 3.4.2-20040916-1 para Windows. La diferencia de 4 Bytes obtenida corresponde precisamente a la presencia del mencionado puntero oculto.&lt;br /&gt;
== Función virtual pura ==&lt;br /&gt;
En ocasiones se lleva al extremo el concepto &amp;quot;virtual&amp;quot; en la declaración de una súper clase (&amp;quot;esta función será redefinida más tarde en las clases derivadas&amp;quot;), por lo que en ella solo existe una declaración de la función, relegándose las distintas definiciones a las clases derivadas. Entonces se dice que esta función es virtual pura. Esta circunstancia hay que advertirla al compilador; es una forma de decirle que la falta de definición no es un olvido por nuestra parte (de lo contrario el compilador nos señala que se nos ha olvidado la definición); esto se hace igualando a cero la declaración de la función:&lt;br /&gt;
virtual int funct1(void);      // Declara función virtual&lt;br /&gt;
virtual int funct2(void) = 0;  // Declara función virtual pura&lt;br /&gt;
&lt;br /&gt;
La existencia de una función virtual basta para que la clase que estamos definiendo sea polimórfica. Si además igualamos la función a cero, la estaremos declarando como función virtual pura, lo que automáticamente declara la clase como abstracta &lt;br /&gt;
Es muy frecuente que las funciones virtuales puras se declaren además con el calificador const , de forma que es usual encontrar expresiones del tipo:&lt;br /&gt;
virtual int funct2(void) const = 0;  // Declara función virtual pura y constante&lt;br /&gt;
===  Ejemplo ===&lt;br /&gt;
El ejemplo que sigue es una modificación del anterior , en el que declaramos la función fun de la clase-base B como virtual pura, con lo que podemos omitir su definición.&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {              // L.4:  Clase-base&lt;br /&gt;
  public:  virtual int fun(int x) = 0;       // L.5 virtual pura&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {  // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 10;}  // L.8 virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {  // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 15;}  // L.11 virtual&lt;br /&gt;
};&lt;br /&gt;
int main(void) {       // =========&lt;br /&gt;
  D1 d1; D2 d2;        // M.1&lt;br /&gt;
&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.fun(10)    &amp;lt;&amp;lt; endl;  // M.3:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.fun(10)    &amp;lt;&amp;lt; endl;  // M.4:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
Comentario&lt;br /&gt;
El resto del programa se mantiene prácticamente igual al modelo anterior, con la salvedad de que ahora en M1 no podemos instanciar un objeto directamente de la superclase B; la razón es que la superclase está incompleta (falta la definición de fun). Si lo intentáramos, el compilador nos mostraría un error señalando que no se puede instanciar un objeto de la clase B y que dicha clase es abstracta; además las clases abstractas no son instanciables por definición.&lt;br /&gt;
En lo que respecta a las salidas, comprobamos que son los valores esperados.&lt;br /&gt;
&lt;br /&gt;
Una declaración de función no puede ser al mismo tiempo una definición y una declaración de virtual pura. Ejemplo:&lt;br /&gt;
struct Est {&lt;br /&gt;
    virtual void f() { /* ... */ } = 0;    // Error!!&lt;br /&gt;
};&lt;br /&gt;
La forma legal de proporcionar una definición es:&lt;br /&gt;
struct Est {&lt;br /&gt;
  virtual void f(void) = 0;    // declara f virtual pura&lt;br /&gt;
};&lt;br /&gt;
virtual void Est::f(void) {    // definición posterior de f&lt;br /&gt;
   /* código de la función f  */&lt;br /&gt;
};&lt;br /&gt;
== Un mundo de excepciones ==&lt;br /&gt;
Seguramente el lector que haya llegado hasta aquí experimente una cierta perplejidad (que comparto). En el párrafo §7  decimos que se utiliza el recurso de declarar una función virtual pura para poder omitir la definición, y a continuación, en el párrafo §7.2 exponemos la forma legal de proporcionarla...  El lector puede comprobar que esta aparente contradicción es asumida por el compilador sin protestas. En efecto, considere el ejemplo siguiente en el que modificamos el anterior añadiendo una definición a la función virtual pura fun.&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {               // L.4:  Clase-base&lt;br /&gt;
  public:  virtual int fun(int x) = 0;       // L.5 virtual pura&lt;br /&gt;
};&lt;br /&gt;
int B::fun(int x) {return x * x}             // L.7 definición de fun&lt;br /&gt;
&lt;br /&gt;
class D1 : public B {   // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 10;}  // L.9 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class D2 : public B {   // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 15;}  // L.12 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {        // =========&lt;br /&gt;
  D1 d1; D2 d2;         // M.1&lt;br /&gt;
&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.fun(10)    &amp;lt;&amp;lt; endl;  // M.3:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.fun(10)    &amp;lt;&amp;lt; endl;  // M.4:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.B::fun(10) &amp;lt;&amp;lt; endl;  // M.5:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.B::fun(10) &amp;lt;&amp;lt; endl;  // M.6:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
== Tipos devueltos por las funciones virtuales ==&lt;br /&gt;
Cuando se redefine una función virtual no se puede cambiarse el tipo de valor devuelto. Para redefinir una función virtual en alguna clase derivada, la nueva función debe coincidir exactamente en número y tipo con los parámetros de la declaración inicial (la &amp;quot;firma&amp;quot; -Signature- de ambas funciones deben ser iguales). Si no coinciden en esto, el compilador C++ considera que se trata de funciones diferentes (un caso de sobrecarga) y se ignora el mecanismo de funciones virtuales.&lt;br /&gt;
Para prevenir que puedan producirse errores inadvertidos, el compilador C++ GNU dispone de la opción  -Woverloaded-virtual, que produce un mensaje de aviso, si se redefine un método declarado previamente virtual en una clase antecesora, y no se cumple la condición de igualdad de firmas.&lt;br /&gt;
No obstante lo anterior, hay casos en que las funciones virtuales redefinidas en clases derivadas devuelven un tipo diferente del de la función virtual de la clase base. Esto es posible solo cuando se dan simultáneamente las dos condiciones siguientes:&lt;br /&gt;
•	La función virtual sobrecontrolada devuelve un puntero o referencia a clase base.&lt;br /&gt;
•	La nueva versión devuelve un puntero o referencia a la clase derivada.&lt;br /&gt;
=== Ejemplo ===&lt;br /&gt;
struct X {};            // clase base.&lt;br /&gt;
struct Y : X {};        // clase derivada (:public X por defecto).&lt;br /&gt;
struct B {              // clase base.&lt;br /&gt;
   virtual void vf1();  // L.4:&lt;br /&gt;
   virtual void vf2();&lt;br /&gt;
   virtual void vf3();&lt;br /&gt;
   void f();&lt;br /&gt;
   virtual X* pf();     /* L.8:  devuelve puntero a clase base,&lt;br /&gt;
                            esta función virtual puede ser sobrecontrolada */&lt;br /&gt;
};&lt;br /&gt;
class D : public B {    // clase derivada&lt;br /&gt;
   public:&lt;br /&gt;
   virtual void vf1();  // L.12: Especificador virtual, legal pero redundante&lt;br /&gt;
   void vf2(int);       /* L.13: No virtual, oculta B::vf2()&lt;br /&gt;
                            dado que usa otros argumentos */&lt;br /&gt;
// char vf3();          // L.14: Ilegal! cambia solo el tipo devuelto!&lt;br /&gt;
   void f();            // L.15: privativa de D (no virtual)&lt;br /&gt;
   Y*   pf();           /* L.16: función sobrecontrolante; difiere solo&lt;br /&gt;
                          en el tipo devuelto. Devuelve puntero a subclase */&lt;br /&gt;
};&lt;br /&gt;
void extf() {&lt;br /&gt;
   D d;                 // d objeto de la clase D (instancia)&lt;br /&gt;
   B* bp = &amp;amp;d;          /* L.20: Conversión estándar D* a B*&lt;br /&gt;
                  Inicializa bp con la tabla de funciones del objeto d.&lt;br /&gt;
                  Si no existe entrada para una función en dicha tabla,&lt;br /&gt;
                  utiliza la función de la tabla de la clase B */&lt;br /&gt;
   bp–&amp;gt;vf1();           // invoca D::vf1&lt;br /&gt;
   bp–&amp;gt;vf2();           // invoca B::vf2 (D::vf2 tiene diferentes argumentos)&lt;br /&gt;
   bp–&amp;gt;f();             // invoca B::f (not virtual)&lt;br /&gt;
   X* xptr = bp–&amp;gt;pf();  /* invoca D::pf() y convierte el resultado&lt;br /&gt;
                            en un puntero a X */&lt;br /&gt;
   D* dptr = &amp;amp;d;&lt;br /&gt;
   Y* yptr = dptr–&amp;gt;pf(); /* inicializa yptr; este puntero invocará a D::pf()&lt;br /&gt;
                            No se realiza ninguna conversión */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
L.12:  La versión D::vf1 es virtual automáticamente, dado que devuelve lo mismo y tiene los mismos parámetros que su homónima en la superclase B. El especificador virtual puede ser utilizado en estos casos pero no es estrictamente necesario a no ser que se vayan a derivar nuevas subclases de la clase derivada.&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Puede Contactar  ==&lt;br /&gt;
*[[Declaración de funciones|Declaración de funciones]] &lt;br /&gt;
*[[Sobrecarga de funciones (programación)|Sobrecarga de funciones (programación)]]&lt;br /&gt;
*[[Parámetros y argumentos (programación)|Parámetros y argumentos (programación)]]&lt;br /&gt;
*[[Invocación de funciones (programación)|Invocación de funciones (programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Sobrecarga de enumeraciones (Informática)|Sobrecarga de enumeraciones (Informática)]] &lt;br /&gt;
*[[Referencias (programación)|Referencias (programación)]]&lt;br /&gt;
== Fuentes  ==&lt;br /&gt;
* [http://www.zator.com/Cpp/E4_11_8a.htm Funciones virtuales]&lt;br /&gt;
* [http://www.fismat.umich.mx/mn1/manual/node7.html Funciones en C ++]&lt;br /&gt;
*     [http://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Funciones#Definiendo_una_funci.C3.B3n    Programación en C++/Funciones]&lt;br /&gt;
*    [http://c.conclase.net/curso/?cap=020#inicio Funciones]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]] [[Category:Programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Destructores_(Programaci%C3%B3n)&amp;diff=3024808</id>
		<title>Destructores (Programación)</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Destructores_(Programaci%C3%B3n)&amp;diff=3024808"/>
		<updated>2017-12-12T18:14:34Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Destructores (Programación) |imagen= |concepto= Son un tipo especial de función miembro, estrechamente relacionados con los constructores}}&lt;br /&gt;
 &lt;br /&gt;
'''Destructores (Programación)'''. Son un tipo especial de función miembro, estrechamente relacionados con los [[Constructores (Programación)|constructores]]. Son también [[Función (programación)|funciones]] que no devuelven nada (ni siquiera void). Tampoco aceptan ningún parámetro, ya que la destrucción de un objeto no acepta ningún tipo de opción o especificación particular y es idéntica para todos los objetos de la clase. Los destructores no pueden ser heredados, aunque una clase derivada puede llamar a los destructores de su superclase si no han sido declarados privados (son públicos o protegidos). Lo mismo que ocurre con los constructores, tampoco puede obtenerse su dirección, por lo que no es posible establecer punteros a este tipo de funciones.&lt;br /&gt;
 &lt;br /&gt;
La misión más común de los destructores es liberar la memoria asignada por los constructores, aunque también puede consistir en desasignar y/o liberar determinados recursos asignados por estos. Por ejemplo, cerrar un fichero; una línea de comunicación, o desbloquear un recurso compartido que hubiera sido bloqueado previamente por el constructor.&lt;br /&gt;
 &lt;br /&gt;
Los destructores son invocados automáticamente (de forma implícita) por el programa en multitud de ocasiones; de hecho es muy raro que sea necesario invocarlos explícitamente. Su misión es limpiar los miembros del objeto antes que el propio objeto se auto-destruya.&lt;br /&gt;
 &lt;br /&gt;
==Declaración==&lt;br /&gt;
Los destructores se distinguen porque tienen el mismo nombre que la clase a que pertenecen precedido por la tilde ~ para simbolizar su estrecha relación con los constructores que utilizan el mismo nombre (son el &amp;quot;complemento&amp;quot; de aquellos). Ejemplo: &lt;br /&gt;
 class X {&lt;br /&gt;
  public:&lt;br /&gt;
  ~X();      // destructor de la clase X&lt;br /&gt;
 };&lt;br /&gt;
 ...&lt;br /&gt;
 X::~X() {    // definición (off-line) del destructor&lt;br /&gt;
  ...&lt;br /&gt;
 }&lt;br /&gt;
== Invocación==&lt;br /&gt;
Los destructores son invocados automáticamente por el [[Compilador|compilador]], y es muy raro que sea necesario invocarlos explícitamente.&lt;br /&gt;
===Invocación explícita de destructores===&lt;br /&gt;
En caso necesario los destructores pueden ser invocados explícitamente de dos formas: indirectamente, mediante una llamada a delete o directamente utilizando el nombre cualificado completo.&lt;br /&gt;
====Ejemplo====&lt;br /&gt;
 class X {...};    // X es una clase&lt;br /&gt;
 ...&lt;br /&gt;
 {&lt;br /&gt;
   X obj1;            // L.4: objeto automático&lt;br /&gt;
   X* ptr = new(X)    // L.5: objeto persistente&lt;br /&gt;
   X* pt2 = &amp;amp;obj1;    // Ok: pt2 es puntero a obj1 de la clase X&lt;br /&gt;
   ...&lt;br /&gt;
   pt2–&amp;gt;X::~X();      // L.8: Ok: llamada legal del destructor&lt;br /&gt;
                      // pt2-&amp;gt;~X();            L.9: Ok: variación sintáctica de la anterior&lt;br /&gt;
                      // obj1.~X();            L.10: Ok otra posibilidad análoga&lt;br /&gt;
   X::~X();           // L.11: Error: llamada ilegal al destructor [1]&lt;br /&gt;
   delete ptr;        // L.12: Ok. invocación implícita al destructor&lt;br /&gt;
 }&lt;br /&gt;
=== Invocación implícita de destructores===&lt;br /&gt;
Además de las posibles invocaciones explícitas, cuando una variable sale del ámbito para el que ha sido declarada, su destructor es invocado de forma implícita. Los destructores de las variables locales son invocados cuando el bloque en el que han sido declarados deja de estar activo. Por su parte, los destructores de las variables globales son invocados como parte del procedimiento de salida después de la función main.&lt;br /&gt;
== Propiedades de los destructores==&lt;br /&gt;
Cuando se tiene un destructor explícito, las [[Sentencias (programación)|sentencias]] del cuerpo se ejecutan antes que la destrucción de los miembros. A su vez, la invocación de los destructores de los miembros se realiza exactamente en orden inverso en que se realizó la invocación de los constructores correspondientes. La destrucción de los miembros estáticos se ejecuta después que la destrucción de los miembros no estáticos.&lt;br /&gt;
Los destructores no pueden ser declarados const o volatile, aunque pueden ser invocados desde estos objetos. Tampoco pueden ser declarados static, lo que supondría poder invocarlos sin la existencia de un objeto que destruir.&lt;br /&gt;
== Destructores virtuales==&lt;br /&gt;
Como cualquier otra función miembro, los destructores pueden ser declarados virtual. El destructor de una clase derivada de otra cuyo destructor es virtual, también es virtual.&lt;br /&gt;
La existencia de un destructor virtual permite que un objeto de una subclase pueda ser correctamente destruido por un puntero a su clase-base.&lt;br /&gt;
===Ejemplo===&lt;br /&gt;
 class B {   // Superclase (polimórfica)&lt;br /&gt;
  ...&lt;br /&gt;
  virtual ~B(); // Destructor virtual&lt;br /&gt;
 };&lt;br /&gt;
 class D : public B {    // Subclase (deriva de B)&lt;br /&gt;
  ...&lt;br /&gt;
  ~D(); // destructor también virtual&lt;br /&gt;
 };&lt;br /&gt;
 void func() {&lt;br /&gt;
  B* ptr = new D;    // puntero a superclase asignado a objeto de subclase&lt;br /&gt;
  ...&lt;br /&gt;
  delete ptr;        // Ok: delete es necesario siempre que se usa new&lt;br /&gt;
 } &lt;br /&gt;
==  Los destructores y  exit==&lt;br /&gt;
Cuando se invoca exit desde un programa, no son invocados los destructores de ninguna variable local del ámbito actual. Las globales son destruidas en su orden normal.&lt;br /&gt;
==Los destructores y abort==&lt;br /&gt;
Cuando se invoca la función abort en cualquier punto de un programa no se invoca ningún destructor, ni aún para las variables de ámbito global.&lt;br /&gt;
== Véase también ==&lt;br /&gt;
*[[Tokens|Tokens]]&amp;lt;br&amp;gt; &lt;br /&gt;
*[[Identificadores|Identificadores]]&lt;br /&gt;
*[[Constructores (Programación)| Constructores (Programación)]] &lt;br /&gt;
*[[Función (programación)|Función (programación)]] &lt;br /&gt;
*[[Funciones virtuales|Funciones virtuales]] &lt;br /&gt;
== Fuente==&lt;br /&gt;
*http://c.conclase.net/curso/?cap=030&lt;br /&gt;
*http://msdn.microsoft.com/es-es/library/1838wste.aspx&lt;br /&gt;
*http://msdn.microsoft.com/es-es/library/66x5fx1b%28v=vs.80%29.aspx&lt;br /&gt;
*http://msdn.microsoft.com/es-es/library/6t4fe76c.aspx&lt;br /&gt;
[[Category:Lenguajes_de_programación]] [[Category:Programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Referencias_(programaci%C3%B3n)&amp;diff=3024794</id>
		<title>Referencias (programación)</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Referencias_(programaci%C3%B3n)&amp;diff=3024794"/>
		<updated>2017-12-12T18:13:00Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;&lt;br /&gt;
{{Definición&lt;br /&gt;
|Nombre=Referencias (programación)&lt;br /&gt;
|imagen=&lt;br /&gt;
|concepto=Son un tipo de dato estrechamente relacionado con los punteros. Es un recurso para pasar argumentos a funciones permitiendo que los argumentos no sean simples variables locales de la función, sino objetos del ámbito que realiza la invocación&lt;br /&gt;
}}&lt;br /&gt;
'''Referencias (programación) '''. Son un tipo de dato estrechamente relacionado con los punteros. Una referencia de un objeto no es un objeto, en el sentido que no tiene su propio espacio de almacenamiento como ocurre con los punteros, y en consecuencia no pueden realizarse con ellas muchas de las operaciones que se relacionan con objetos. Por ejemplo obtener su dirección, crearlas con el operador nuevo, o crear matrices de referencias.&lt;br /&gt;
 &lt;br /&gt;
Una referencia es una especie de alias o &amp;quot;alter ego&amp;quot; del objeto. Es un recurso para pasar argumentos a funciones permitiendo que los argumentos no sean simples variables locales de la función, sino objetos del ámbito que realiza la invocación, lo que permite que la [[función]] pueda modificar [[objetos externos]] a ella.&lt;br /&gt;
== Sintaxis: ==&lt;br /&gt;
La declaración de una [[Variable en programación|variable]] de este tipo se realiza mediante el declarador de referencia. La sintaxis general es:&lt;br /&gt;
&amp;lt;tipo_objeto&amp;gt; &amp;amp; &amp;lt;etiqueta_referencia&amp;gt; [= &amp;lt;iniciador&amp;gt;]&lt;br /&gt;
Ejemplo:&lt;br /&gt;
int x;&lt;br /&gt;
...&lt;br /&gt;
int &amp;amp; z = x; // decimos que x es el 'iniciador' y que z es la 'referencia'&lt;br /&gt;
Estas [[sentencias]] declaran e inicia la variable z como referencia-a-entero, y la asocia con la variable x (que es un entero). En adelante z actúa como un alias de x, de forma que cualquier operación sobre z equivale a hacerla sobre x. En realidad puede considerarse que z es &amp;quot;casi&amp;quot; un sinónimo de x (como si fuesen la misma [[variable]]). &lt;br /&gt;
== Observaciones ==&lt;br /&gt;
En muchas situaciones prácticas puede ser indiferente utilizar una referencia o un puntero, sin embargo mantienen importantes diferencias que conviene conocer y que resumimos en el cuadro adjunto antes de comentarlas más detenidamente. En cualquier caso, la mejor regla es recordar que las referencias pueden considerarse como un sustituto del identificador de un objeto, mientras que los punteros deben ser considerados siempre como objetos en sí mismos. Además sus [[aritméticas]] son distintas. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Posibilidad de&lt;br /&gt;
! Referencias&lt;br /&gt;
! Punteros&lt;br /&gt;
|-&lt;br /&gt;
| Declaración independiente de la definición&lt;br /&gt;
| No&lt;br /&gt;
| Si &lt;br /&gt;
|-&lt;br /&gt;
| Asignarles un nuevo valor&lt;br /&gt;
| No&lt;br /&gt;
| Si &lt;br /&gt;
|-&lt;br /&gt;
| Referirse a un objeto de su mismo tipo&lt;br /&gt;
| No&lt;br /&gt;
| Si &lt;br /&gt;
|-&lt;br /&gt;
| Asignarles el valor void&lt;br /&gt;
| No&lt;br /&gt;
| Si &lt;br /&gt;
|}&lt;br /&gt;
== Declaración ==&lt;br /&gt;
Las referencias no pueden ser declaradas aisladas, de forma que tienen que estar indefectiblemente unidas a un objeto en su propia [[definición]] (deben ser inicializadas en la declaración). Además, una vez declaradas no pueden ser reasignadas a otro objeto (como los punteros), por lo que resultan unidas de por vida al objeto inicial. Por ejemplo:&lt;br /&gt;
int&amp;amp; z; // Error.&lt;br /&gt;
int&amp;amp; z = x // Ok.&lt;br /&gt;
int&amp;amp; z = y; // Error.&lt;br /&gt;
Por la razón anterior, puesto que tienen que estar unidas a un objeto, no pueden referenciar a void:&lt;br /&gt;
int&amp;amp; z = void; // Error.&lt;br /&gt;
Sí pueden ser inicializadas a otra referencia del mismo tipo, en cuyo caso señalan al objeto inicial. &lt;br /&gt;
 &lt;br /&gt;
Las referencias son una especie de punteros constantes, pero que no aceptan el [[álgebra de punteros]] ni pueden ser manipuladas igual.&lt;br /&gt;
== Reasignación de referencias ==&lt;br /&gt;
Después de la definición inicial, las sucesivas asignaciones a las referencias deben ser con objetos del mismo tipo. Por ejemplo, a una referencia-a-int solo se le pueden asignar tipos int. Pero estas asignaciones son en realidad al objeto inicialmente referenciado. Ejemplo:&lt;br /&gt;
int x = 10, y = 20;&lt;br /&gt;
int&amp;amp; refi = x; // definición inicial&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;X = &amp;quot; &amp;lt;&amp;lt; refi; // -&amp;gt; X = 10 (valor de x)&lt;br /&gt;
refi = y; // Ojo!! Equivale a: x = y&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;X = &amp;quot; &amp;lt;&amp;lt; refi; // -&amp;gt; X = 20 (x es ahora 20)&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;X = &amp;quot; &amp;lt;&amp;lt; x; // -&amp;gt; X = 20 (comprobación)&lt;br /&gt;
== Modelado ==&lt;br /&gt;
En ocasiones el [[compilador]] realiza automáticamente determinadas promociones de tipo para hacer posible la asignación. Por ejemplo, siguiendo con las definiciones anteriores:&lt;br /&gt;
enum COLOR { ROJO, VERDE, AZUL};&lt;br /&gt;
COLOR c1 = VERDE;&lt;br /&gt;
refi = c1; // L.3: Ok!! (Ahora x = 1)&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;X = &amp;quot; &amp;lt;&amp;lt; refi; // -&amp;gt; X = 1&lt;br /&gt;
float f = 12.5;&lt;br /&gt;
refi = f; // L.6: Ok!!&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;F = &amp;quot; &amp;lt;&amp;lt; f; // -&amp;gt; F = 12.5&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;X = &amp;quot; &amp;lt;&amp;lt; refi; // -&amp;gt; X = 12 (Atención!!)&lt;br /&gt;
En la asignación L.3, la variable enumerada c1 es promovida a [[entero]] (cosa perfectamente factible, el resultado es asignado a refi, lo que a la postre equivale a asignarlo a x. Un caso parecido es el de la asignación L.6, donde el float f es promovido a entero (lo que implica una pérdida de precisión) y el resultado asignado nuevamente a refi, la diferencia resultante entre f y x se muestra en las dos últimas salidas.&lt;br /&gt;
== Punteros y referencias a referencias ==&lt;br /&gt;
No es posible declarar punteros-a-referencias ni referencias-a-referencias:&lt;br /&gt;
int x = 10;&lt;br /&gt;
int&amp;amp; rti = x; // Ok referencia-a-x&lt;br /&gt;
int&amp;amp;* ptrti = &amp;amp;rti // Error!! Puntero-a-referencia&lt;br /&gt;
int&amp;amp;&amp;amp; rar = rti // Error!! Referencia-a-referencia&lt;br /&gt;
 &lt;br /&gt;
Puesto que las referencias-a-tipoX son en realidad un &amp;quot;alter ego&amp;quot; del tipo referenciado, sí es posible utilizar referencias para la definición de otras referencias al mismo tipo:&lt;br /&gt;
int&amp;amp; rti2 = rti; // Ok otra referencia-a-x&lt;br /&gt;
En contra de lo que ocurre con sus parientes cercanos los punteros, no es posible iniciar referencias con el operador new.&lt;br /&gt;
== Referencias a punteros ==&lt;br /&gt;
Aunque de poca importancia práctica, la referencia-a-puntero, es un alias que puede ser utilizado a todos los efectos como si fuese el propio puntero. Ejemplo:&lt;br /&gt;
#include &amp;lt;iostream.h&amp;gt;&lt;br /&gt;
int main() { // ======&lt;br /&gt;
int x = 10;&lt;br /&gt;
int* ptr = &amp;amp;x; // puntero-a-int&lt;br /&gt;
int*&amp;amp; ref = ptr; // referencia-a-puntero-a-int&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;ptr-a-X = &amp;quot; &amp;lt;&amp;lt; ref &amp;lt;&amp;lt; endl;&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;ptr-a-X = &amp;quot; &amp;lt;&amp;lt; ptr &amp;lt;&amp;lt; endl;&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;Valor X = &amp;quot; &amp;lt;&amp;lt; *ref &amp;lt;&amp;lt; endl; // M.6&lt;br /&gt;
cout &amp;lt;&amp;lt; &amp;quot;Valor X = &amp;quot; &amp;lt;&amp;lt; *ptr &amp;lt;&amp;lt; endl;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
ptr-a-X = 0065FE00&lt;br /&gt;
ptr-a-X = 0065FE00&lt;br /&gt;
Valor X = 10&lt;br /&gt;
Valor X = 10&lt;br /&gt;
En este ejemplo es digna de mención la forma de declaración de ref, referencia-a-puntero; y como a todos los efectos, incluso para aplicarle el operador de in dirección *, la referencia se comporta en M.6 como un alias perfecto del puntero, señalando al mismo objeto que aquel.&lt;br /&gt;
== Referencias a funciones ==&lt;br /&gt;
[[C++]] permite definir referencias a [[Función (programación)|funciones]], aunque carecen de importancia práctica. La sintaxis para su declaración es la misma que con los punteros, aunque como es usual, su inicialización debe hacerse en el punto de la declaración. Así mismo, pueden invocarse funciones a través de sus referencias como si se tratara de [[punteros]].&lt;br /&gt;
 &lt;br /&gt;
Si en la declaración de una referencia, el iniciador es una constante o un objeto de tipo diferente que el referenciado, entonces se crea un objeto temporal para el que la referencia actúa como un alias. Considere el siguiente ejemplo:&lt;br /&gt;
int&amp;amp; z = 6;&lt;br /&gt;
Se crea un objeto temporal tipo int que recibe el valor 6; se crea también una referencia-a-int de nemónico z, a ese objeto temporal. El [[compilador]] avisa de esta circunstancia con una advertencia: Temporary used to initialize 'z' in function.... el objeto temporal solo es accesible a través de su referencia.&lt;br /&gt;
== Argumentos por referencia ==&lt;br /&gt;
La razón última de la introducción de referencias en [[C++]] es posibilitar la [[Sobrecarga de operadores|sobrecarga de operadores]], en la práctica su uso más frecuente es el paso de argumentos a funciones &amp;quot;por referencia&amp;quot;; en especial cuando se trata de objetos definidos por el usuario (instancias de clases). Observe que mientras en C clásico solo se pasan argumentos por valor, en [[C++]] es posible pasar argumentos por valor y por referencia.&lt;br /&gt;
Ejemplo:&lt;br /&gt;
void func1 (int); // declara argumento de tipo int&lt;br /&gt;
void func2 (int&amp;amp;); // declara argumento de tipo referencia-a-int&lt;br /&gt;
...&lt;br /&gt;
int sum = 3;&lt;br /&gt;
func1(sum); // sum pasa por valor&lt;br /&gt;
func2(sum); // sum pasa por referencia&lt;br /&gt;
 &lt;br /&gt;
La utilización del argumento es idéntica en la invocación de ambas funciones, como si fuese &amp;quot;por valor&amp;quot;. La diferencia en uno y otro caso estriba solo en la forma de declarar los argumentos en la definición de la función.&lt;br /&gt;
 &lt;br /&gt;
El [[argumento]] sum pasado por referencia en func2, puede ser modificado directamente desde dentro de esta función. Por contra, en func1 el argumento pasa por valor; la función recibe una copia de la variable sum, por lo que no puede modificar el valor original (la variable sum existente fuera de la función func1). &lt;br /&gt;
 &lt;br /&gt;
En ocasiones, especialmente cuando los argumentos son objetos (instancias de clases), el verdadero motivo de pasar objetos &amp;quot;por referencia&amp;quot; no es precisamente para que la función pueda modificar el argumento (incluso se intenta evitar esto declarando el argumento como referencia constante), sino por razones de eficacia del [[Código fuente|código]].&lt;br /&gt;
Más que alguna nueva &amp;quot;funcionalidad&amp;quot;, el paso de argumentos a funciones &amp;quot;por referencia&amp;quot; solo proporciona cierta comodidad adicional a la funcionalidad proporcionada por los punteros&lt;br /&gt;
== Valores devueltos por referencia ==&lt;br /&gt;
Otro uso común de este tipo de objetos es su utilización como valor de retorno de una función. Es el caso del [[valor]] devuelto por la función adjunta&lt;br /&gt;
int&amp;amp; max (int&amp;amp; a, int&amp;amp; b) { if (a &amp;gt;= b) return a; return b; }&lt;br /&gt;
== Criterios de eficiencia ==&lt;br /&gt;
En ocasiones la utilización de referencias para el paso de argumentos a funciones o en el valor devuelto, está motivada solo por criterios de eficacia. En efecto, las secuencias de llamada y retorno de funciones implican la creación de todas las [[Variable en programación|variables]] locales de la función (incluyendo el valor que será devuelto), así como la invocación del constructor-copia para todos los argumentos que no han sido pasados por referencia. Cuando estos objetos son muy grandes. Por ejemplo, en instancias de clases con muchos datos o que derivan de [[jerarquías]] complejas, se requieren procesos de creación y destrucción, a veces muy complicados, que pueden evitarse parcialmente utilizando referencias. En tales casos suele recurrirse a declarar constantes los argumentos pasados &amp;quot;por referencia&amp;quot; para evitar que la función pueda alterar su valor.&lt;br /&gt;
== Puede Consultar ==&lt;br /&gt;
*[[Declaración de funciones|Declaración de funciones]] &lt;br /&gt;
*[[Función (programación)|Función (programación)]]&lt;br /&gt;
*[[Funciones virtuales|Funciones virtuales]] &lt;br /&gt;
*[[Sobrecarga de funciones|Sobrecarga de funciones]]&lt;br /&gt;
*[[Parámetros y argumentos (programación)|Parámetros y argumentos (programación)]]&lt;br /&gt;
*[[Invocación de funciones (programación)|Invocación de funciones (programación)]]&lt;br /&gt;
== Fuente ==&lt;br /&gt;
* [http://www.zator.com/Cpp/E4_2_3.htm Referencias]&lt;br /&gt;
* [http://www.mitecnologico.com/Main/ReferenciasProgramacion Referencias Programacion]&lt;br /&gt;
* [http://unoyunodiez.wordpress.com/2011/03/01/el-lenguaje-de-programacion-c-referencias/ El lenguaje de programación C++: referencias]&lt;br /&gt;
 &lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]] [[Category:Programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Enumeraciones_(Inform%C3%A1tica)&amp;diff=3024787</id>
		<title>Enumeraciones (Informática)</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Enumeraciones_(Inform%C3%A1tica)&amp;diff=3024787"/>
		<updated>2017-12-12T18:12:43Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre=Enumeraciones  (Informática)|imagen=   |concepto=Son un tipo especial de variables que tienen la propiedad de que su  rango de valores es un conjunto de constantes enteras denominadas  constantes de enumeración, a cada una de las cuales se le asigna un  valor}}&lt;br /&gt;
'''Enumeraciones (Informática)'''. Las [[Variables|variables]] enumeradas, enumeraciones o más abreviadamente enum (palabra reservada), son un tipo especial de variables que tienen la propiedad de que su rango de valores es un conjunto de constantes enteras denominadas constantes de enumeración, a cada una de las cuales se le asigna un valor. Para mayor legibilidad del código estos valores del rango se identifican por nemónicos. &lt;br /&gt;
 &lt;br /&gt;
==Ejemplo ==&lt;br /&gt;
 &lt;br /&gt;
Por ejemplo, la declaración:&lt;br /&gt;
 enum dia { DOM, LUN, MART, MIER, JUEV, VIER, SAB } diaX;&lt;br /&gt;
 &lt;br /&gt;
Establece un tipo enum al que se identifica por dia. Las [[Variables|variables]] de este tipo pueden adoptar un conjunto de seis valores enteros 0, 1, 2, 3, 4, 5, 6 (enumeradores) representados por los nemónicos DOM, LUN,...,SAB. Además se define una variable diaX de este tipo (variable enumerada).&lt;br /&gt;
 &lt;br /&gt;
En el ejemplo anterior, la variable diaX puede adoptar siete valores enteros (del 0 al 6). El programa los identifica con los nemónicos ya señalados.  Ojo: no confundir la variable -enumeración- con los valores que puede adoptar -[[Constantes de enumeración (Informática)|constante de enumeración]].&lt;br /&gt;
 &lt;br /&gt;
Cada enumeración distinta constituye un tipo de enumerando diferente. &lt;br /&gt;
 &lt;br /&gt;
Ejemplo:&lt;br /&gt;
 enum Calificacion {APTO, NO-APTO}  c1;&lt;br /&gt;
 enum Evolucion {SUBE, BAJA, IGUAL} c2; &lt;br /&gt;
c1 y c2 son objetos de tipo distinto.&lt;br /&gt;
 &lt;br /&gt;
Puede omitirse la palabra clave enum si dia no es [[Identificadores (Informática)|identificador]] de nada más en el mismo ámbito. El [[Compilador|compilador]] sabe que se trata de una variable tipo enum por la sintaxis de la propia declaración. Por ejemplo, es correcto: &lt;br /&gt;
 dia { DOM, LUN, MART, MIER, JUEV, VIER, SAB } diaX; &lt;br /&gt;
El identificador dia es la etiqueta opcional del tipo, y puede ser usada en subsecuentes declaraciones de variables del mismo tipo: &lt;br /&gt;
 enum Dia laborable, festivo;    // declara dos nuevas variables &lt;br /&gt;
aunque también se podría omitir el especificador enum (el compilador ya sabe  que Dia es de tipo enum): &lt;br /&gt;
 Dia laborable, festivo;         // equivalente al anterior &lt;br /&gt;
Como ocurre con las declaraciones de estructuras y uniones, si no existen otras variables del mismo tipo, puede omitirse la etiqueta con lo que tenemos un tipo anónimo:&lt;br /&gt;
 enum { DOM, LUN, MART, MIER, JUEV, VIER, SAB } diaX;&lt;br /&gt;
También aquí (como ocurre con las estructuras y uniones), el inconveniente de declarar un tipo anónimo es que después no podemos volver a declarar otra variable del mismo tipo. Observe que las expresiones que siguen no son equivalentes!!&lt;br /&gt;
 enum diaX { DOM, LUN, MART, MIER, JUEV, VIER, SAB };&lt;br /&gt;
 enum { DOM, LUN, MART, MIER, JUEV, VIER, SAB } diaX; &lt;br /&gt;
En [[C|C]], una variable enumerada puede recibir cualquier valor de tipo int sin que se realice ninguna otra comprobación; en cambio [[C++|C++]] es más fuertemente tipado en este sentido, y a una variable enumerada solo se le puede asignar uno de sus enumeradores. Ejemplo:&lt;br /&gt;
 diaX = LUN;       // Ok.&lt;br /&gt;
 diaX = 1;         // Ilegal, a pesar que LUN == 1 &lt;br /&gt;
Las enumeraciones proporcionan un modo muy flexible de asociar nombres con valores, algo que también puede hacerse con los #define, sin embargo, las enumeraciones (aún de un solo elemento) presentan ventajas entre las que podemos señalar:&lt;br /&gt;
Los valores pueden ser auto-generados &lt;br /&gt;
Las variables de enumeradas ofrecen la      posibilidad de comprobación. &lt;br /&gt;
El depurador puede ser capaz de imprimir los      valores de los enumeradores en su forma simbólica (lo que facilita      grandemente las comprobaciones). &lt;br /&gt;
En la práctica, las enumeraciones proporcionan un lugar (&amp;quot;placeholder&amp;quot;) muy conveniente para almacenar constantes enteras como códigos de error o de cualquier otro tipo que podamos manejar en nuestras aplicaciones. Por ejemplo: en lugar de utilizar&lt;br /&gt;
  #define ERROR_NO_ERROR    0    &lt;br /&gt;
  #define ERROR_NOT_FOUND   1&lt;br /&gt;
  #define ERROR_BUSY        2&lt;br /&gt;
  #define ERROR_FULL        3&lt;br /&gt;
  ...&lt;br /&gt;
Es más conveniente utilizar un enumerador:&lt;br /&gt;
 enum ERRORS { NO_ERROR, NOT_FOUND, BUSY, FULL, ... } err; &lt;br /&gt;
Los tipos enum pueden aparecer en cualquier sitio donde sea permitido un entero. Ejemplo:&lt;br /&gt;
 enum dias { LUN, MAR, MIER, JUEV, VIER, SAB, DOM } diaX;&lt;br /&gt;
 enum dias diapago;&lt;br /&gt;
 typedef enum dias DIAS;&lt;br /&gt;
 DIAS *diaptr;&lt;br /&gt;
 int i = MIER;&lt;br /&gt;
 diaX = LUN;          // Ok.&lt;br /&gt;
 *diaptr = diaX;      // Ok.&lt;br /&gt;
 LUN = MIER;          // ILEGAL: LUN es una constante! &lt;br /&gt;
==Visibilidad==&lt;br /&gt;
Las etiquetas de los enum comparten el mismo espacio de nombres que los de estructuras y uniones. Los [[Identificadores (Informática)|identificadores]] de los enumeradores comparten el mismo espacio que los identificadores de las variables ordinarias; de aquí se deduce que los nombres de los enumeradores de las distintas enumeraciones, tienen que ser diferentes (los valores no tienen porqué serlo ni aún en la misma enumeración).&lt;br /&gt;
===Ejemplo===&lt;br /&gt;
 int dom = 11;&lt;br /&gt;
 {&lt;br /&gt;
    enum dias { dom, lun, mar, mier, juev, vier, sab } diaX;&lt;br /&gt;
    /* el enumerador dom oculta otra declaracion de int dom */&lt;br /&gt;
    struct dias { int i, j;};   // ILEGAL: identificador dias ya usado&lt;br /&gt;
    double mar;                 // ILEGAL: redefinicion de mar&lt;br /&gt;
 }&lt;br /&gt;
 dom = 12;                      // int dom vuelve a ser visible &lt;br /&gt;
==Asignaciones a tipo enum==&lt;br /&gt;
 &lt;br /&gt;
En el [[Compilador|compilador]] Borland [[C++|C++]] 5.5, las reglas para expresiones que contengan tipos enum pueden forzarse a ser más estrictas activando el conmutador -A (que significa ANSI C++ estricto), con lo que el compilador refuerza las reglas con mensajes de error. Así, al asignar un entero a una variable enum (como en el ejemplo) produciría un error.&lt;br /&gt;
 enum color { Rojo, Verde, Azul };&lt;br /&gt;
  int f() {&lt;br /&gt;
    color c;&lt;br /&gt;
    c = 0;    // Incorrecto: a 'c' solo se le puede asignar Rojo, Verde o Azul&lt;br /&gt;
    return c;&lt;br /&gt;
  }&lt;br /&gt;
En estos casos de compilación estricta, se obtiene también un error cuando se pasa un entero como parámetro a una función que espera un enum o viceversa. Estudie el ejemplo propuesto teniendo en cuenta que el resultado de la expresión flag1|flag2 (OR inclusivo entre bits) es un entero.&lt;br /&gt;
 &lt;br /&gt;
En estos casos de compilación estricta, se obtiene también un error cuando se pasa un entero como parámetro a una función que espera un enum o viceversa. Estudie el ejemplo propuesto teniendo en cuenta que el resultado de la expresión flag1 | flag2 (OR inclusivo entre bits) es un entero.&lt;br /&gt;
 #include &amp;lt;iostream.h&amp;gt;&lt;br /&gt;
 enum En { flag1 = 0x01, flag2 = 0x02 };&lt;br /&gt;
 int f1(En) {                 // L.3:&lt;br /&gt;
   return (flag1 + 1);&lt;br /&gt;
 }&lt;br /&gt;
 void f2() {&lt;br /&gt;
   int x = f1(flag1|flag2);   // L.7:&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; x &amp;lt;&amp;lt; endl;&lt;br /&gt;
 }&lt;br /&gt;
 int main () {&lt;br /&gt;
   f2();&lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
Aquí En es un tipo enum; los enumeradores flag1 y flag2 son constantes de enumeración de valores 1 y 2 respectivamente, que han definidas en formato hexadecimal.&lt;br /&gt;
Al intentar compilar se produce un error: Cannot convert 'int' to 'En' in function f2() ya que la invocación a f1 en L7 espera un enum tipo En (como indica el prototipo de L3), pero se le pasa un int, ya que como se ha apuntado, la expresión flag1|flag2 produce un entero.&lt;br /&gt;
Para arreglarlo, aplicamos un modelado de tipo al argumento pasado a la invocación en L.7, que lo transforma en el tipo exigido, con lo que la compilación se realiza sin novedad.&lt;br /&gt;
 #include &amp;lt;iostream.h&amp;gt;&lt;br /&gt;
 enum En { flag1 = 0x01, flag2 = 0x02 };&lt;br /&gt;
 int f1(En) {                       // L.3:&lt;br /&gt;
   return (flag1 + 1);&lt;br /&gt;
 }&lt;br /&gt;
 void f2() {&lt;br /&gt;
   int x = f1(En (flag1|flag2) );   // L.7bis:&lt;br /&gt;
   cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; x &amp;lt;&amp;lt; endl;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
 int main () {&lt;br /&gt;
   f2();&lt;br /&gt;
 }&lt;br /&gt;
 Salida:&lt;br /&gt;
 El valor es: 2&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Véase también  ==&lt;br /&gt;
*[[Sobrecarga de enumeraciones (Informática)|Sobrecarga de enumeraciones (Informática)]] &lt;br /&gt;
*[[Constante (Informática)|Constante]]&lt;br /&gt;
*[[Parámetros y argumentos (programación)|Parámetros y argumentos (programación)]]&lt;br /&gt;
*[[Constantes de enumeración (Informática)|Constantes de enumeración (Informática)]]&lt;br /&gt;
*[[Funciones virtuales|Funciones virtuales]] &lt;br /&gt;
&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://www.zator.com/Cpp/E4_8.htm Enumeraciones]&lt;br /&gt;
*   [http://msdn.microsoft.com/es-es/library/cc138362.aspx Tipos de enumeración (Guía de programación de C#]&lt;br /&gt;
*  [http://shadowsecurity.info/449/programacion-en-c.html Programacion en C++ enumeracion usando enum]&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]] [[Category:Programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Invocaci%C3%B3n_de_funciones_(programaci%C3%B3n)&amp;diff=3024782</id>
		<title>Invocación de funciones (programación)</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Invocaci%C3%B3n_de_funciones_(programaci%C3%B3n)&amp;diff=3024782"/>
		<updated>2017-12-12T18:12:24Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre=Invocación de funciones (programación)|imagen=Invocacion_de_Funciones.jpeg   |concepto=Implica pasarle el control de la ejecución del programa, así como los argumentos ó parámetros que requiere para realizar su tarea}}&lt;br /&gt;
'''Invocación de funciones (programación)'''. Una invocación ó llamada a una [[Función (programación)|función]] implica pasarle el control de la ejecución del programa, así como los argumentos ó parámetros que requiere para realizar su tarea, se realiza colocando el nombre de la función y los argumentos actuales en el mismo orden que los parámetros formales correspondientes. La sintaxis del lenguaje permite también la invocación de funciones a través de punteros a funciones e incluso de referencias, aunque esto último sea menos frecuente. Cuando las funciones son miembros de clases la invocación sigue una sintaxis especial. En estos casos incluso existen operadores especiales para invocarlas a través de sus punteros.&lt;br /&gt;
== Evaluación de argumentos ==&lt;br /&gt;
La gramática [[C++]] permite utilizar expresiones como argumentos en la invocación de funciones. Estas expresiones son evaluadas, y sus posibles efectos laterales tienen efecto, antes que la función sea cargada en la pila. Sin embargo, tales prácticas son en general desaconsejadas, pues dan lugar a código difícil de leer. Ejemplo:&lt;br /&gt;
 int x foo (int x) { return x+2; }&lt;br /&gt;
 ...&lt;br /&gt;
 int main() {&lt;br /&gt;
  int n = 3;&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;foo -&amp;gt; &amp;quot; &amp;lt;&amp;lt; foo(n++) &amp;lt;&amp;lt; endl;&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;foo -&amp;gt; &amp;quot; &amp;lt;&amp;lt; foo(++n) &amp;lt;&amp;lt; endl;&lt;br /&gt;
  ...&lt;br /&gt;
 }&lt;br /&gt;
Salida:&lt;br /&gt;
 foo -&amp;gt;5&lt;br /&gt;
 foo -&amp;gt;7&lt;br /&gt;
El orden de evaluación de los argumentos es indefinido (depende del [[compilador]]), por lo que no es recomendable utilizar expresiones que dependan del orden de evaluación de los parámetros. Ejemplo:&lt;br /&gt;
 int x foo (int x, int y) { return x + y; }&lt;br /&gt;
 ...&lt;br /&gt;
 int main() {&lt;br /&gt;
  int n = 3;&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;foo -&amp;gt; &amp;quot; &amp;lt;&amp;lt; foo(n++, n) &amp;lt;&amp;lt; endl;&lt;br /&gt;
  ...&lt;br /&gt;
 }&lt;br /&gt;
En estas condiciones es imposible predecir si la salida será 7 u 8.&lt;br /&gt;
== Conversión de argumentos ==&lt;br /&gt;
A continuación de la evaluación, los valores resultantes de las expresiones son convertidos automáticamente a los mismos tipos que los declarados para los parámetros formales.&lt;br /&gt;
Ejemplo (suponiendo la definición del caso anterior):&lt;br /&gt;
 cout &amp;lt;&amp;lt; foo(x + 3.5);    // -&amp;gt; 8&lt;br /&gt;
Cuando no se ha declarado previamente un prototipo de la [[Función (programación)|función]], [[C++]] realiza una invocación a la función convirtiendo la totalidad de los argumentos según las reglas de Conversiones aritméticas estándar. En cambio, si existe un prototipo de función en el ámbito, [[C++]] convierte los argumentos al tipo declarado para los parámetros.&lt;br /&gt;
&lt;br /&gt;
Cuando un prototipo incluye puntos suspensivos (...), el [[compilador]] convierte todos los argumentos (si los hay) como en cualquier otro caso hasta la elipsis, después conforma todos los demás parámetros (que han sido declarados [[Variable en programación|variables]]) según las reglas usuales para argumentos de funciones que no tienen prototipo.&lt;br /&gt;
&lt;br /&gt;
Si existe un prototipo, el número de argumentos debe coincidir con los declarados (a menos que existan puntos suspensivos). El tipo de los argumentos también debe coincidir, pero solo hasta el punto en que una asignación pudiera realizar legalmente una conversión (del tipo realmente pasado al tipo esperado). También existe el recurso de hacer una conversión explícita (&amp;quot;cast&amp;quot;) para convertir un argumento en un tipo que sea aceptable por el prototipo (Modelado de tipos).&lt;br /&gt;
&lt;br /&gt;
En [[C++]] los parámetros son pasados por valor, lo que significa que existen copias locales de los argumentos formales, estas copias son variables locales de la función invocada.&lt;br /&gt;
== Conversión de parámetros ==&lt;br /&gt;
Es posible incluir sentencias de asignación en la lista de argumentos de invocación de funciones, aunque sea una práctica desaconsejable, pues da lugar a código difícil de interpretar y en ocasiones sin mucho sentido.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, en [[C++]] es válido el siguiente código que compila sin problema:&lt;br /&gt;
 #include &amp;lt;iostream.h&amp;gt;&lt;br /&gt;
 void fun (char* p, int n) {&lt;br /&gt;
  for (int i = 1; i &amp;lt;= n ; i++) cout &amp;lt;&amp;lt; p &amp;lt;&amp;lt; i &amp;lt;&amp;lt; endl;&lt;br /&gt;
 }&lt;br /&gt;
 void main() {              // =============&lt;br /&gt;
  char* pt1 = &amp;quot;Hola, que tal!! &amp;quot;;&lt;br /&gt;
  char* pt2;&lt;br /&gt;
  int x;&lt;br /&gt;
  fun(pt2 = pt1, x =5);   // desaconsejado !!&lt;br /&gt;
 }&lt;br /&gt;
 Salida:&lt;br /&gt;
 Hola, que tal!! 1&lt;br /&gt;
 Hola, que tal!! 2&lt;br /&gt;
 Hola, que tal!! 3&lt;br /&gt;
 Hola, que tal!! 4&lt;br /&gt;
 Hola, que tal!! 5&lt;br /&gt;
== Formas de invocación de funciones ==&lt;br /&gt;
La forma de efectuarse la invocación de funciones y el tratamiento de [[Identificadores (Informática)|identificadores]] globales, son cuestiones que están relacionadas, ya que ciertas formas de llamada presuponen determinado tratamiento de los identificadores.&lt;br /&gt;
&lt;br /&gt;
Estos detalles tienen importancia cuando se quiere mezclar código [[C++]] con el generado por otros [[Lenguaje de programación|lenguajes de programación]], bien porque necesitemos llamar una rutina en otro lenguaje desde un programa [[C++]], o porque desde otro lenguaje necesitemos utilizar una rutina escrita en [[C++]].  La razón es que todos los lenguajes no se comportan de la misma forma, variando ciertas cuestiones de detalle. &lt;br /&gt;
&lt;br /&gt;
Estos detalles se refieren concretamente a:&lt;br /&gt;
* El tratamiento dado a los identificadores&lt;br /&gt;
* Convención de llamada a utilizar, que compone tres cuestiones: Limpieza de la pila; paso de parámetros, y tratamiento de los identificadores globales.&lt;br /&gt;
&lt;br /&gt;
Los detalles sobre la forma de proceder en cada caso dependen de la plataforma. En la mayoría de compiladores es posible fijar ciertas directrices sobre la forma de proceder en estos casos, tanto a nivel global como a nivel particular de algunos identificadores. Los comentarios que siguen se refieren al compilador Borland C++, aunque salvando algunas cuestiones de detalle, pueden hacerse extensivos al resto de plataformas (MS Visucal C++, GNU g++, etc.)&lt;br /&gt;
 &lt;br /&gt;
=== Tratamiento de identificadores ===&lt;br /&gt;
Una característica que distingue a unos compiladores (lenguajes) de otros, es el tratamiento dado a los identificadores (nombres) de los objetos; lo que se conoce como sistema de codificación de nombres (&amp;quot;name encoding scheme&amp;quot;). De este sistema depende que durante las fases intermedias de la compilación, los identificadores sean guardados tal como los escribe el programador o sufran mutaciones más o menos importantes.&lt;br /&gt;
&lt;br /&gt;
En [[C++]], cuando está activada la opción -u (lo que ocurre por defecto), el [[compilador]] guarda todos los [[identificadores]] globales en su grafía original (mayúsculas, minúsculas o mixta), añadiendo automáticamente un guión bajo &amp;quot;_&amp;quot; (&amp;quot;Underscore&amp;quot; ASCII 95) delante de cualquier identificador global, ya sea de función (todas lo son), o de [[Variable en programación|variable]]. Para modificar este comportamiento se puede utilizar la opción -u- como parámetro en la línea de comando del [[compilador]].&lt;br /&gt;
&lt;br /&gt;
En el caso de identificadores que han sido modificados con el identificador [[Pascal|Pascal]], no se añade ningún guión, pero el identificador es convertido a mayúsculas&lt;br /&gt;
=== Convención de llamada ===&lt;br /&gt;
En informática se han consagrado diversas formas de invocación de funciones, las más frecuentes son las siguientes: Rápida;  C;  Pascal;  Registro y  Estándar.&lt;br /&gt;
&lt;br /&gt;
'''Estas convenciones se diferencian en:'''&lt;br /&gt;
* La forma que cada una utiliza para la limpieza de la pila (stack).&lt;br /&gt;
* El orden de paso de parámetros (derecha a izquierda o a la      inversa).&lt;br /&gt;
* El uso o no de mayúsculas y minúsculas, y ciertos prefijos en los identificadores globales.&lt;br /&gt;
La especificación de la forma que se utilizará en el programa, puede hacerse a nivel global o solo a nivel particular de algunas funciones específicas.&lt;br /&gt;
&lt;br /&gt;
Para indicarlo a nivel global se utiliza alguno de los comandos específicos del compilador (son los indicados en cada caso). En estos casos, las palabras clave: _ _pascal,  _ _fastcall, o _ _stdcall pueden utilizarse para declarar que una rutina o función utiliza específicamente una convención distinta de la señalada como general.&lt;br /&gt;
&lt;br /&gt;
La forma de indicarlo a nivel particular es mediante el uso de ciertas palabras reservadas para que sea utilizada una forma específica en lugar de la que tenga asignada el compilador por defecto. Estas palabras deben indicarse en la declaración o prototipo, y delante del especificador de invocación de la función. Son las siguientes:  _ _cdecl, _ _pascal, _ _fastcall, _ _msfastcall y _ _stdcall.&lt;br /&gt;
==== Invocación rápida ====&lt;br /&gt;
Esta opción se ha incluido en el [[compilador]] [[C++]] para compatibilidad con el de [[Microsoft|Microsoft]]. Indica al [[compilador]] que utilice convención de llamada de MS VC++ para todas las funciones que no tengan explícitamente declarada otra forma.&lt;br /&gt;
En esta convención, las dos primeras DWORD  o argumentos más pequeños pasan a los registros ECX y EDX; todos los demás pasan de derecha a izquierda. La función invocada es responsable de desalojar los argumentos de la pila.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Formas de indicarlo al compilador:'''&lt;br /&gt;
* Especificador global:  comando de compilación -pm&lt;br /&gt;
* Especificador particular:  especificador _ _msfastcall&lt;br /&gt;
Ejemplo:&lt;br /&gt;
 int __msfastcall funcDos (x, y);&lt;br /&gt;
&lt;br /&gt;
==== Invocación C ====&lt;br /&gt;
Esta opción indica al [[compilador]] utilizar la secuencia de llamada estándar C para funciones, es decir: generar guiones de subrayado -guiones bajos-; distinguir mayúsculas de minúsculas (no transformar minúsculas en mayúsculas); pasar parámetros de derecha a izquierda.En [[C++]] se utiliza por defecto esta convención de llamada.&lt;br /&gt;
&lt;br /&gt;
En este tipo de invocación, la colocación de parámetros en la pila se realiza de derecha a izquierda, lo que significa que el último argumento de la función es colocado el primero y el primero es colocado el último. Esto hace que estas funciones puedan utilizar un número variable de parámetros en cada invocación. Es decir, no tienen que pasar necesariamente el mismo número de parámetros en todas las invocaciones que se realicen a dicho código. Las [[Función (programación)|funciones]] que gozan de esta particularidad son denominadas &amp;quot;variadic&amp;quot; en la literatura inglesa.  La función que realiza la llamada (&amp;quot;caller&amp;quot;) es la encargada de limpiar la pila, lo que provoca que el código de este tipo de ejecutables sean ligeramente mayores que en el resto de convenciones, en las que es la función invocada (&amp;quot;called&amp;quot;) la que limpia la pila.&lt;br /&gt;
&lt;br /&gt;
'''Formas de indicarlo al compilador:'''&lt;br /&gt;
* Especificador global: comandos de compilación -pc, -p-  &lt;br /&gt;
* Especificador particular:  especificadores cdecl,  _cdecl y _ _cdecl  en la declaración de la función o identificador      global (las tres formas son equivalentes).&lt;br /&gt;
====  Invocación Pascal ====&lt;br /&gt;
Esta opción indica al [[compilador]] utilizar la secuencia de llamada de [[Pascal|Pascal]] para las funciones: no generar guiones de subrayado, forzar identificadores a mayúsculas, limpieza de la pila por la función que realiza la llamada y paso de parámetros de izquierda a derecha.&lt;br /&gt;
&lt;br /&gt;
Generalmente las llamadas de función resultantes son más pequeñas y rápidas que las generadas con la convención C, y también utilizan la pila para el paso de parámetros. En este caso, las funciones deben pasar el número exacto de argumentos y del tipo adecuado. Los identificadores de las funciones declaradas con este modificador están sujetos al planchado de nombres.&lt;br /&gt;
&lt;br /&gt;
En la programación para entornos Windows 3.x se exigía que las llamadas al Sistema utilizaran esta convención.&lt;br /&gt;
&lt;br /&gt;
'''Formas de indicarlo al compilador:'''&lt;br /&gt;
* Especificador global: comando de compilación -p&lt;br /&gt;
* Especificador particular:  especificadores pascal, _pascal o _ _pascal  (las tres formas      son equivalentes).&lt;br /&gt;
==== Invocación Registro ====&lt;br /&gt;
Esta opción indica que se deben generar todas las funciones utilizando la convención de paso de parámetros a registro. Esto supone que los tres primeros parámetros (de izquierda a derecha) se colocan en los registros EAX, EDX y ECX. En caso que se trate de objetos que no quepan en los registros, por ejemplo, si son números fraccionarios o estructuras, no se utilizan los registros, sino la pila como es usual.&lt;br /&gt;
&lt;br /&gt;
Las funciones declaradas con los identificadores _cdecl o _pascal no pueden utilizar simultáneamente este especificador, porque ambas utilizan la pila para el paso de parámetros.&lt;br /&gt;
Los identificadores de estas funciones están sujetos al planchado de nombres, además el compilador les añade una arroba '@' como prefijo. &lt;br /&gt;
&lt;br /&gt;
'''Formas de indicarlo al compilador:'''&lt;br /&gt;
* Especificador global: comando de compilación -pr&lt;br /&gt;
* Especificador particular: especificadores _fastcall y  _ _fastcall (ambas formas son equivalentes).&lt;br /&gt;
Ejemplo:&lt;br /&gt;
 int _msfastcall funcTres (x, y, z);&lt;br /&gt;
&lt;br /&gt;
====  Invocación estándar ====&lt;br /&gt;
Esta opción indica al [[compilador]] que debe utilizar la secuencia de llamada estándar para funciones: no generar guiones bajos; conservar mayúsculas y minúsculas; la función invocada limpia la pila, y colocación de parámetros de derecha a izquierda.&lt;br /&gt;
&lt;br /&gt;
A diferencia de la invocación C, esta convención exige pasar el número y tipo de argumentos exacto. Estas funciones cumplen con la convención de argumentos de Win32, y están sujetas a planchado de nombres. &lt;br /&gt;
&lt;br /&gt;
'''Formas de indicarlo al compilador:'''&lt;br /&gt;
* Especificador global: comando de compilación -ps&lt;br /&gt;
* Especificador particular: especificador _ _stdcall. y _stdcall&lt;br /&gt;
Ejemplo:&lt;br /&gt;
 #define WINAPI __stdcall&lt;br /&gt;
 #include &amp;lt;windows.h&amp;gt;&lt;br /&gt;
 int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,&lt;br /&gt;
                    PSTR szCmdLine, int iCmdShow) {&lt;br /&gt;
   MessageBox (NULL, TEXT (&amp;quot;Hola Windows 98&amp;quot;), TEXT (&amp;quot;Saludo&amp;quot;), 0);&lt;br /&gt;
   return 0;&lt;br /&gt;
 }&lt;br /&gt;
Dado que en la programación [[Microsoft Windows|Windows]], la función WinMain es equivalente a la main de C/[[C++]], la sentencia anterior constituye el inicio de cualquier aplicación Windows.  Su sintaxis señala explícitamente al [[compilador]] que debe utilizar para ella la convención de llamada estándar.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Puede Consultar  ==&lt;br /&gt;
*[[Declaración de funciones|Declaración de funciones]] &lt;br /&gt;
*[[Función (programación)|Función (programación)]]&lt;br /&gt;
*[[Funciones virtuales|Funciones virtuales]] &lt;br /&gt;
*[[Sobrecarga de funciones (programación)|Sobrecarga de funciones (programación)]]&lt;br /&gt;
*[[Parámetros y argumentos (programación)|Parámetros y argumentos (programación)]]&lt;br /&gt;
*[[Referencias (programación)|Referencias (programación)]]&lt;br /&gt;
&lt;br /&gt;
== Fuentes  ==&lt;br /&gt;
Artículos consultados&lt;br /&gt;
*www.zator.com/Cpp/E4_4_6.htm Invocación de funciones y conversión de argumentos]&lt;br /&gt;
*www.zator.com/Cpp/E4_4_6a.htm Formas de invocación de funciones]&lt;br /&gt;
*www.sistemas.itlp.edu.mx/tutoriales/pascal/u6_6_2_2.html Invocación de funciones]&lt;br /&gt;
==Enlaces externos==&lt;br /&gt;
*http://www.itescam.edu.mx/principal/sylabus/fpdb/recursos/r54217.DOC Invocación a funciones - ITESCAM]&lt;br /&gt;
*http://help.adobe.com/es_ES/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7f57.html Fundamentos de la utilización de funciones ]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]] [[Category:Programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Par%C3%A1metros_y_argumentos_(programaci%C3%B3n)&amp;diff=3024779</id>
		<title>Parámetros y argumentos (programación)</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Par%C3%A1metros_y_argumentos_(programaci%C3%B3n)&amp;diff=3024779"/>
		<updated>2017-12-12T18:11:59Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre=Parámetros y argumentos (programación)|imagen=   |concepto=Un argumento o parámetro es el medio a partir del cual podemos expandir el ámbito de variables locales de funciones, hacia otras funciones y además quienes nos permiten establecer comunicaciones entre funciones}}&lt;br /&gt;
'''Parámetros y argumentos (programación)''': Un argumento o parámetro es el medio a partir del cual podemos expandir el ámbito de variables locales de [[Función (programación)|funciones]], hacia otras funciones y además quienes nos permiten establecer comunicaciones entre funciones. Si nos vemos ante la necesidad de visualizar o modificar el valor de una [[Variable en programación|variable]] local en otra función que llamaremos, debemos invocar a dicha función haciendo referencia de su nombre, seguido de los parámetros o nombres de variables para las cuales, en teoría ampliaríamos su ámbito.&lt;br /&gt;
&lt;br /&gt;
Las palabras parámetro y argumento, aunque de significado similar, tiene distintas connotaciones semánticas: Se denominan parámetros los tipos declarados en el prototipo (que deben corresponder con los declarados en la definición). Cuando se realiza una llamada a la [[Función (programación)|función]], los &amp;quot;valores&amp;quot; pasados se denominan argumentos. A veces se utilizan también las expresiones argumentos formales, para los parámetros y argumentos actuales para los valores pasados.&lt;br /&gt;
  Parámetros (en prototipo o definición)   argumentos formales&lt;br /&gt;
  Valores pasados (en tiempo de ejecución)   argumentos actuales&lt;br /&gt;
== Sintaxis ==&lt;br /&gt;
La sintaxis utilizada para la declaración de la lista de parámetros formales es similar a la utilizada en la declaración de cualquier [[identificadores|identificador]].  Ejemplos:&lt;br /&gt;
 int func(void) {...}                  // sin parámetros&lt;br /&gt;
 inf func() {...}                      // ídem.&lt;br /&gt;
 int func(T1 t1, T2 t2, T3 t3=1) {...} // tres parámetros simples,&lt;br /&gt;
                                      // uno con argumento por  defecto&lt;br /&gt;
 int func(T1* ptr1, T2&amp;amp; tref) {...}    // los argumentos son un puntero y&lt;br /&gt;
                                      // una referencia.&lt;br /&gt;
 int func(register int i) {...}        // Petición de uso de registro para&lt;br /&gt;
                                      // argumento (entero)&lt;br /&gt;
 int func(char* str,...) {...}         /* Una cadena y cierto número de otros&lt;br /&gt;
             argumentos, o un número fijo de argumentos de tipos  variables */&lt;br /&gt;
Los argumentos son siempre objetos. Sus tipos pueden ser: escalares; estructuras; uniones, o enumeraciones; clases definidas por el usuario; punteros o referencias a estructuras y uniones, o punteros a funciones, a clases o a [[Matriz|matrices]]. El tipo void está permitido como único parámetro formal. Significa que la función no recibe ningún argumento.&lt;br /&gt;
Todos los parámetros de una función tienen ámbito del bloque de la propia función y la misma duración automática que la función.&lt;br /&gt;
&lt;br /&gt;
El único especificador de almacenamiento que se permite es register. En la declaración de parámetros también pueden utilizarse los modificadores volatile y const. Este último se utiliza cuando se pasan argumentos por referencia y queremos garantizar que la función no modificará el valor recibido. Ejemplo:&lt;br /&gt;
  int dimension(X x1, const X&amp;amp; x2)      // x2 NO se puede modificar!!&lt;br /&gt;
== Argumentos por defecto ==&lt;br /&gt;
[[C++]] permite tener valores por defecto para los parámetros. Esto supone que, si no se pasa el parámetro correspondiente, se asume un valor predefinido. La forma de indicarlo es declararlo en el prototipo de la función, como se muestra en el ejemplo (ambas expresiones son equivalentes).&lt;br /&gt;
  float mod (float x, float y = 0);&lt;br /&gt;
  float mod (float, float = 0);&lt;br /&gt;
Un argumento por defecto no puede ser repetido o cambiado en una siguiente declaración dentro del mismo ámbito. Por ejemplo:&lt;br /&gt;
 void func (int x = 5);&lt;br /&gt;
 ...&lt;br /&gt;
 void func (int x = 5);    // Error: repetición de argumento por defecto&lt;br /&gt;
 {                         // nuevo ámbito&lt;br /&gt;
    void func (x = 7);    // L.4 Correcto: esta función oculta a la anterior&lt;br /&gt;
 }                         // el ámbito anterior vuelve a ser visible&lt;br /&gt;
 void func (x = 7);        // Error: cambiar argumento por defecto&lt;br /&gt;
La gramática de [[C++]] exige que los parámetros con valores por defecto deben ser los últimos en la lista de parámetros, y que si en una ocasión falta algún argumento, los que le siguen también deben faltar (adoptar también los valores por defecto).&lt;br /&gt;
Los argumentos por defecto de métodos (funciones-miembro de clases) no pueden ser otros miembros a no ser que sean estáticos. &lt;br /&gt;
Los argumentos por defecto no pueden ser otros argumentos:&lt;br /&gt;
 x = somefunc (int x, int y = x);    // Error!&lt;br /&gt;
Los argumentos pasados por referencia solo pueden adoptar valores por defecto, estáticos, globales, o de un subespacio cualificado.&lt;br /&gt;
==  Argumentos: por valor y por referencia ==&lt;br /&gt;
Existen dos formas de pasar argumentos a las funciones: por valor y por referencia. El primero es utilizado por defecto con la declaración usual de parámetros. En el paso &amp;quot;por valor&amp;quot;, se crean copias de los argumentos pasados a la función, los cuales, junto a las variables locales (incluyendo el posible valor devuelto), y la dirección de vuelta a la rutina que efectúa la invocación, son pasados a la pila en la secuencia de llamada. Más tarde, cuando termina su ejecución definitivamente, es decir, cuando el control vuelve a la función que la invocó, toda esta información es sacada de la pila mediante la secuencia de retorno (y se pierde). Estos procesos suponen un consumo de tiempo y espacio (memoria), a veces considerable.&lt;br /&gt;
=== Paso por valor ===&lt;br /&gt;
Hemos visto que el paso de parámetros por valor significa que existen copias de los argumentos formales (estas copias son variables locales de la función llamada), y que una función no puede alterar ninguna variable de la función que la invocó.&lt;br /&gt;
* La única excepción es el caso de las matrices. Cuando se utiliza una matriz como argumento en la llamada a una función, el valor pasado es un puntero a la dirección de memoria del principio de la matriz.&lt;br /&gt;
Cuando los argumentos pasan por valor pero no hay concordancia entre el tipo de los argumentos actuales y los argumentos formales utilizados en la declaración de la función, entonces se produce un modelado de tipo antes de la asignación. &lt;br /&gt;
=== Pasar un puntero ===&lt;br /&gt;
En C clásico, cuando se desea que la función llamada pueda alterar el valor de variables de la función que la invoca, o ahorrar el espacio que supone la copia local de los argumentos (que pueden ser estructuras de datos muy grandes), la solución consistía en utilizar punteros a las variables respectivas como argumentos para la función (en vez de pasar las variables en sí mismas). A su vez, la función llamada debía declarar el parámetro como puntero, y acceder a la variable indirectamente a través de él. En otras palabras: cuando en C se desea que un valor X pase a una función F y que esta pueda alterar el valor de X en la función que la invocó, el argumento utilizado es &amp;amp;X (la dirección de X). De esta forma, aunque F recibe una copia de &amp;amp;X, puede alterar el valor original a través de esta dirección. Esta técnica puede tener sus ventajas.  Por ejemplo, si X es una estructura muy grande, pero puede tener efectos colaterales peligrosísimos y ser una fuente de errores difíciles de detectar.&lt;br /&gt;
=== Paso por referencia ===&lt;br /&gt;
[[C++]] permite utilizar la técnica del C clásico descrita arriba, pero también utilizar el paso de argumentos por referencia (en realidad es una variante semántica del proceso anteriormente descrito). Para ello se utiliza el declarador de referencia &amp;amp;.&lt;br /&gt;
Las referencias presentan las ventajas de los punteros, en el sentido que permiten modificar los valores de los objetos pasados como argumento, y de que permiten ahorrar espacio si hay que pasar objetos muy grandes, pero no presentan los peligros potenciales de aquellos. En caso necesario las referencias pueden declararse constantes, indicando así que la función invocada no modificará estos valores. En estos casos, la utilización de referencias obedece casi exclusivamente a razones de eficacia en el mecanismo de llamada.&lt;br /&gt;
=== Comparativa ===&lt;br /&gt;
A continuación se muestran tres implementaciones de una misma función; cada una con una forma distinta para paso del argumento.&lt;br /&gt;
&lt;br /&gt;
'''Implementación-1''':    Sistema clásico, paso &amp;quot;por valor&amp;quot;&lt;br /&gt;
 int pru1(int n) {   // n entero; pasa &amp;quot;por valor&amp;quot;&lt;br /&gt;
   return 3 * n;&lt;br /&gt;
 }&lt;br /&gt;
 ...&lt;br /&gt;
 int x, i = 4;&lt;br /&gt;
 x = pru1(i);        // ahora: x = 12, i = 4&lt;br /&gt;
 int&amp;amp; ry = i;&lt;br /&gt;
 x = pru (ry);       // ahora: x = 12, i = 4&lt;br /&gt;
La última sentencia no es un paso por referencia, sino por valor (a pesar de que el argumento actual sea una referencia).&lt;br /&gt;
&lt;br /&gt;
'''Implementación-2''':   Sistema clásico, paso de &amp;quot;punteros por valor&amp;quot; (seudo-referencia)&lt;br /&gt;
 void pru2(int* np) {  // np puntero-a-entero; pasa &amp;quot;por valor&amp;quot;&lt;br /&gt;
   *np = (*np) * 3;&lt;br /&gt;
 }&lt;br /&gt;
  . . .&lt;br /&gt;
 int x = 4;&lt;br /&gt;
 pru2(&amp;amp;x);             // ahora x = 12&lt;br /&gt;
En este caso, pasar el valor &amp;amp;x (dirección de x) como argumento, es equivalente a pasar un puntero a dicha variable (que es lo exigido en la definición de pru2). Es decir, la última línea se puede sustituir por las siguientes:&lt;br /&gt;
 int* ptr = &amp;amp;x         // define puntero-a-x&lt;br /&gt;
 pru2(ptr);            // pasa el puntero como argumento&lt;br /&gt;
&lt;br /&gt;
'''Implementación-3''':    Sistema [[C++]],  paso &amp;quot;por referencia&amp;quot;&lt;br /&gt;
 void pru3(int&amp;amp; n) { // n tipo &amp;quot;referencia-a-int&amp;quot;; pasa &amp;quot;por  referencia&amp;quot;&lt;br /&gt;
   n = 3 * n;&lt;br /&gt;
 }&lt;br /&gt;
  . . .&lt;br /&gt;
 int x = 4;&lt;br /&gt;
 pru3(x);            // ahora x = 12&lt;br /&gt;
En este último caso, la declaración int&amp;amp; n como parámetro de la función pru3, establece que este n sea declarado como &amp;quot;referencia-a-entero&amp;quot;, de forma que cuando se pasa el argumento x, la [[Función (programación)|función]] crea un valor n que es una especie de alias o espejo de x, de forma que la expresión n = 3*n tiene el mismo efecto que x = 3*x.&lt;br /&gt;
&lt;br /&gt;
En la declaración de una referencia, cuando el iniciador es una constante, o un objeto de tipo diferente que el referenciado, se crea un objeto temporal para el que la referencia actúa como un alias. Esta creación de objetos temporales es lo que permite la conversión de tipos referencia-a-tipoX cuando se utilizan como parámetros de funciones y no hay concordancia entre el valor recibido y el esperado (suponiendo que exista posibilidad de conversión).  &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Puede Consultar  ==&lt;br /&gt;
*[[Declaración de funciones|Declaración de funciones]] &lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Sobrecarga de enumeraciones (Informática)|Sobrecarga de enumeraciones (Informática)]] &lt;br /&gt;
*[[Función (programación)|Función (programación)]]&lt;br /&gt;
*[[Funciones virtuales|Funciones virtuales]] &lt;br /&gt;
*[[Sobrecarga de funciones (programación)|Sobrecarga de funciones (programación)]]&lt;br /&gt;
*[[Invocación de funciones (programación)|Invocación de funciones (programación)]]&lt;br /&gt;
== Fuente  ==&lt;br /&gt;
* [http://www.zator.com/Cpp/E4_4_5.htm#Ref-1 Parámetros y argumentos]&lt;br /&gt;
* [http://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Funciones#Definiendo_una_funci.C3.B3n Programación en C++/Funciones]&lt;br /&gt;
*  [http://www.edutecne.utn.edu.ar/semin.../param_y_argum_lenguaje_C.pdf Parámetros y Argumentos en el Lenguaje de Programación C++]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]] [[Category:Programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Sobrecarga_de_funciones_(programaci%C3%B3n)&amp;diff=3024771</id>
		<title>Sobrecarga de funciones (programación)</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Sobrecarga_de_funciones_(programaci%C3%B3n)&amp;diff=3024771"/>
		<updated>2017-12-12T18:11:36Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre=Sobrecarga de funcione (Programación)|imagen=   |concepto=&lt;br /&gt;
Es un mecanismo que permite asignar el mismo nombre a funciones distintas}}&lt;br /&gt;
'''Sobrecarga de funciones (Programación)'''. Es un mecanismo que permite asignar el mismo nombre a [[Función (programación)|funciones]] distintas. Para el compilador estas funciones no tienen nada en común a excepción del [[Identificadores (Informática)|identificador]], por lo que se trata en realidad de un recurso semántico del lenguaje que solo tiene sentido cuando se asigna el mismo nombre a funciones que realizan tareas similares en objetos diferentes.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, si tuviésemos objetos que fuesen diversos tipos de polígono (triángulo, cuadrado, pentágono, círculo, etc), tendría sentido denominar getArea a todas las funciones que calculasen el área de las diversas figuras, aunque naturalmente serían funciones distintas en cada caso. También tendría sentido denominar open a las funciones que abrieran un fichero o una línea de comunicación.&lt;br /&gt;
&lt;br /&gt;
Al tratar de los [[Operadores|operadores]], para el compilador son en realidad funciones, cuyos nombres y sintaxis de invocación son un tanto especiales y que la sobrecarga de estas funciones permite, por ejemplo, extender los conceptos de suma (+), asignación (=) o identidad (==), a objetos distintos de los básicos (preconstruidos en el lenguaje). El hecho de que acciones distintas pero conceptualmente semejantes, puedan ser representadas por el mismo operador (función), resulta a la postre una gran ayuda conceptual. Por ejemplo: puede hablarse de una &amp;quot;suma&amp;quot; de enteros y de una &amp;quot;suma&amp;quot; de complejos que serán gobernadas por versiones distintas del operador suma (+).&lt;br /&gt;
== Resolución de sobrecarga ==&lt;br /&gt;
Cuando se realiza la invocación de una función sobrecargada, es decir que existen otras del mismo nombre en el mismo ámbito, el compilador decide cual de ellas se utilizará mediante un proceso denominado resolución de sobrecarga (&amp;quot;Overload resolution&amp;quot;) aplicando ciertas reglas para verificar cual de las declaraciones se ajusta mejor al número y tipo de los argumentos utilizados. Es decir, donde existe máxima concordancia entre los argumentos actuales y formales. El proceso sigue unas reglas denominadas de congruencia estándar de argumentos; son las siguientes (en el orden precedencia señalado):&lt;br /&gt;
&lt;br /&gt;
1- Concordancia exacta en número y tipo. Esta concordancia puede incluir conversiones triviales, por ejemplo, nombre de matriz a puntero; nombre de función a puntero a función, y tipoX a const tipoX.&lt;br /&gt;
&lt;br /&gt;
2-  Concordancia después de realizar promociones de los tipos asimilables a enteros, por ejemplo: char; short; bool; enum (y sus correspondientes versiones unsigned) a int. También de tipos float a double.&lt;br /&gt;
&lt;br /&gt;
3- Concordancia después de realizar conversiones estándar. Por ejemplo: int a double; double a long double; clase-derivada* a Superclase*; tipoX* a void*.&lt;br /&gt;
&lt;br /&gt;
4- Concordancia después de realizar conversiones definidas por el usuario.&lt;br /&gt;
&lt;br /&gt;
5- Concordancia usando la elipsis (...) en funciones con número variable de parámetros.&lt;br /&gt;
&lt;br /&gt;
Si el análisis conduce a que dos funciones distintas concuerdan al mismo nivel máximo, entonces se produce un error y la sentencia es rehusada por el compilador declarando que existe una ambigüedad.&lt;br /&gt;
&lt;br /&gt;
Cuando las versiones sobrecargadas tienen dos o más argumentos, se procede a obtener la mejor concordancia para cada uno utilizando las reglas anteriores. Si una función tiene mejor concordancia que las demás para un argumento y mejor o igual para los restantes, es invocada. En caso contrario la llamada se rehúsa declarando ambigüedad.&lt;br /&gt;
El orden en que hayan sido declaradas las versiones sobrecargadas no influye para nada en la precedencia anterior.&lt;br /&gt;
Observe que en todo lo expuesto no se menciona para nada el valor devuelto. Esto significa que para que exista sobrecarga las funciones deben diferir en el tipo y/o número de argumentos. Por tanto, no es válido que solo difieran en el tipo de valor devuelto.&lt;br /&gt;
== Sobrecarga y valores devueltos ==&lt;br /&gt;
Con objeto de que el mecanismo de sobrecarga sea independiente del contexto, los valores devueltos por las funciones no son tenidos en cuenta a efectos del mecanismo de sobrecarga. Esto tiene importantes consecuencias prácticas. Por ejemplo:&lt;br /&gt;
 int func (int, char);       // L.1:&lt;br /&gt;
 int func (float, char);     // Ok versión sobrecargada&lt;br /&gt;
 void func (int, char);      // Error definición duplicada con L.1&lt;br /&gt;
== Sobrecarga y ámbito de nombres ==&lt;br /&gt;
Debe tener en cuenta que en C++ no existe el concepto de sobrecarga a través de ámbitos de nombres, por lo que las versiones sobrecargadas deben estar en el mismo ámbito. Por ejemplo:&lt;br /&gt;
 #include &amp;lt;iostream.h&amp;gt;&lt;br /&gt;
 namespace UNO {               // Subespacio exterior&lt;br /&gt;
   void func (int i) { cout &amp;lt;&amp;lt; &amp;quot;func(int) &amp;quot; &amp;lt;&amp;lt; endl; }&lt;br /&gt;
   namespace UNO_A {          // Subespacio anidado&lt;br /&gt;
      void func (float f) { cout &amp;lt;&amp;lt; &amp;quot;func(float) &amp;quot; &amp;lt;&amp;lt; endl; }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 void main (void) {            // =======&lt;br /&gt;
   int x = 1; float f = 1.1;&lt;br /&gt;
   UNO::func(x);&lt;br /&gt;
   UNO::func(f);&lt;br /&gt;
 }&lt;br /&gt;
 Salida:&lt;br /&gt;
 func(int)&lt;br /&gt;
 func(int)&lt;br /&gt;
En ambos casos no ha existido sobrecarga de la función a través de los subespacios de nombres; en ambos casos se ha invocado la misma versión de func; la del subespacio exterior.&lt;br /&gt;
Los ámbitos de las clases derivadas no son una excepción de esta regla general.&lt;br /&gt;
Cuando se precisa que el mecanismo de la sobrecarga funcione a través de ámbitos distintos, debe utilizarse la declaraciónusing o la directivausing.&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Puede Contactar  ==&lt;br /&gt;
*[[Declaración de funciones|Declaración de funciones]] &lt;br /&gt;
*[[Función (programación)|Función (programación)]]&lt;br /&gt;
*[[Funciones virtuales|Funciones virtuales]] &lt;br /&gt;
*[[Parámetros y argumentos (programación)|Parámetros y argumentos (programación)]]&lt;br /&gt;
*[[Invocación de funciones (programación)|Invocación de funciones (programación)]]&lt;br /&gt;
*[[Referencias (programación)|Referencias (programación)]]&lt;br /&gt;
== Fuentes  ==&lt;br /&gt;
* [http://www.zator.com/Cpp/E4_4_1a.htm Sobrecarga de funciones]&lt;br /&gt;
* [http://www.fismat.umich.mx/mn1/manual/node7.html Funciones en C ++]&lt;br /&gt;
* [http://c.conclase.net/curso/?cap=021 Funciones IV: Sobrecarga]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]] [[Category:Programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Funciones_virtuales&amp;diff=3024757</id>
		<title>Funciones virtuales</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Funciones_virtuales&amp;diff=3024757"/>
		<updated>2017-12-12T18:10:29Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Funciones virtuales |imagen=   |concepto=&lt;br /&gt;
Las funciones virtuales permiten que clases derivadas de una misma base (clases hermanas) puedan tener diferentes versiones de un método. Se utiliza la palabra-clave virtual para avisar al compilador que un método será polimórfico y que en las clases derivadas existen distintas definiciones del mismo}}&lt;br /&gt;
''' Funciones virtuales '''. Las funciones virtuales permiten que clases derivadas de una misma base (clases hermanas) puedan tener diferentes versiones de un método. Se utiliza la palabra-clave virtual para avisar al compilador que un método será polimórfico y que en las clases derivadas existen distintas definiciones del mismo. En respuesta, el &amp;quot;Linker&amp;quot; utiliza para ella una técnica especial, enlazado retrasado. La declaración de virtual en un método de una clase, implica que esta es polimórfica, y que probablemente no se utilizará directamente para instanciar objetos, sino como super-clase de una jerarquía.&lt;br /&gt;
&lt;br /&gt;
Esta posibilidad, que un mismo método puede exhibir distintos comportamientos en los descendientes de una base común, es precisamente lo que posibilita y define el polimorfismo. En estos casos se dice que las descendientes de la función virtual solapan o sobrecontrolan (&amp;quot;Override&amp;quot;) la versión de la superclase, pero esta versión de la superclase puede no existir en absoluto. Es probable que en ella solo exista una declaración del tipo: vitual void foo(); sin que exista una definición de la misma. Para que pueda existir la declaración de un método sin que exista la definición correspondiente, el método debe ser virtual puro  (un tipo particular dentro de los virtuales).&lt;br /&gt;
&lt;br /&gt;
Utilizaremos la siguiente terminología:  &amp;quot;función sobrecontrolada&amp;quot; o &amp;quot;solapada&amp;quot;, para referirnos a la versión en la superclase y &amp;quot;función sobrecontroladora&amp;quot; o &amp;quot;que solapa&amp;quot; para referirnos a la nueva versión en la clase derivada. Cualquier referencia al sobrecontrol o solapamiento (&amp;quot;Overriding&amp;quot;) indica que se está utilizando el mecanismo C++ de las funciones virtuales. Parecido pero no idéntico al de sobrecarga; conviene no confundir ambos conceptos. Más adelante intentamos aclarar sus diferencias .&lt;br /&gt;
== Sintaxis ==&lt;br /&gt;
Para declarar que un método de una clase base es virtual, su prototipo se declara como siempre, pero anteponiendo la palabra-clave virtual, que indica al compilador algo así como: &amp;quot;Será definido más tarde en una clase derivada&amp;quot;. Ejemplo:&lt;br /&gt;
virtual void dibujar();&lt;br /&gt;
Cuando se aplica a métodos de clase, el especificador virtual debe ser utilizado en la declaración, pero no en la definición si esta se realiza offline (fuera del cuerpo de la clase). Ejemplo:&lt;br /&gt;
class CL {&lt;br /&gt;
  ...&lt;br /&gt;
  virtual void func1();&lt;br /&gt;
  virtual void func2();&lt;br /&gt;
  virtual void func3() { ... }    // Ok. definición inline&lt;br /&gt;
};&lt;br /&gt;
virtual void CL::func1() { ... }  // Error!!&lt;br /&gt;
void CL::func2() { ... }          // Ok. definición offline&lt;br /&gt;
== Descripción ==&lt;br /&gt;
Al tratar del enlazado se indicaron las causas que justifican la existencia de este tipo de funciones en los lenguajes orientados a objeto (que aconsejamos repasar ahora. Para ayudarnos a comprender el problema que se pretende resolver con este tipo de funciones, exponemos una continuación del ejemplo de la clase Poligono al que nos referimos al tratar de las clases polimórficas:&lt;br /&gt;
&lt;br /&gt;
class Color { public: int R, G, B; };   // clase auxiliar&lt;br /&gt;
class Punto { public: float x, y; };    // clase auxiliar&lt;br /&gt;
&lt;br /&gt;
class Poligono {        // clase-base (polimórfica)&lt;br /&gt;
  protected:            // interfaz para las clases derivadas&lt;br /&gt;
  Punto centro;&lt;br /&gt;
  Color col;&lt;br /&gt;
  ...&lt;br /&gt;
  public:               // interfaz para los usuarios de poligonos&lt;br /&gt;
  virtual void dibujar() const;&lt;br /&gt;
  virtual void rotar(int grados);&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class Circulo : public Poligono {       // Un tipo de polígono&lt;br /&gt;
  protected:&lt;br /&gt;
  int radio;&lt;br /&gt;
  ...&lt;br /&gt;
  public:&lt;br /&gt;
  void dibujar() const;&lt;br /&gt;
  void rotar(int) { }&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class Triangulo : public Poligono {     // Otro tipo de pológono&lt;br /&gt;
  protected:&lt;br /&gt;
  Punto a, b, c;&lt;br /&gt;
  ...&lt;br /&gt;
  public:&lt;br /&gt;
  void dibujar() const;&lt;br /&gt;
  void rotar(int);&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Lo que se pretende con este tipo de jerarquía es que los usuarios de subclases manejen los distintos polígonos a través de su interfaz pública (sus miembros públicos), mientras que los implementadores (creadores de los diversos tipos de polígonos que puedan existir en la aplicación), compartan los aspectos representados por los miembros protegidos.&lt;br /&gt;
Los miembros protegidos son utilizados también para aquellos aspectos que son dependientes de la implementación. Por ejemplo, aunque la propiedad color será compartida por todas las clases de polígonos, posiblemente su definición dependa de aspectos concretos de la implementación, es decir, del concepto de &amp;quot;color&amp;quot; del sistema operativo, que probablemente estará en definiciones en ficheros de cabecera.&lt;br /&gt;
Los miembros en la superclase (polimórfica) representan las partes que son comunes a todos los miembros (a todos los polígonos) pero en la mayoría de los casos no es sencillo decidir cuáles serán estos miembros (propiedades o métodos) compartidos por todas las clases derivadas. Por ejemplo, aunque se puede definir un centro para cualquier polígono, mantener su valor puede ser una molestia innecesaria en la mayoría de los polígonos y sobre todo en los triángulos, mientras es imprescindible en los círculos y muy útil en el resto de polígonos equiláteros.&lt;br /&gt;
=== Ejemplo ===&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {                 // L.4:  Clase-base&lt;br /&gt;
  public: virtual int fun(int x) {return x * x;}   // L.5 virtual&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {     // Clase derivada-1&lt;br /&gt;
  public:  int fun (int x) {return x + 10;}        // L.8 virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {     // Clase derivada-2&lt;br /&gt;
  public:  int fun (int x) {return x + 15;}        // L.11 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {          // =========&lt;br /&gt;
  B b; D1 d1; D2 d2;      // M.1&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; b.fun(10)     &amp;lt;&amp;lt; endl;  // M.2:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.fun(10)    &amp;lt;&amp;lt; endl;  // M.3:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.fun(10)    &amp;lt;&amp;lt; endl;  // M.4:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.B::fun(10) &amp;lt;&amp;lt; endl;  // M.5:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.B::fun(10) &amp;lt;&amp;lt; endl;  // M.6:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
Comentario&lt;br /&gt;
Definimos una clase-base B, en la que definimos una función virtual fun; a continuación derivamos de ella dos subclases D1 y D2, en las que definimos sendas versiones de fun que solapan la versión existente en la clase-base.&lt;br /&gt;
Las versiones de fun en L.8 y L.11 son virtuales, a pesar de no tener el declarador virtual indicado explícitamente. Estas versiones son un caso de polimorfismo, y solapan a la versión definida en la clase-base.&lt;br /&gt;
La línea M.1 instancia tres objetos de las clases anteriormente definidas.  En las líneas M.2 a M.4 comprobamos sus valores, que son los esperados (en cada caso se ha utilizado la versión de fun adecuada al objeto correspondiente).  Observe que la elección de la función adecuada no se realiza por el análisis de los argumentos pasados a la función como en el caso de la sobrecarga (aquí los argumentos son iguales en todos los casos), sino por la &amp;quot;naturaleza&amp;quot; del objeto que invoca la función;  esta es precisamente la característica distintiva del del polimorfismo.&lt;br /&gt;
Las líneas M.5 y M.6 sirven para recordarnos que a pesar del solapamiento, la versión de fun de la superclase sigue existiendo, y es accesible en los objetos de las clases derivadas utilizando el sobrecontrol adecuado.&lt;br /&gt;
Nota: la utilización del operador :: de acceso a ámbito anula el mecanismo de funciones virtuales, pero es aconsejable no usarlo en demasía, pues conduce a programas más difíciles de mantener. Como regla general, este tipo de calificación solo debe utilizarse para acceder a miembros del subobjeto heredado como es el caso del ejemplo.&lt;br /&gt;
Ejemplo-2&lt;br /&gt;
Hagamos ahora de abogados del diablo compilando el ejemplo anterior con la única modificación de que el método fun de B no sea virtual, sino un método normal. Es decir, la sentencia L.5, quedaría como:&lt;br /&gt;
public: int fun(int x) {return x * x;}    // L.5b no virtual!!&lt;br /&gt;
En este caso, comprobamos que el resultado coincide exactamente con el anterior, lo que nos induciría a preguntar ¿Para qué diablos sirven entonces las funciones virtuales?&lt;br /&gt;
Ejemplo-3&lt;br /&gt;
La explicación podemos encontrala fácilmente mediante una pequeña modificación en el programa: en vez de acceder directamente a los miembros de los objetos utilizando el selector directo de miembro, en las sentencias de salida, realizaremos el acceso mediante punteros a las clases correspondientes. De estos punteros declararemos dos tipos: a la superclase y a las clases derivadas (por brevedad hemos suprimido las sentencias de comprobación M.5 y M.6).&lt;br /&gt;
El nuevo diseño sería el siguiente:&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {                 // L.4: Clase-base&lt;br /&gt;
  public: virtual int fun(int x) {return x * x;}  // L.5 virtual&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {     // Clase derivada-1&lt;br /&gt;
  public: int fun (int x) {return x + 10;}        // L.8 virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {     // Clase derivada-2&lt;br /&gt;
  public: int fun (int x) {return x + 15;}        // L.11 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {          // =========&lt;br /&gt;
  B b; D1 d1; D2 d2;      // M.1&lt;br /&gt;
  B* bp = &amp;amp;b; B* bp1 = &amp;amp;d1; B* bp2 = &amp;amp;d2;           // M.1a&lt;br /&gt;
  D1* d1p = &amp;amp;d1; D2* d2p = &amp;amp;d2;                     // M.1b&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;   // M.2a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp1-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.3a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp2-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.3b:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1p-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.4a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2p-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.4b:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
Comentario&lt;br /&gt;
La sentencia M.1a define tres punteros a la clase-base. No obstante, dos de ellos se utilizan para señalar objetos de las sub-clases. Esto es típico de los punteros en jerarquías de clases. Precisamente se introdujo esta &amp;quot;relajación&amp;quot; en el control de tipos, para facilitar ciertas funcionalidades de las clases polimórficas.&lt;br /&gt;
La sentencia M.1b define sendos punteros a subclase, que en este caso si son aplicados a entidades de su mismo tipo.&lt;br /&gt;
Teniendo en cuenta las modificaciones efectuadas, y como no podía ser menos, las nuevas salidas son exactamente análogas a las del ejemplo inicial.&lt;br /&gt;
Ejemplo-4&lt;br /&gt;
Si suprimimos la declaración de virtual para la sentencia L.5 y volvemos a compilar el programa, se obtienen los resultados siguientes:&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
En ausencia de enlazado retrasado, las sentencias M.3a y M.3b, que acceden a métodos de objetos a través de punteros a la superclase, se refieren a los métodos heredados (que se definieron en la superclase). En este contexto pueden considerarse equivalentes los siguientes pares de expresiones:&lt;br /&gt;
bp1-&amp;gt;fun(10)  ==  d1.B::fun(10)&lt;br /&gt;
bp2-&amp;gt;fun(10)  ==  d2.B::fun(10)&lt;br /&gt;
&lt;br /&gt;
Hay ocasiones es que este comportamiento no interesa. Precisamente en las clases abstractas, en las que la definición de B::fun() no existe en absoluto, y expresiones como M.3a y M.3b conducirían a error si fun() no fuese declarada virtual pura en B.&lt;br /&gt;
Ejemplo-5&lt;br /&gt;
Presentamos una variación muy interesante del primer ejemplo, en el que simplemente hemos eliminado la línea 11, de forma que no existe definición específica de fun en la subclase D2.&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {                 // L.4:  Clase-base&lt;br /&gt;
  public:  virtual int fun(int x) {return x * x;}   // L.5 virtual&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {     // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 10;}         // L.8 virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B { };  // Clase derivada&lt;br /&gt;
&lt;br /&gt;
int main(void) {          // =========&lt;br /&gt;
  B b; D1 d1; D2 d2;      // M.1&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; b.fun(10)     &amp;lt;&amp;lt; endl;  // M.2:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.fun(10)    &amp;lt;&amp;lt; endl;  // M.3:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.fun(10)    &amp;lt;&amp;lt; endl;  // M.4:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.B::fun(10) &amp;lt;&amp;lt; endl;  // M.5:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.B::fun(10) &amp;lt;&amp;lt; endl;  // M.6:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
Comentario&lt;br /&gt;
El objeto d2 no dispone ahora de una definición específica de la función virtual fun, por lo que cualquier invocación a la misma supone utilizar la versión heredada de la superclase. En este caso las invocaciones en M.4 y M.6 utilizan la misma (y única) versión de dicha función.&lt;br /&gt;
&lt;br /&gt;
No confundir el mecanismo de las funciones virtuales con el de sobrecarga y ocultación. Sea el caso siguiente:&lt;br /&gt;
class Base {&lt;br /&gt;
  public:&lt;br /&gt;
  void fun (int);    // No virtual!!&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
class Derivada : public Base {&lt;br /&gt;
  public:&lt;br /&gt;
  void fun (int);    // Oculta a Base::fun&lt;br /&gt;
  void fun (char);   // versión sobrecargada de la anterior&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
Aquí pueden declararse las funciones void Base::fun(int) y void Derivada::fun(int); incluso sin ser virtuales. En este caso, se dice que void Derivada::fun(int) oculta cualquier otra versión de fun(int) que exista en cualquiera de sus ancestros. Además, si la clase Derivada define otras versiones de fun(), es decir, existen versiones de Derivada::fun() con diferentes definiciones, entonces se dice de estas últimas son versiones sobrecargadas de Derivada::fun(). Por supuesto, estas versiones sobrecargadas deberán seguir las reglas correspondientes.&lt;br /&gt;
Ejemplo-6&lt;br /&gt;
Para ilustrar el mecanismo de ocultación en un ejemplo ejecutable, utilizaremos una pequeña variación del ejemplo anterior (Ejemplo-3  ):&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {                // L.4: Clase-base&lt;br /&gt;
  public: virtual int fun(int x) {return x * x;}    // L.5 virtual&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {    // Clase derivada-1&lt;br /&gt;
  public: int fun (int x, int y) {return x + 10;}   // L.8 NO virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {    // Clase derivada-2&lt;br /&gt;
  public: int fun (int x) {return x + 15;}          // L.11 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {         // =========&lt;br /&gt;
  B b; D1 d1; D2 d2;     // M.1&lt;br /&gt;
  B* bp = &amp;amp;b; B* bp1 = &amp;amp;d1; B* bp2 = &amp;amp;d2;           // M.1a&lt;br /&gt;
  D1* d1p = &amp;amp;d1; D2* d2p = &amp;amp;d2;     // M.1b&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;   // M.2a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp1-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.3a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp2-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.3b:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1p-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.4a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2p-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.4b:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
En este caso nos hemos limitado a añadir un segundo argumento a la definición de D1::fun de la clase derivada-1 (L8). Como consecuencia, la nueva función no es virtual, ya que no cumple con las condiciones exigidas . El resultado es que en las instancias de D1, la definición B::fun de la superclase queda ocultada por la nueva definición , con la consecuencia de que la sentencia M.4a, que antes de la modificación funcionaba correctamente, produce ahora un error de compilación porque los argumentos actuales (un entero) no concuerdan con los argumentos formales esperados por la función (dos enteros).&lt;br /&gt;
Además el compilador nos advierte de la ocultación mediante una advertecia; en Borland C++: 'D1::fun(int,int)' hides virtual function 'B::fun(int)'.&lt;br /&gt;
&lt;br /&gt;
Cuando se declare una función como virtual tenga en mente que:&lt;br /&gt;
•	Solo pueden ser métodos (funciones-miembro).&lt;br /&gt;
•	No pueden ser declaradas friend de otras clases.&lt;br /&gt;
•	No pueden ser miembros estáticos &lt;br /&gt;
•	Los constructores no pueden ser declarados virtuales &lt;br /&gt;
•	Los destructores sí pueden ser virtuales.&lt;br /&gt;
&lt;br /&gt;
Las funciones virtuales no necesitan ser redefinidas en todas las clases derivadas. Puede existir una definición en la clase base y todas, o algunas de las subclases, pueden llamar a la función-base.&lt;br /&gt;
Para redefinir una función virtual en una clase derivada, las declaraciones en la clase base y en la derivada deben coincidir en cuanto a número y tipo de los parámetros. Excepcionalmente pueden diferir en el tipo devuelto; este caso es discutido más adelante.&lt;br /&gt;
&lt;br /&gt;
Una función virtual redefinida, que solapa la función de la superclase, sigue siendo virtual y no necesita el especificador virtual en su declaración en la subclase. La propiedad virtual es heredada automáticamente por las funciones de la subclase. Aunque si la subclase va a ser derivada de nuevo, entonces sí es necesario el especificador.&lt;br /&gt;
Ejemplo:&lt;br /&gt;
class B {       // Superclase&lt;br /&gt;
   public:&lt;br /&gt;
   virtual int func();&lt;br /&gt;
};&lt;br /&gt;
...&lt;br /&gt;
class D1 : public B {     // Derivada&lt;br /&gt;
  public:&lt;br /&gt;
  int fun ();             // virtual por defecto&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {     // Derivada&lt;br /&gt;
  public:&lt;br /&gt;
  virtual int fun ();     // virtual explícita&lt;br /&gt;
};&lt;br /&gt;
class D1a : public D1 {   // Derivada&lt;br /&gt;
  public:&lt;br /&gt;
  int fun ();             // No virtual!!&lt;br /&gt;
};&lt;br /&gt;
class D2a : public D2 {   // Derivada&lt;br /&gt;
  public:&lt;br /&gt;
  int fun ();             // Ok Virtual!!&lt;br /&gt;
  int fun (char);         // No virtual!!&lt;br /&gt;
};&lt;br /&gt;
De la simple inspección de las dos últimas líneas, no es posible deducir que el método fun de la clase D2a es un método virtual. Esto representa en ocasiones un problema y puede ser motivo de confusión, ya que es muy frecuente que las definiciones de las superclases se encuentren en ficheros de cabecera, y el programador que utiliza tales superclases para derivar versiones específicas debe consultar dichos ficheros. Sobre todo, porque como se indicó en el epígrafe anterior, la declaración en la subclase debe coincidir en cuanto a número y tipo de los parámetros. En caso contrario se trataría de una nueva definición, con lo que estamos ante un caso de sobrecarga y se ignora el mecanismo de enlazado retrasado.&lt;br /&gt;
== Invocación de funciones virtuales ==&lt;br /&gt;
Lo que realmente caracteriza a las funciones virtuales es la forma muy especial que utiliza el compilador para invocarlas; forma que es posible gracias a su tipo de enlazado. Por lo demás, el mecanismo externo (la sintaxis utilizada) es exactamente igual que la del resto de funciones miembro. He aquí un resumen de esta sintaxis:&lt;br /&gt;
class CB {              // Clase-base&lt;br /&gt;
   public:&lt;br /&gt;
   void fun1(){...}     // definición-10&lt;br /&gt;
   void virtual fun2(){...}    // definición-20&lt;br /&gt;
   ...&lt;br /&gt;
};&lt;br /&gt;
class D1 : public CB {  // Derivada-1&lt;br /&gt;
   public:&lt;br /&gt;
   void fun1() {...}    // definición-11&lt;br /&gt;
   void fun2() {...}    // definición-12&lt;br /&gt;
};&lt;br /&gt;
class D2 : public CB {  // Derivada-2&lt;br /&gt;
   public:&lt;br /&gt;
   void fun1() {...}    // definición-21&lt;br /&gt;
   void fun2() {...}    // definición-22&lt;br /&gt;
};&lt;br /&gt;
...&lt;br /&gt;
CB obj; D1 obj1;  D2 obj2;     // se instancian objetos de las clases&lt;br /&gt;
...&lt;br /&gt;
obj.fun1();             // invoca definición-10&lt;br /&gt;
obj.fun2();             // invoca definición-20&lt;br /&gt;
obj1.fun1();            // invoca definición-11&lt;br /&gt;
obj1.fun2();            // invoca definición-12&lt;br /&gt;
obj1.CB::fun1();        // invoca definición-10&lt;br /&gt;
obj1.CB::fun2();        // invoca definición-20&lt;br /&gt;
obj2.fun1();            // invoca definición-21&lt;br /&gt;
obj2.fun2();            // invoca definición-22&lt;br /&gt;
obj2.CB::fun1();        // invoca definición-10&lt;br /&gt;
obj2.CB::fun2();        // invoca definición-20&lt;br /&gt;
La dierencia entre las invocaciones obj.fun1() y obj1.CB::fun1(), estriba en que la misma función se ejecuta sobre distinto juego de variables. Por contra, en obj.fun1() y obj.fun2(), funciones distintas se ejecutan sobre el mismo juego de variables.&lt;br /&gt;
CB* ptr = &amp;amp;obj;         // se definen punteros a los objetos&lt;br /&gt;
D1* ptr1= &amp;amp;obj1;&lt;br /&gt;
D2* ptr2= &amp;amp;obj2;&lt;br /&gt;
...&lt;br /&gt;
ptr-&amp;gt;fun1();            // invoca definición-10&lt;br /&gt;
ptr1-&amp;gt;fun1();           // invoca definición-11&lt;br /&gt;
ptr2-&amp;gt;fun1();           // invoca definición-21&lt;br /&gt;
&lt;br /&gt;
Cuando desde un objeto se invoca un método (virtual o no) utilizando el nombre del objeto mediante los operadores de acceso a miembros, directo, o indirecto,  se invoca el código de la función correspondiente a la clase de la que se instancia el objeto. Es decir, el código invocado solo depende del tipo de objeto (y de la sintaxis de la invocación). Esta información puede conocerse en tiempo de compilación, en cuyo caso se utilizaría enlazado estático. En otros casos este dato solo es conocido en tiempo de ejecución, por lo que debería emplearse enlazado dinámico.&lt;br /&gt;
Cualquiera que sea el mecanismo para referenciar al objeto que invoca a la función (operador de acceso directo -1- o indirecto -2-):&lt;br /&gt;
obj.fun1()      // -1-&lt;br /&gt;
ptr-&amp;gt;fun1()     // -2-&lt;br /&gt;
La función conoce cuál es el objeto que la invoca -que juego de variables debe utilizar- a través del argumento implícito this.&lt;br /&gt;
== Invocación en jerarquías de clases ==&lt;br /&gt;
Sea B es una clase base, y otra D derivada públicamente de B. Cada una contiene una función virtual vf, entonces si vf es invocada por un objeto de D, la llamada que se realiza es D::vf(), incluso cuando el acceso se realiza vía un puntero o referencia a la superclase B. Ejemplo:&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class C {               // Clase-base&lt;br /&gt;
  public: virtual int get() {return 10;}&lt;br /&gt;
};&lt;br /&gt;
class D : public C {    // Derivada&lt;br /&gt;
  public: virtual int get() {return 100;}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {        // =========&lt;br /&gt;
  D d;&lt;br /&gt;
  C* cptr = &amp;amp;d;&lt;br /&gt;
  C&amp;amp; cref = d;&lt;br /&gt;
  cout &amp;lt;&amp;lt; d.get()     &amp;lt;&amp;lt; endl;&lt;br /&gt;
  cout &amp;lt;&amp;lt; cptr-&amp;gt;get() &amp;lt;&amp;lt; endl;&lt;br /&gt;
  cout &amp;lt;&amp;lt; cref.get()  &amp;lt;&amp;lt; endl;&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
100&lt;br /&gt;
100&lt;br /&gt;
100&lt;br /&gt;
&lt;br /&gt;
==  Tabla de funciones virtuales ==&lt;br /&gt;
Las funciones virtuales pagan un tributo por su versatilidad. Cada objeto de la clase derivada tiene que incluir un puntero (vfptr) a una tabla de direcciones de funciones virtuales, conocida como vtable. La utilización de dicho puntero permite seleccionar desde el objeto, la función correspondiente en tiempo de ejecución. Como resultado, el mecanismo de invocación de estas funciones  es mucho menos eficiente que el de los métodos normales (enlazado estático), por lo que debe reservarse su utilización a los casos estrictamente necesarios.&lt;br /&gt;
Es fácil poner en evidencia la existencia del puntero vfptr mediante un sencillo experimento que utiliza el operador sizeof&lt;br /&gt;
struct S1 {&lt;br /&gt;
  int n;&lt;br /&gt;
  double get() { return n; } // método auxiliar normal&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct S2 {&lt;br /&gt;
  int n;&lt;br /&gt;
  virtual double get() { return n; } // método virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
size_t tamS1 = sizeof(S1);  // -&amp;gt; 4&lt;br /&gt;
size_t tamS2 = sizeof(S2);  // -&amp;gt; 8&lt;br /&gt;
Comentario&lt;br /&gt;
El resultado del tamaño de ambos tipos es respectivamente 4 y 8 en cualquiera de los compiladores comprobados: Borland C++ 5.5 y gcc-g++ 3.4.2-20040916-1 para Windows. La diferencia de 4 Bytes obtenida corresponde precisamente a la presencia del mencionado puntero oculto.&lt;br /&gt;
== Función virtual pura ==&lt;br /&gt;
En ocasiones se lleva al extremo el concepto &amp;quot;virtual&amp;quot; en la declaración de una súper clase (&amp;quot;esta función será redefinida más tarde en las clases derivadas&amp;quot;), por lo que en ella solo existe una declaración de la función, relegándose las distintas definiciones a las clases derivadas. Entonces se dice que esta función es virtual pura. Esta circunstancia hay que advertirla al compilador; es una forma de decirle que la falta de definición no es un olvido por nuestra parte (de lo contrario el compilador nos señala que se nos ha olvidado la definición); esto se hace igualando a cero la declaración de la función:&lt;br /&gt;
virtual int funct1(void);      // Declara función virtual&lt;br /&gt;
virtual int funct2(void) = 0;  // Declara función virtual pura&lt;br /&gt;
&lt;br /&gt;
La existencia de una función virtual basta para que la clase que estamos definiendo sea polimórfica. Si además igualamos la función a cero, la estaremos declarando como función virtual pura, lo que automáticamente declara la clase como abstracta &lt;br /&gt;
Es muy frecuente que las funciones virtuales puras se declaren además con el calificador const , de forma que es usual encontrar expresiones del tipo:&lt;br /&gt;
virtual int funct2(void) const = 0;  // Declara función virtual pura y constante&lt;br /&gt;
==  Ejemplo ==&lt;br /&gt;
El ejemplo que sigue es una modificación del anterior , en el que declaramos la función fun de la clase-base B como virtual pura, con lo que podemos omitir su definición.&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {              // L.4:  Clase-base&lt;br /&gt;
  public:  virtual int fun(int x) = 0;       // L.5 virtual pura&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {  // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 10;}  // L.8 virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {  // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 15;}  // L.11 virtual&lt;br /&gt;
};&lt;br /&gt;
int main(void) {       // =========&lt;br /&gt;
  D1 d1; D2 d2;        // M.1&lt;br /&gt;
&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.fun(10)    &amp;lt;&amp;lt; endl;  // M.3:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.fun(10)    &amp;lt;&amp;lt; endl;  // M.4:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
Comentario&lt;br /&gt;
El resto del programa se mantiene prácticamente igual al modelo anterior, con la salvedad de que ahora en M1 no podemos instanciar un objeto directamente de la superclase B; la razón es que la superclase está incompleta (falta la definición de fun). Si lo intentáramos, el compilador nos mostraría un error señalando que no se puede instanciar un objeto de la clase B y que dicha clase es abstracta; además las clases abstractas no son instanciables por definición.&lt;br /&gt;
En lo que respecta a las salidas, comprobamos que son los valores esperados.&lt;br /&gt;
&lt;br /&gt;
Una declaración de función no puede ser al mismo tiempo una definición y una declaración de virtual pura. Ejemplo:&lt;br /&gt;
struct Est {&lt;br /&gt;
    virtual void f() { /* ... */ } = 0;    // Error!!&lt;br /&gt;
};&lt;br /&gt;
La forma legal de proporcionar una definición es:&lt;br /&gt;
struct Est {&lt;br /&gt;
  virtual void f(void) = 0;    // declara f virtual pura&lt;br /&gt;
};&lt;br /&gt;
virtual void Est::f(void) {    // definición posterior de f&lt;br /&gt;
   /* código de la función f  */&lt;br /&gt;
};&lt;br /&gt;
== Un mundo de excepciones ==&lt;br /&gt;
Seguramente el lector que haya llegado hasta aquí experimente una cierta perplejidad (que comparto). En el párrafo §7  decimos que se utiliza el recurso de declarar una función virtual pura para poder omitir la definición, y a continuación, en el párrafo §7.2 exponemos la forma legal de proporcionarla...  El lector puede comprobar que esta aparente contradicción es asumida por el compilador sin protestas. En efecto, considere el ejemplo siguiente en el que modificamos el anterior añadiendo una definición a la función virtual pura fun.&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {               // L.4:  Clase-base&lt;br /&gt;
  public:  virtual int fun(int x) = 0;       // L.5 virtual pura&lt;br /&gt;
};&lt;br /&gt;
int B::fun(int x) {return x * x}             // L.7 definición de fun&lt;br /&gt;
&lt;br /&gt;
class D1 : public B {   // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 10;}  // L.9 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class D2 : public B {   // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 15;}  // L.12 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {        // =========&lt;br /&gt;
  D1 d1; D2 d2;         // M.1&lt;br /&gt;
&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.fun(10)    &amp;lt;&amp;lt; endl;  // M.3:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.fun(10)    &amp;lt;&amp;lt; endl;  // M.4:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.B::fun(10) &amp;lt;&amp;lt; endl;  // M.5:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.B::fun(10) &amp;lt;&amp;lt; endl;  // M.6:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
== Tipos devueltos por las funciones virtuales ==&lt;br /&gt;
Cuando se redefine una función virtual no se puede cambiarse el tipo de valor devuelto. Para redefinir una función virtual en alguna clase derivada, la nueva función debe coincidir exactamente en número y tipo con los parámetros de la declaración inicial (la &amp;quot;firma&amp;quot; -Signature- de ambas funciones deben ser iguales). Si no coinciden en esto, el compilador C++ considera que se trata de funciones diferentes (un caso de sobrecarga) y se ignora el mecanismo de funciones virtuales.&lt;br /&gt;
Para prevenir que puedan producirse errores inadvertidos, el compilador C++ GNU dispone de la opción  -Woverloaded-virtual, que produce un mensaje de aviso, si se redefine un método declarado previamente virtual en una clase antecesora, y no se cumple la condición de igualdad de firmas.&lt;br /&gt;
No obstante lo anterior, hay casos en que las funciones virtuales redefinidas en clases derivadas devuelven un tipo diferente del de la función virtual de la clase base. Esto es posible solo cuando se dan simultáneamente las dos condiciones siguientes:&lt;br /&gt;
•	La función virtual sobrecontrolada devuelve un puntero o referencia a clase base.&lt;br /&gt;
•	La nueva versión devuelve un puntero o referencia a la clase derivada.&lt;br /&gt;
=== Ejemplo ===&lt;br /&gt;
struct X {};            // clase base.&lt;br /&gt;
struct Y : X {};        // clase derivada (:public X por defecto).&lt;br /&gt;
struct B {              // clase base.&lt;br /&gt;
   virtual void vf1();  // L.4:&lt;br /&gt;
   virtual void vf2();&lt;br /&gt;
   virtual void vf3();&lt;br /&gt;
   void f();&lt;br /&gt;
   virtual X* pf();     /* L.8:  devuelve puntero a clase base,&lt;br /&gt;
                            esta función virtual puede ser sobrecontrolada */&lt;br /&gt;
};&lt;br /&gt;
class D : public B {    // clase derivada&lt;br /&gt;
   public:&lt;br /&gt;
   virtual void vf1();  // L.12: Especificador virtual, legal pero redundante&lt;br /&gt;
   void vf2(int);       /* L.13: No virtual, oculta B::vf2()&lt;br /&gt;
                            dado que usa otros argumentos */&lt;br /&gt;
// char vf3();          // L.14: Ilegal! cambia solo el tipo devuelto!&lt;br /&gt;
   void f();            // L.15: privativa de D (no virtual)&lt;br /&gt;
   Y*   pf();           /* L.16: función sobrecontrolante; difiere solo&lt;br /&gt;
                          en el tipo devuelto. Devuelve puntero a subclase */&lt;br /&gt;
};&lt;br /&gt;
void extf() {&lt;br /&gt;
   D d;                 // d objeto de la clase D (instancia)&lt;br /&gt;
   B* bp = &amp;amp;d;          /* L.20: Conversión estándar D* a B*&lt;br /&gt;
                  Inicializa bp con la tabla de funciones del objeto d.&lt;br /&gt;
                  Si no existe entrada para una función en dicha tabla,&lt;br /&gt;
                  utiliza la función de la tabla de la clase B */&lt;br /&gt;
   bp–&amp;gt;vf1();           // invoca D::vf1&lt;br /&gt;
   bp–&amp;gt;vf2();           // invoca B::vf2 (D::vf2 tiene diferentes argumentos)&lt;br /&gt;
   bp–&amp;gt;f();             // invoca B::f (not virtual)&lt;br /&gt;
   X* xptr = bp–&amp;gt;pf();  /* invoca D::pf() y convierte el resultado&lt;br /&gt;
                            en un puntero a X */&lt;br /&gt;
   D* dptr = &amp;amp;d;&lt;br /&gt;
   Y* yptr = dptr–&amp;gt;pf(); /* inicializa yptr; este puntero invocará a D::pf()&lt;br /&gt;
                            No se realiza ninguna conversión */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
L.12:  La versión D::vf1 es virtual automáticamente, dado que devuelve lo mismo y tiene los mismos parámetros que su homónima en la superclase B. El especificador virtual puede ser utilizado en estos casos pero no es estrictamente necesario a no ser que se vayan a derivar nuevas subclases de la clase derivada.&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Puede Contactar  ==&lt;br /&gt;
*[[Declaración de funciones|Declaración de funciones]] &lt;br /&gt;
*[[Sobrecarga de funciones (programación)|Sobrecarga de funciones (programación)]]&lt;br /&gt;
*[[Parámetros y argumentos (programación)|Parámetros y argumentos (programación)]]&lt;br /&gt;
*[[Invocación de funciones (programación)|Invocación de funciones (programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Sobrecarga de enumeraciones (Informática)|Sobrecarga de enumeraciones (Informática)]] &lt;br /&gt;
*[[Referencias (programación)|Referencias (programación)]]&lt;br /&gt;
== Fuentes  ==&lt;br /&gt;
* [http://www.zator.com/Cpp/E4_11_8a.htm Funciones virtuales]&lt;br /&gt;
* [http://www.fismat.umich.mx/mn1/manual/node7.html Funciones en C ++]&lt;br /&gt;
*     [http://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Funciones#Definiendo_una_funci.C3.B3n    Programación en C++/Funciones]&lt;br /&gt;
*    [http://c.conclase.net/curso/?cap=020#inicio Funciones]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]] [[Category:Programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Funciones_virtuales&amp;diff=3024746</id>
		<title>Funciones virtuales</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Funciones_virtuales&amp;diff=3024746"/>
		<updated>2017-12-12T18:09:04Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Funciones virtuales |imagen=   |concepto=&lt;br /&gt;
Las funciones virtuales permiten que clases derivadas de una misma base (clases hermanas) puedan tener diferentes versiones de un método. Se utiliza la palabra-clave virtual para avisar al compilador que un método será polimórfico y que en las clases derivadas existen distintas definiciones del mismo}}&lt;br /&gt;
''' Funciones virtuales '''. Las funciones virtuales permiten que clases derivadas de una misma base (clases hermanas) puedan tener diferentes versiones de un método. Se utiliza la palabra-clave virtual para avisar al compilador que un método será polimórfico y que en las clases derivadas existen distintas definiciones del mismo. En respuesta, el &amp;quot;Linker&amp;quot; utiliza para ella una técnica especial, enlazado retrasado. La declaración de virtual en un método de una clase, implica que esta es polimórfica, y que probablemente no se utilizará directamente para instanciar objetos, sino como super-clase de una jerarquía.&lt;br /&gt;
&lt;br /&gt;
Esta posibilidad, que un mismo método puede exhibir distintos comportamientos en los descendientes de una base común, es precisamente lo que posibilita y define el polimorfismo. En estos casos se dice que las descendientes de la función virtual solapan o sobrecontrolan (&amp;quot;Override&amp;quot;) la versión de la superclase, pero esta versión de la superclase puede no existir en absoluto. Es probable que en ella solo exista una declaración del tipo: vitual void foo(); sin que exista una definición de la misma. Para que pueda existir la declaración de un método sin que exista la definición correspondiente, el método debe ser virtual puro  (un tipo particular dentro de los virtuales).&lt;br /&gt;
&lt;br /&gt;
Utilizaremos la siguiente terminología:  &amp;quot;función sobrecontrolada&amp;quot; o &amp;quot;solapada&amp;quot;, para referirnos a la versión en la superclase y &amp;quot;función sobrecontroladora&amp;quot; o &amp;quot;que solapa&amp;quot; para referirnos a la nueva versión en la clase derivada. Cualquier referencia al sobrecontrol o solapamiento (&amp;quot;Overriding&amp;quot;) indica que se está utilizando el mecanismo C++ de las funciones virtuales. Parecido pero no idéntico al de sobrecarga; conviene no confundir ambos conceptos. Más adelante intentamos aclarar sus diferencias .&lt;br /&gt;
== Sintaxis ==&lt;br /&gt;
Para declarar que un método de una clase base es virtual, su prototipo se declara como siempre, pero anteponiendo la palabra-clave virtual, que indica al compilador algo así como: &amp;quot;Será definido más tarde en una clase derivada&amp;quot;. Ejemplo:&lt;br /&gt;
virtual void dibujar();&lt;br /&gt;
Cuando se aplica a métodos de clase, el especificador virtual debe ser utilizado en la declaración, pero no en la definición si esta se realiza offline (fuera del cuerpo de la clase). Ejemplo:&lt;br /&gt;
class CL {&lt;br /&gt;
  ...&lt;br /&gt;
  virtual void func1();&lt;br /&gt;
  virtual void func2();&lt;br /&gt;
  virtual void func3() { ... }    // Ok. definición inline&lt;br /&gt;
};&lt;br /&gt;
virtual void CL::func1() { ... }  // Error!!&lt;br /&gt;
void CL::func2() { ... }          // Ok. definición offline&lt;br /&gt;
== Descripción ==&lt;br /&gt;
Al tratar del enlazado se indicaron las causas que justifican la existencia de este tipo de funciones en los lenguajes orientados a objeto (que aconsejamos repasar ahora. Para ayudarnos a comprender el problema que se pretende resolver con este tipo de funciones, exponemos una continuación del ejemplo de la clase Poligono al que nos referimos al tratar de las clases polimórficas:&lt;br /&gt;
&lt;br /&gt;
class Color { public: int R, G, B; };   // clase auxiliar&lt;br /&gt;
class Punto { public: float x, y; };    // clase auxiliar&lt;br /&gt;
&lt;br /&gt;
class Poligono {        // clase-base (polimórfica)&lt;br /&gt;
  protected:            // interfaz para las clases derivadas&lt;br /&gt;
  Punto centro;&lt;br /&gt;
  Color col;&lt;br /&gt;
  ...&lt;br /&gt;
  public:               // interfaz para los usuarios de poligonos&lt;br /&gt;
  virtual void dibujar() const;&lt;br /&gt;
  virtual void rotar(int grados);&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class Circulo : public Poligono {       // Un tipo de polígono&lt;br /&gt;
  protected:&lt;br /&gt;
  int radio;&lt;br /&gt;
  ...&lt;br /&gt;
  public:&lt;br /&gt;
  void dibujar() const;&lt;br /&gt;
  void rotar(int) { }&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class Triangulo : public Poligono {     // Otro tipo de pológono&lt;br /&gt;
  protected:&lt;br /&gt;
  Punto a, b, c;&lt;br /&gt;
  ...&lt;br /&gt;
  public:&lt;br /&gt;
  void dibujar() const;&lt;br /&gt;
  void rotar(int);&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Lo que se pretende con este tipo de jerarquía es que los usuarios de subclases manejen los distintos polígonos a través de su interfaz pública (sus miembros públicos), mientras que los implementadores (creadores de los diversos tipos de polígonos que puedan existir en la aplicación), compartan los aspectos representados por los miembros protegidos.&lt;br /&gt;
Los miembros protegidos son utilizados también para aquellos aspectos que son dependientes de la implementación. Por ejemplo, aunque la propiedad color será compartida por todas las clases de polígonos, posiblemente su definición dependa de aspectos concretos de la implementación, es decir, del concepto de &amp;quot;color&amp;quot; del sistema operativo, que probablemente estará en definiciones en ficheros de cabecera.&lt;br /&gt;
Los miembros en la superclase (polimórfica) representan las partes que son comunes a todos los miembros (a todos los polígonos) pero en la mayoría de los casos no es sencillo decidir cuáles serán estos miembros (propiedades o métodos) compartidos por todas las clases derivadas. Por ejemplo, aunque se puede definir un centro para cualquier polígono, mantener su valor puede ser una molestia innecesaria en la mayoría de los polígonos y sobre todo en los triángulos, mientras es imprescindible en los círculos y muy útil en el resto de polígonos equiláteros.&lt;br /&gt;
=== Ejemplo ===&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {                 // L.4:  Clase-base&lt;br /&gt;
  public: virtual int fun(int x) {return x * x;}   // L.5 virtual&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {     // Clase derivada-1&lt;br /&gt;
  public:  int fun (int x) {return x + 10;}        // L.8 virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {     // Clase derivada-2&lt;br /&gt;
  public:  int fun (int x) {return x + 15;}        // L.11 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {          // =========&lt;br /&gt;
  B b; D1 d1; D2 d2;      // M.1&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; b.fun(10)     &amp;lt;&amp;lt; endl;  // M.2:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.fun(10)    &amp;lt;&amp;lt; endl;  // M.3:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.fun(10)    &amp;lt;&amp;lt; endl;  // M.4:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.B::fun(10) &amp;lt;&amp;lt; endl;  // M.5:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.B::fun(10) &amp;lt;&amp;lt; endl;  // M.6:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
Comentario&lt;br /&gt;
Definimos una clase-base B, en la que definimos una función virtual fun; a continuación derivamos de ella dos subclases D1 y D2, en las que definimos sendas versiones de fun que solapan la versión existente en la clase-base.&lt;br /&gt;
Las versiones de fun en L.8 y L.11 son virtuales, a pesar de no tener el declarador virtual indicado explícitamente. Estas versiones son un caso de polimorfismo, y solapan a la versión definida en la clase-base.&lt;br /&gt;
La línea M.1 instancia tres objetos de las clases anteriormente definidas.  En las líneas M.2 a M.4 comprobamos sus valores, que son los esperados (en cada caso se ha utilizado la versión de fun adecuada al objeto correspondiente).  Observe que la elección de la función adecuada no se realiza por el análisis de los argumentos pasados a la función como en el caso de la sobrecarga (aquí los argumentos son iguales en todos los casos), sino por la &amp;quot;naturaleza&amp;quot; del objeto que invoca la función;  esta es precisamente la característica distintiva del del polimorfismo.&lt;br /&gt;
Las líneas M.5 y M.6 sirven para recordarnos que a pesar del solapamiento, la versión de fun de la superclase sigue existiendo, y es accesible en los objetos de las clases derivadas utilizando el sobrecontrol adecuado.&lt;br /&gt;
Nota: la utilización del operador :: de acceso a ámbito anula el mecanismo de funciones virtuales, pero es aconsejable no usarlo en demasía, pues conduce a programas más difíciles de mantener. Como regla general, este tipo de calificación solo debe utilizarse para acceder a miembros del subobjeto heredado como es el caso del ejemplo.&lt;br /&gt;
Ejemplo-2&lt;br /&gt;
Hagamos ahora de abogados del diablo compilando el ejemplo anterior con la única modificación de que el método fun de B no sea virtual, sino un método normal. Es decir, la sentencia L.5, quedaría como:&lt;br /&gt;
public: int fun(int x) {return x * x;}    // L.5b no virtual!!&lt;br /&gt;
En este caso, comprobamos que el resultado coincide exactamente con el anterior, lo que nos induciría a preguntar ¿Para qué diablos sirven entonces las funciones virtuales?&lt;br /&gt;
Ejemplo-3&lt;br /&gt;
La explicación podemos encontrala fácilmente mediante una pequeña modificación en el programa: en vez de acceder directamente a los miembros de los objetos utilizando el selector directo de miembro, en las sentencias de salida, realizaremos el acceso mediante punteros a las clases correspondientes. De estos punteros declararemos dos tipos: a la superclase y a las clases derivadas (por brevedad hemos suprimido las sentencias de comprobación M.5 y M.6).&lt;br /&gt;
El nuevo diseño sería el siguiente:&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {                 // L.4: Clase-base&lt;br /&gt;
  public: virtual int fun(int x) {return x * x;}  // L.5 virtual&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {     // Clase derivada-1&lt;br /&gt;
  public: int fun (int x) {return x + 10;}        // L.8 virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {     // Clase derivada-2&lt;br /&gt;
  public: int fun (int x) {return x + 15;}        // L.11 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {          // =========&lt;br /&gt;
  B b; D1 d1; D2 d2;      // M.1&lt;br /&gt;
  B* bp = &amp;amp;b; B* bp1 = &amp;amp;d1; B* bp2 = &amp;amp;d2;           // M.1a&lt;br /&gt;
  D1* d1p = &amp;amp;d1; D2* d2p = &amp;amp;d2;                     // M.1b&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;   // M.2a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp1-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.3a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp2-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.3b:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1p-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.4a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2p-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.4b:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
Comentario&lt;br /&gt;
La sentencia M.1a define tres punteros a la clase-base. No obstante, dos de ellos se utilizan para señalar objetos de las sub-clases. Esto es típico de los punteros en jerarquías de clases. Precisamente se introdujo esta &amp;quot;relajación&amp;quot; en el control de tipos, para facilitar ciertas funcionalidades de las clases polimórficas.&lt;br /&gt;
La sentencia M.1b define sendos punteros a subclase, que en este caso si son aplicados a entidades de su mismo tipo.&lt;br /&gt;
Teniendo en cuenta las modificaciones efectuadas, y como no podía ser menos, las nuevas salidas son exactamente análogas a las del ejemplo inicial.&lt;br /&gt;
Ejemplo-4&lt;br /&gt;
Si suprimimos la declaración de virtual para la sentencia L.5 y volvemos a compilar el programa, se obtienen los resultados siguientes:&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
En ausencia de enlazado retrasado, las sentencias M.3a y M.3b, que acceden a métodos de objetos a través de punteros a la superclase, se refieren a los métodos heredados (que se definieron en la superclase). En este contexto pueden considerarse equivalentes los siguientes pares de expresiones:&lt;br /&gt;
bp1-&amp;gt;fun(10)  ==  d1.B::fun(10)&lt;br /&gt;
bp2-&amp;gt;fun(10)  ==  d2.B::fun(10)&lt;br /&gt;
&lt;br /&gt;
Hay ocasiones es que este comportamiento no interesa. Precisamente en las clases abstractas, en las que la definición de B::fun() no existe en absoluto, y expresiones como M.3a y M.3b conducirían a error si fun() no fuese declarada virtual pura en B.&lt;br /&gt;
Ejemplo-5&lt;br /&gt;
Presentamos una variación muy interesante del primer ejemplo, en el que simplemente hemos eliminado la línea 11, de forma que no existe definición específica de fun en la subclase D2.&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {                 // L.4:  Clase-base&lt;br /&gt;
  public:  virtual int fun(int x) {return x * x;}   // L.5 virtual&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {     // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 10;}         // L.8 virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B { };  // Clase derivada&lt;br /&gt;
&lt;br /&gt;
int main(void) {          // =========&lt;br /&gt;
  B b; D1 d1; D2 d2;      // M.1&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; b.fun(10)     &amp;lt;&amp;lt; endl;  // M.2:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.fun(10)    &amp;lt;&amp;lt; endl;  // M.3:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.fun(10)    &amp;lt;&amp;lt; endl;  // M.4:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.B::fun(10) &amp;lt;&amp;lt; endl;  // M.5:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.B::fun(10) &amp;lt;&amp;lt; endl;  // M.6:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
Comentario&lt;br /&gt;
El objeto d2 no dispone ahora de una definición específica de la función virtual fun, por lo que cualquier invocación a la misma supone utilizar la versión heredada de la superclase. En este caso las invocaciones en M.4 y M.6 utilizan la misma (y única) versión de dicha función.&lt;br /&gt;
&lt;br /&gt;
No confundir el mecanismo de las funciones virtuales con el de sobrecarga y ocultación. Sea el caso siguiente:&lt;br /&gt;
class Base {&lt;br /&gt;
  public:&lt;br /&gt;
  void fun (int);    // No virtual!!&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
class Derivada : public Base {&lt;br /&gt;
  public:&lt;br /&gt;
  void fun (int);    // Oculta a Base::fun&lt;br /&gt;
  void fun (char);   // versión sobrecargada de la anterior&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
Aquí pueden declararse las funciones void Base::fun(int) y void Derivada::fun(int); incluso sin ser virtuales. En este caso, se dice que void Derivada::fun(int) oculta cualquier otra versión de fun(int) que exista en cualquiera de sus ancestros. Además, si la clase Derivada define otras versiones de fun(), es decir, existen versiones de Derivada::fun() con diferentes definiciones, entonces se dice de estas últimas son versiones sobrecargadas de Derivada::fun(). Por supuesto, estas versiones sobrecargadas deberán seguir las reglas correspondientes.&lt;br /&gt;
Ejemplo-6&lt;br /&gt;
Para ilustrar el mecanismo de ocultación en un ejemplo ejecutable, utilizaremos una pequeña variación del ejemplo anterior (Ejemplo-3  ):&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {                // L.4: Clase-base&lt;br /&gt;
  public: virtual int fun(int x) {return x * x;}    // L.5 virtual&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {    // Clase derivada-1&lt;br /&gt;
  public: int fun (int x, int y) {return x + 10;}   // L.8 NO virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {    // Clase derivada-2&lt;br /&gt;
  public: int fun (int x) {return x + 15;}          // L.11 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {         // =========&lt;br /&gt;
  B b; D1 d1; D2 d2;     // M.1&lt;br /&gt;
  B* bp = &amp;amp;b; B* bp1 = &amp;amp;d1; B* bp2 = &amp;amp;d2;           // M.1a&lt;br /&gt;
  D1* d1p = &amp;amp;d1; D2* d2p = &amp;amp;d2;     // M.1b&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;   // M.2a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp1-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.3a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp2-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.3b:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1p-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.4a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2p-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.4b:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
En este caso nos hemos limitado a añadir un segundo argumento a la definición de D1::fun de la clase derivada-1 (L8). Como consecuencia, la nueva función no es virtual, ya que no cumple con las condiciones exigidas . El resultado es que en las instancias de D1, la definición B::fun de la superclase queda ocultada por la nueva definición , con la consecuencia de que la sentencia M.4a, que antes de la modificación funcionaba correctamente, produce ahora un error de compilación porque los argumentos actuales (un entero) no concuerdan con los argumentos formales esperados por la función (dos enteros).&lt;br /&gt;
Además el compilador nos advierte de la ocultación mediante una advertecia; en Borland C++: 'D1::fun(int,int)' hides virtual function 'B::fun(int)'.&lt;br /&gt;
&lt;br /&gt;
Cuando se declare una función como virtual tenga en mente que:&lt;br /&gt;
•	Solo pueden ser métodos (funciones-miembro).&lt;br /&gt;
•	No pueden ser declaradas friend de otras clases.&lt;br /&gt;
•	No pueden ser miembros estáticos &lt;br /&gt;
•	Los constructores no pueden ser declarados virtuales &lt;br /&gt;
•	Los destructores sí pueden ser virtuales.&lt;br /&gt;
&lt;br /&gt;
Las funciones virtuales no necesitan ser redefinidas en todas las clases derivadas. Puede existir una definición en la clase base y todas, o algunas de las subclases, pueden llamar a la función-base.&lt;br /&gt;
Para redefinir una función virtual en una clase derivada, las declaraciones en la clase base y en la derivada deben coincidir en cuanto a número y tipo de los parámetros. Excepcionalmente pueden diferir en el tipo devuelto; este caso es discutido más adelante.&lt;br /&gt;
&lt;br /&gt;
Una función virtual redefinida, que solapa la función de la superclase, sigue siendo virtual y no necesita el especificador virtual en su declaración en la subclase. La propiedad virtual es heredada automáticamente por las funciones de la subclase. Aunque si la subclase va a ser derivada de nuevo, entonces sí es necesario el especificador.&lt;br /&gt;
Ejemplo:&lt;br /&gt;
class B {       // Superclase&lt;br /&gt;
   public:&lt;br /&gt;
   virtual int func();&lt;br /&gt;
};&lt;br /&gt;
...&lt;br /&gt;
class D1 : public B {     // Derivada&lt;br /&gt;
  public:&lt;br /&gt;
  int fun ();             // virtual por defecto&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {     // Derivada&lt;br /&gt;
  public:&lt;br /&gt;
  virtual int fun ();     // virtual explícita&lt;br /&gt;
};&lt;br /&gt;
class D1a : public D1 {   // Derivada&lt;br /&gt;
  public:&lt;br /&gt;
  int fun ();             // No virtual!!&lt;br /&gt;
};&lt;br /&gt;
class D2a : public D2 {   // Derivada&lt;br /&gt;
  public:&lt;br /&gt;
  int fun ();             // Ok Virtual!!&lt;br /&gt;
  int fun (char);         // No virtual!!&lt;br /&gt;
};&lt;br /&gt;
De la simple inspección de las dos últimas líneas, no es posible deducir que el método fun de la clase D2a es un método virtual. Esto representa en ocasiones un problema y puede ser motivo de confusión, ya que es muy frecuente que las definiciones de las superclases se encuentren en ficheros de cabecera, y el programador que utiliza tales superclases para derivar versiones específicas debe consultar dichos ficheros. Sobre todo, porque como se indicó en el epígrafe anterior, la declaración en la subclase debe coincidir en cuanto a número y tipo de los parámetros. En caso contrario se trataría de una nueva definición, con lo que estamos ante un caso de sobrecarga y se ignora el mecanismo de enlazado retrasado.&lt;br /&gt;
== Invocación de funciones virtuales ==&lt;br /&gt;
Lo que realmente caracteriza a las funciones virtuales es la forma muy especial que utiliza el compilador para invocarlas; forma que es posible gracias a su tipo de enlazado. Por lo demás, el mecanismo externo (la sintaxis utilizada) es exactamente igual que la del resto de funciones miembro. He aquí un resumen de esta sintaxis:&lt;br /&gt;
class CB {              // Clase-base&lt;br /&gt;
   public:&lt;br /&gt;
   void fun1(){...}     // definición-10&lt;br /&gt;
   void virtual fun2(){...}    // definición-20&lt;br /&gt;
   ...&lt;br /&gt;
};&lt;br /&gt;
class D1 : public CB {  // Derivada-1&lt;br /&gt;
   public:&lt;br /&gt;
   void fun1() {...}    // definición-11&lt;br /&gt;
   void fun2() {...}    // definición-12&lt;br /&gt;
};&lt;br /&gt;
class D2 : public CB {  // Derivada-2&lt;br /&gt;
   public:&lt;br /&gt;
   void fun1() {...}    // definición-21&lt;br /&gt;
   void fun2() {...}    // definición-22&lt;br /&gt;
};&lt;br /&gt;
...&lt;br /&gt;
CB obj; D1 obj1;  D2 obj2;     // se instancian objetos de las clases&lt;br /&gt;
...&lt;br /&gt;
obj.fun1();             // invoca definición-10&lt;br /&gt;
obj.fun2();             // invoca definición-20&lt;br /&gt;
obj1.fun1();            // invoca definición-11&lt;br /&gt;
obj1.fun2();            // invoca definición-12&lt;br /&gt;
obj1.CB::fun1();        // invoca definición-10&lt;br /&gt;
obj1.CB::fun2();        // invoca definición-20&lt;br /&gt;
obj2.fun1();            // invoca definición-21&lt;br /&gt;
obj2.fun2();            // invoca definición-22&lt;br /&gt;
obj2.CB::fun1();        // invoca definición-10&lt;br /&gt;
obj2.CB::fun2();        // invoca definición-20&lt;br /&gt;
La dierencia entre las invocaciones obj.fun1() y obj1.CB::fun1(), estriba en que la misma función se ejecuta sobre distinto juego de variables. Por contra, en obj.fun1() y obj.fun2(), funciones distintas se ejecutan sobre el mismo juego de variables.&lt;br /&gt;
CB* ptr = &amp;amp;obj;         // se definen punteros a los objetos&lt;br /&gt;
D1* ptr1= &amp;amp;obj1;&lt;br /&gt;
D2* ptr2= &amp;amp;obj2;&lt;br /&gt;
...&lt;br /&gt;
ptr-&amp;gt;fun1();            // invoca definición-10&lt;br /&gt;
ptr1-&amp;gt;fun1();           // invoca definición-11&lt;br /&gt;
ptr2-&amp;gt;fun1();           // invoca definición-21&lt;br /&gt;
&lt;br /&gt;
Cuando desde un objeto se invoca un método (virtual o no) utilizando el nombre del objeto mediante los operadores de acceso a miembros, directo, o indirecto,  se invoca el código de la función correspondiente a la clase de la que se instancia el objeto. Es decir, el código invocado solo depende del tipo de objeto (y de la sintaxis de la invocación). Esta información puede conocerse en tiempo de compilación, en cuyo caso se utilizaría enlazado estático. En otros casos este dato solo es conocido en tiempo de ejecución, por lo que debería emplearse enlazado dinámico.&lt;br /&gt;
Cualquiera que sea el mecanismo para referenciar al objeto que invoca a la función (operador de acceso directo -1- o indirecto -2-):&lt;br /&gt;
obj.fun1()      // -1-&lt;br /&gt;
ptr-&amp;gt;fun1()     // -2-&lt;br /&gt;
La función conoce cuál es el objeto que la invoca -que juego de variables debe utilizar- a través del argumento implícito this.&lt;br /&gt;
== Invocación en jerarquías de clases ==&lt;br /&gt;
Sea B es una clase base, y otra D derivada públicamente de B. Cada una contiene una función virtual vf, entonces si vf es invocada por un objeto de D, la llamada que se realiza es D::vf(), incluso cuando el acceso se realiza vía un puntero o referencia a la superclase B. Ejemplo:&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class C {               // Clase-base&lt;br /&gt;
  public: virtual int get() {return 10;}&lt;br /&gt;
};&lt;br /&gt;
class D : public C {    // Derivada&lt;br /&gt;
  public: virtual int get() {return 100;}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {        // =========&lt;br /&gt;
  D d;&lt;br /&gt;
  C* cptr = &amp;amp;d;&lt;br /&gt;
  C&amp;amp; cref = d;&lt;br /&gt;
  cout &amp;lt;&amp;lt; d.get()     &amp;lt;&amp;lt; endl;&lt;br /&gt;
  cout &amp;lt;&amp;lt; cptr-&amp;gt;get() &amp;lt;&amp;lt; endl;&lt;br /&gt;
  cout &amp;lt;&amp;lt; cref.get()  &amp;lt;&amp;lt; endl;&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
100&lt;br /&gt;
100&lt;br /&gt;
100&lt;br /&gt;
&lt;br /&gt;
==  Tabla de funciones virtuales ==&lt;br /&gt;
Las funciones virtuales pagan un tributo por su versatilidad. Cada objeto de la clase derivada tiene que incluir un puntero (vfptr) a una tabla de direcciones de funciones virtuales, conocida como vtable. La utilización de dicho puntero permite seleccionar desde el objeto, la función correspondiente en tiempo de ejecución. Como resultado, el mecanismo de invocación de estas funciones  es mucho menos eficiente que el de los métodos normales (enlazado estático), por lo que debe reservarse su utilización a los casos estrictamente necesarios.&lt;br /&gt;
Es fácil poner en evidencia la existencia del puntero vfptr mediante un sencillo experimento que utiliza el operador sizeof&lt;br /&gt;
struct S1 {&lt;br /&gt;
  int n;&lt;br /&gt;
  double get() { return n; } // método auxiliar normal&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct S2 {&lt;br /&gt;
  int n;&lt;br /&gt;
  virtual double get() { return n; } // método virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
size_t tamS1 = sizeof(S1);  // -&amp;gt; 4&lt;br /&gt;
size_t tamS2 = sizeof(S2);  // -&amp;gt; 8&lt;br /&gt;
Comentario&lt;br /&gt;
El resultado del tamaño de ambos tipos es respectivamente 4 y 8 en cualquiera de los compiladores comprobados: Borland C++ 5.5 y gcc-g++ 3.4.2-20040916-1 para Windows. La diferencia de 4 Bytes obtenida corresponde precisamente a la presencia del mencionado puntero oculto.&lt;br /&gt;
== Función virtual pura ==&lt;br /&gt;
En ocasiones se lleva al extremo el concepto &amp;quot;virtual&amp;quot; en la declaración de una súper clase (&amp;quot;esta función será redefinida más tarde en las clases derivadas&amp;quot;), por lo que en ella solo existe una declaración de la función, relegándose las distintas definiciones a las clases derivadas. Entonces se dice que esta función es virtual pura. Esta circunstancia hay que advertirla al compilador; es una forma de decirle que la falta de definición no es un olvido por nuestra parte (de lo contrario el compilador nos señala que se nos ha olvidado la definición); esto se hace igualando a cero la declaración de la función:&lt;br /&gt;
virtual int funct1(void);      // Declara función virtual&lt;br /&gt;
virtual int funct2(void) = 0;  // Declara función virtual pura&lt;br /&gt;
&lt;br /&gt;
La existencia de una función virtual basta para que la clase que estamos definiendo sea polimórfica. Si además igualamos la función a cero, la estaremos declarando como función virtual pura, lo que automáticamente declara la clase como abstracta &lt;br /&gt;
Es muy frecuente que las funciones virtuales puras se declaren además con el calificador const , de forma que es usual encontrar expresiones del tipo:&lt;br /&gt;
virtual int funct2(void) const = 0;  // Declara función virtual pura y constante&lt;br /&gt;
==  Ejemplo ==&lt;br /&gt;
El ejemplo que sigue es una modificación del anterior , en el que declaramos la función fun de la clase-base B como virtual pura, con lo que podemos omitir su definición.&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {              // L.4:  Clase-base&lt;br /&gt;
  public:  virtual int fun(int x) = 0;       // L.5 virtual pura&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {  // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 10;}  // L.8 virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {  // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 15;}  // L.11 virtual&lt;br /&gt;
};&lt;br /&gt;
int main(void) {       // =========&lt;br /&gt;
  D1 d1; D2 d2;        // M.1&lt;br /&gt;
&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.fun(10)    &amp;lt;&amp;lt; endl;  // M.3:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.fun(10)    &amp;lt;&amp;lt; endl;  // M.4:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
Comentario&lt;br /&gt;
El resto del programa se mantiene prácticamente igual al modelo anterior, con la salvedad de que ahora en M1 no podemos instanciar un objeto directamente de la superclase B; la razón es que la superclase está incompleta (falta la definición de fun). Si lo intentáramos, el compilador nos mostraría un error señalando que no se puede instanciar un objeto de la clase B y que dicha clase es abstracta; además las clases abstractas no son instanciables por definición.&lt;br /&gt;
En lo que respecta a las salidas, comprobamos que son los valores esperados.&lt;br /&gt;
&lt;br /&gt;
Una declaración de función no puede ser al mismo tiempo una definición y una declaración de virtual pura. Ejemplo:&lt;br /&gt;
struct Est {&lt;br /&gt;
    virtual void f() { /* ... */ } = 0;    // Error!!&lt;br /&gt;
};&lt;br /&gt;
La forma legal de proporcionar una definición es:&lt;br /&gt;
struct Est {&lt;br /&gt;
  virtual void f(void) = 0;    // declara f virtual pura&lt;br /&gt;
};&lt;br /&gt;
virtual void Est::f(void) {    // definición posterior de f&lt;br /&gt;
   /* código de la función f  */&lt;br /&gt;
};&lt;br /&gt;
== Un mundo de excepciones ==&lt;br /&gt;
Seguramente el lector que haya llegado hasta aquí experimente una cierta perplejidad (que comparto). En el párrafo §7  decimos que se utiliza el recurso de declarar una función virtual pura para poder omitir la definición, y a continuación, en el párrafo §7.2 exponemos la forma legal de proporcionarla...  El lector puede comprobar que esta aparente contradicción es asumida por el compilador sin protestas. En efecto, considere el ejemplo siguiente en el que modificamos el anterior añadiendo una definición a la función virtual pura fun.&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {               // L.4:  Clase-base&lt;br /&gt;
  public:  virtual int fun(int x) = 0;       // L.5 virtual pura&lt;br /&gt;
};&lt;br /&gt;
int B::fun(int x) {return x * x}             // L.7 definición de fun&lt;br /&gt;
&lt;br /&gt;
class D1 : public B {   // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 10;}  // L.9 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class D2 : public B {   // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 15;}  // L.12 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {        // =========&lt;br /&gt;
  D1 d1; D2 d2;         // M.1&lt;br /&gt;
&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.fun(10)    &amp;lt;&amp;lt; endl;  // M.3:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.fun(10)    &amp;lt;&amp;lt; endl;  // M.4:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.B::fun(10) &amp;lt;&amp;lt; endl;  // M.5:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.B::fun(10) &amp;lt;&amp;lt; endl;  // M.6:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
== Tipos devueltos por las funciones virtuales ==&lt;br /&gt;
Cuando se redefine una función virtual no se puede cambiarse el tipo de valor devuelto. Para redefinir una función virtual en alguna clase derivada, la nueva función debe coincidir exactamente en número y tipo con los parámetros de la declaración inicial (la &amp;quot;firma&amp;quot; -Signature- de ambas funciones deben ser iguales). Si no coinciden en esto, el compilador C++ considera que se trata de funciones diferentes (un caso de sobrecarga) y se ignora el mecanismo de funciones virtuales.&lt;br /&gt;
Para prevenir que puedan producirse errores inadvertidos, el compilador C++ GNU dispone de la opción  -Woverloaded-virtual, que produce un mensaje de aviso, si se redefine un método declarado previamente virtual en una clase antecesora, y no se cumple la condición de igualdad de firmas.&lt;br /&gt;
No obstante lo anterior, hay casos en que las funciones virtuales redefinidas en clases derivadas devuelven un tipo diferente del de la función virtual de la clase base. Esto es posible solo cuando se dan simultáneamente las dos condiciones siguientes:&lt;br /&gt;
•	La función virtual sobrecontrolada devuelve un puntero o referencia a clase base.&lt;br /&gt;
•	La nueva versión devuelve un puntero o referencia a la clase derivada.&lt;br /&gt;
=== Ejemplo ===&lt;br /&gt;
struct X {};            // clase base.&lt;br /&gt;
struct Y : X {};        // clase derivada (:public X por defecto).&lt;br /&gt;
struct B {              // clase base.&lt;br /&gt;
   virtual void vf1();  // L.4:&lt;br /&gt;
   virtual void vf2();&lt;br /&gt;
   virtual void vf3();&lt;br /&gt;
   void f();&lt;br /&gt;
   virtual X* pf();     /* L.8:  devuelve puntero a clase base,&lt;br /&gt;
                            esta función virtual puede ser sobrecontrolada */&lt;br /&gt;
};&lt;br /&gt;
class D : public B {    // clase derivada&lt;br /&gt;
   public:&lt;br /&gt;
   virtual void vf1();  // L.12: Especificador virtual, legal pero redundante&lt;br /&gt;
   void vf2(int);       /* L.13: No virtual, oculta B::vf2()&lt;br /&gt;
                            dado que usa otros argumentos */&lt;br /&gt;
// char vf3();          // L.14: Ilegal! cambia solo el tipo devuelto!&lt;br /&gt;
   void f();            // L.15: privativa de D (no virtual)&lt;br /&gt;
   Y*   pf();           /* L.16: función sobrecontrolante; difiere solo&lt;br /&gt;
                          en el tipo devuelto. Devuelve puntero a subclase */&lt;br /&gt;
};&lt;br /&gt;
void extf() {&lt;br /&gt;
   D d;                 // d objeto de la clase D (instancia)&lt;br /&gt;
   B* bp = &amp;amp;d;          /* L.20: Conversión estándar D* a B*&lt;br /&gt;
                  Inicializa bp con la tabla de funciones del objeto d.&lt;br /&gt;
                  Si no existe entrada para una función en dicha tabla,&lt;br /&gt;
                  utiliza la función de la tabla de la clase B */&lt;br /&gt;
   bp–&amp;gt;vf1();           // invoca D::vf1&lt;br /&gt;
   bp–&amp;gt;vf2();           // invoca B::vf2 (D::vf2 tiene diferentes argumentos)&lt;br /&gt;
   bp–&amp;gt;f();             // invoca B::f (not virtual)&lt;br /&gt;
   X* xptr = bp–&amp;gt;pf();  /* invoca D::pf() y convierte el resultado&lt;br /&gt;
                            en un puntero a X */&lt;br /&gt;
   D* dptr = &amp;amp;d;&lt;br /&gt;
   Y* yptr = dptr–&amp;gt;pf(); /* inicializa yptr; este puntero invocará a D::pf()&lt;br /&gt;
                            No se realiza ninguna conversión */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
L.12:  La versión D::vf1 es virtual automáticamente, dado que devuelve lo mismo y tiene los mismos parámetros que su homónima en la superclase B. El especificador virtual puede ser utilizado en estos casos pero no es estrictamente necesario a no ser que se vayan a derivar nuevas subclases de la clase derivada.&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Puede Contactar  ==&lt;br /&gt;
*[[Declaración de funciones|Declaración de funciones]] &lt;br /&gt;
*[[Sobrecarga de funciones (programación)|Sobrecarga de funciones (programación)]]&lt;br /&gt;
*[[Parámetros y argumentos (programación)|Parámetros y argumentos (programación)]]&lt;br /&gt;
*[[Invocación de funciones (programación)|Invocación de funciones (programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Sobrecarga de enumeraciones (Informática)|Sobrecarga de enumeraciones (Informática)]] &lt;br /&gt;
*[[Referencias (programación)|Referencias (programación)]]&lt;br /&gt;
== Fuentes  ==&lt;br /&gt;
* [http://www.zator.com/Cpp/E4_4.htm Funciones]&lt;br /&gt;
* [http://www.fismat.umich.mx/mn1/manual/node7.html Funciones en C ++]&lt;br /&gt;
*     [http://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Funciones#Definiendo_una_funci.C3.B3n    Programación en C++/Funciones]&lt;br /&gt;
*    [http://c.conclase.net/curso/?cap=020#inicio Funciones]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]] [[Category:Programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Funciones_virtuales&amp;diff=3024732</id>
		<title>Funciones virtuales</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Funciones_virtuales&amp;diff=3024732"/>
		<updated>2017-12-12T18:07:42Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Funciones virtuales |imagen=   |concepto=&lt;br /&gt;
Las funciones virtuales permiten que clases derivadas de una misma base (clases hermanas) puedan tener diferentes versiones de un método. Se utiliza la palabra-clave virtual para avisar al compilador que un método será polimórfico y que en las clases derivadas existen distintas definiciones del mismo}}&lt;br /&gt;
''' Funciones virtuales '''. Las funciones virtuales permiten que clases derivadas de una misma base (clases hermanas) puedan tener diferentes versiones de un método. Se utiliza la palabra-clave virtual para avisar al compilador que un método será polimórfico y que en las clases derivadas existen distintas definiciones del mismo. En respuesta, el &amp;quot;Linker&amp;quot; utiliza para ella una técnica especial, enlazado retrasado. La declaración de virtual en un método de una clase, implica que esta es polimórfica, y que probablemente no se utilizará directamente para instanciar objetos, sino como super-clase de una jerarquía.&lt;br /&gt;
&lt;br /&gt;
Esta posibilidad, que un mismo método puede exhibir distintos comportamientos en los descendientes de una base común, es precisamente lo que posibilita y define el polimorfismo. En estos casos se dice que las descendientes de la función virtual solapan o sobrecontrolan (&amp;quot;Override&amp;quot;) la versión de la superclase, pero esta versión de la superclase puede no existir en absoluto. Es probable que en ella solo exista una declaración del tipo: vitual void foo(); sin que exista una definición de la misma. Para que pueda existir la declaración de un método sin que exista la definición correspondiente, el método debe ser virtual puro  (un tipo particular dentro de los virtuales).&lt;br /&gt;
Utilizaremos la siguiente terminología:  &amp;quot;función sobrecontrolada&amp;quot; o &amp;quot;solapada&amp;quot;, para referirnos a la versión en la superclase y &amp;quot;función sobrecontroladora&amp;quot; o &amp;quot;que solapa&amp;quot; para referirnos a la nueva versión en la clase derivada. Cualquier referencia al sobrecontrol o solapamiento (&amp;quot;Overriding&amp;quot;) indica que se está utilizando el mecanismo C++ de las funciones virtuales. Parecido pero no idéntico al de sobrecarga; conviene no confundir ambos conceptos. Más adelante intentamos aclarar sus diferencias .&lt;br /&gt;
== Sintaxis ==&lt;br /&gt;
Para declarar que un método de una clase base es virtual, su prototipo se declara como siempre, pero anteponiendo la palabra-clave virtual, que indica al compilador algo así como: &amp;quot;Será definido más tarde en una clase derivada&amp;quot;. Ejemplo:&lt;br /&gt;
virtual void dibujar();&lt;br /&gt;
Cuando se aplica a métodos de clase, el especificador virtual debe ser utilizado en la declaración, pero no en la definición si esta se realiza offline (fuera del cuerpo de la clase). Ejemplo:&lt;br /&gt;
class CL {&lt;br /&gt;
  ...&lt;br /&gt;
  virtual void func1();&lt;br /&gt;
  virtual void func2();&lt;br /&gt;
  virtual void func3() { ... }    // Ok. definición inline&lt;br /&gt;
};&lt;br /&gt;
virtual void CL::func1() { ... }  // Error!!&lt;br /&gt;
void CL::func2() { ... }          // Ok. definición offline&lt;br /&gt;
== Descripción ==&lt;br /&gt;
Al tratar del enlazado se indicaron las causas que justifican la existencia de este tipo de funciones en los lenguajes orientados a objeto (que aconsejamos repasar ahora. Para ayudarnos a comprender el problema que se pretende resolver con este tipo de funciones, exponemos una continuación del ejemplo de la clase Poligono al que nos referimos al tratar de las clases polimórficas:&lt;br /&gt;
&lt;br /&gt;
class Color { public: int R, G, B; };   // clase auxiliar&lt;br /&gt;
class Punto { public: float x, y; };    // clase auxiliar&lt;br /&gt;
&lt;br /&gt;
class Poligono {        // clase-base (polimórfica)&lt;br /&gt;
  protected:            // interfaz para las clases derivadas&lt;br /&gt;
  Punto centro;&lt;br /&gt;
  Color col;&lt;br /&gt;
  ...&lt;br /&gt;
  public:               // interfaz para los usuarios de poligonos&lt;br /&gt;
  virtual void dibujar() const;&lt;br /&gt;
  virtual void rotar(int grados);&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class Circulo : public Poligono {       // Un tipo de polígono&lt;br /&gt;
  protected:&lt;br /&gt;
  int radio;&lt;br /&gt;
  ...&lt;br /&gt;
  public:&lt;br /&gt;
  void dibujar() const;&lt;br /&gt;
  void rotar(int) { }&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class Triangulo : public Poligono {     // Otro tipo de pológono&lt;br /&gt;
  protected:&lt;br /&gt;
  Punto a, b, c;&lt;br /&gt;
  ...&lt;br /&gt;
  public:&lt;br /&gt;
  void dibujar() const;&lt;br /&gt;
  void rotar(int);&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Lo que se pretende con este tipo de jerarquía es que los usuarios de subclases manejen los distintos polígonos a través de su interfaz pública (sus miembros públicos), mientras que los implementadores (creadores de los diversos tipos de polígonos que puedan existir en la aplicación), compartan los aspectos representados por los miembros protegidos.&lt;br /&gt;
Los miembros protegidos son utilizados también para aquellos aspectos que son dependientes de la implementación. Por ejemplo, aunque la propiedad color será compartida por todas las clases de polígonos, posiblemente su definición dependa de aspectos concretos de la implementación, es decir, del concepto de &amp;quot;color&amp;quot; del sistema operativo, que probablemente estará en definiciones en ficheros de cabecera.&lt;br /&gt;
Los miembros en la superclase (polimórfica) representan las partes que son comunes a todos los miembros (a todos los polígonos) pero en la mayoría de los casos no es sencillo decidir cuáles serán estos miembros (propiedades o métodos) compartidos por todas las clases derivadas. Por ejemplo, aunque se puede definir un centro para cualquier polígono, mantener su valor puede ser una molestia innecesaria en la mayoría de los polígonos y sobre todo en los triángulos, mientras es imprescindible en los círculos y muy útil en el resto de polígonos equiláteros.&lt;br /&gt;
=== Ejemplo ===&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {                 // L.4:  Clase-base&lt;br /&gt;
  public: virtual int fun(int x) {return x * x;}   // L.5 virtual&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {     // Clase derivada-1&lt;br /&gt;
  public:  int fun (int x) {return x + 10;}        // L.8 virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {     // Clase derivada-2&lt;br /&gt;
  public:  int fun (int x) {return x + 15;}        // L.11 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {          // =========&lt;br /&gt;
  B b; D1 d1; D2 d2;      // M.1&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; b.fun(10)     &amp;lt;&amp;lt; endl;  // M.2:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.fun(10)    &amp;lt;&amp;lt; endl;  // M.3:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.fun(10)    &amp;lt;&amp;lt; endl;  // M.4:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.B::fun(10) &amp;lt;&amp;lt; endl;  // M.5:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.B::fun(10) &amp;lt;&amp;lt; endl;  // M.6:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
Comentario&lt;br /&gt;
Definimos una clase-base B, en la que definimos una función virtual fun; a continuación derivamos de ella dos subclases D1 y D2, en las que definimos sendas versiones de fun que solapan la versión existente en la clase-base.&lt;br /&gt;
Las versiones de fun en L.8 y L.11 son virtuales, a pesar de no tener el declarador virtual indicado explícitamente. Estas versiones son un caso de polimorfismo, y solapan a la versión definida en la clase-base.&lt;br /&gt;
La línea M.1 instancia tres objetos de las clases anteriormente definidas.  En las líneas M.2 a M.4 comprobamos sus valores, que son los esperados (en cada caso se ha utilizado la versión de fun adecuada al objeto correspondiente).  Observe que la elección de la función adecuada no se realiza por el análisis de los argumentos pasados a la función como en el caso de la sobrecarga (aquí los argumentos son iguales en todos los casos), sino por la &amp;quot;naturaleza&amp;quot; del objeto que invoca la función;  esta es precisamente la característica distintiva del del polimorfismo.&lt;br /&gt;
Las líneas M.5 y M.6 sirven para recordarnos que a pesar del solapamiento, la versión de fun de la superclase sigue existiendo, y es accesible en los objetos de las clases derivadas utilizando el sobrecontrol adecuado.&lt;br /&gt;
Nota: la utilización del operador :: de acceso a ámbito anula el mecanismo de funciones virtuales, pero es aconsejable no usarlo en demasía, pues conduce a programas más difíciles de mantener. Como regla general, este tipo de calificación solo debe utilizarse para acceder a miembros del subobjeto heredado como es el caso del ejemplo.&lt;br /&gt;
Ejemplo-2&lt;br /&gt;
Hagamos ahora de abogados del diablo compilando el ejemplo anterior con la única modificación de que el método fun de B no sea virtual, sino un método normal. Es decir, la sentencia L.5, quedaría como:&lt;br /&gt;
public: int fun(int x) {return x * x;}    // L.5b no virtual!!&lt;br /&gt;
En este caso, comprobamos que el resultado coincide exactamente con el anterior, lo que nos induciría a preguntar ¿Para qué diablos sirven entonces las funciones virtuales?&lt;br /&gt;
Ejemplo-3&lt;br /&gt;
La explicación podemos encontrala fácilmente mediante una pequeña modificación en el programa: en vez de acceder directamente a los miembros de los objetos utilizando el selector directo de miembro, en las sentencias de salida, realizaremos el acceso mediante punteros a las clases correspondientes. De estos punteros declararemos dos tipos: a la superclase y a las clases derivadas (por brevedad hemos suprimido las sentencias de comprobación M.5 y M.6).&lt;br /&gt;
El nuevo diseño sería el siguiente:&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {                 // L.4: Clase-base&lt;br /&gt;
  public: virtual int fun(int x) {return x * x;}  // L.5 virtual&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {     // Clase derivada-1&lt;br /&gt;
  public: int fun (int x) {return x + 10;}        // L.8 virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {     // Clase derivada-2&lt;br /&gt;
  public: int fun (int x) {return x + 15;}        // L.11 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {          // =========&lt;br /&gt;
  B b; D1 d1; D2 d2;      // M.1&lt;br /&gt;
  B* bp = &amp;amp;b; B* bp1 = &amp;amp;d1; B* bp2 = &amp;amp;d2;           // M.1a&lt;br /&gt;
  D1* d1p = &amp;amp;d1; D2* d2p = &amp;amp;d2;                     // M.1b&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;   // M.2a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp1-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.3a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp2-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.3b:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1p-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.4a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2p-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.4b:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
Comentario&lt;br /&gt;
La sentencia M.1a define tres punteros a la clase-base. No obstante, dos de ellos se utilizan para señalar objetos de las sub-clases. Esto es típico de los punteros en jerarquías de clases. Precisamente se introdujo esta &amp;quot;relajación&amp;quot; en el control de tipos, para facilitar ciertas funcionalidades de las clases polimórficas.&lt;br /&gt;
La sentencia M.1b define sendos punteros a subclase, que en este caso si son aplicados a entidades de su mismo tipo.&lt;br /&gt;
Teniendo en cuenta las modificaciones efectuadas, y como no podía ser menos, las nuevas salidas son exactamente análogas a las del ejemplo inicial.&lt;br /&gt;
Ejemplo-4&lt;br /&gt;
Si suprimimos la declaración de virtual para la sentencia L.5 y volvemos a compilar el programa, se obtienen los resultados siguientes:&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
En ausencia de enlazado retrasado, las sentencias M.3a y M.3b, que acceden a métodos de objetos a través de punteros a la superclase, se refieren a los métodos heredados (que se definieron en la superclase). En este contexto pueden considerarse equivalentes los siguientes pares de expresiones:&lt;br /&gt;
bp1-&amp;gt;fun(10)  ==  d1.B::fun(10)&lt;br /&gt;
bp2-&amp;gt;fun(10)  ==  d2.B::fun(10)&lt;br /&gt;
&lt;br /&gt;
Hay ocasiones es que este comportamiento no interesa. Precisamente en las clases abstractas, en las que la definición de B::fun() no existe en absoluto, y expresiones como M.3a y M.3b conducirían a error si fun() no fuese declarada virtual pura en B.&lt;br /&gt;
Ejemplo-5&lt;br /&gt;
Presentamos una variación muy interesante del primer ejemplo, en el que simplemente hemos eliminado la línea 11, de forma que no existe definición específica de fun en la subclase D2.&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {                 // L.4:  Clase-base&lt;br /&gt;
  public:  virtual int fun(int x) {return x * x;}   // L.5 virtual&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {     // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 10;}         // L.8 virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B { };  // Clase derivada&lt;br /&gt;
&lt;br /&gt;
int main(void) {          // =========&lt;br /&gt;
  B b; D1 d1; D2 d2;      // M.1&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; b.fun(10)     &amp;lt;&amp;lt; endl;  // M.2:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.fun(10)    &amp;lt;&amp;lt; endl;  // M.3:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.fun(10)    &amp;lt;&amp;lt; endl;  // M.4:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.B::fun(10) &amp;lt;&amp;lt; endl;  // M.5:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.B::fun(10) &amp;lt;&amp;lt; endl;  // M.6:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
Comentario&lt;br /&gt;
El objeto d2 no dispone ahora de una definición específica de la función virtual fun, por lo que cualquier invocación a la misma supone utilizar la versión heredada de la superclase. En este caso las invocaciones en M.4 y M.6 utilizan la misma (y única) versión de dicha función.&lt;br /&gt;
&lt;br /&gt;
No confundir el mecanismo de las funciones virtuales con el de sobrecarga y ocultación. Sea el caso siguiente:&lt;br /&gt;
class Base {&lt;br /&gt;
  public:&lt;br /&gt;
  void fun (int);    // No virtual!!&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
class Derivada : public Base {&lt;br /&gt;
  public:&lt;br /&gt;
  void fun (int);    // Oculta a Base::fun&lt;br /&gt;
  void fun (char);   // versión sobrecargada de la anterior&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
Aquí pueden declararse las funciones void Base::fun(int) y void Derivada::fun(int); incluso sin ser virtuales. En este caso, se dice que void Derivada::fun(int) oculta cualquier otra versión de fun(int) que exista en cualquiera de sus ancestros. Además, si la clase Derivada define otras versiones de fun(), es decir, existen versiones de Derivada::fun() con diferentes definiciones, entonces se dice de estas últimas son versiones sobrecargadas de Derivada::fun(). Por supuesto, estas versiones sobrecargadas deberán seguir las reglas correspondientes.&lt;br /&gt;
Ejemplo-6&lt;br /&gt;
Para ilustrar el mecanismo de ocultación en un ejemplo ejecutable, utilizaremos una pequeña variación del ejemplo anterior (Ejemplo-3  ):&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {                // L.4: Clase-base&lt;br /&gt;
  public: virtual int fun(int x) {return x * x;}    // L.5 virtual&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {    // Clase derivada-1&lt;br /&gt;
  public: int fun (int x, int y) {return x + 10;}   // L.8 NO virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {    // Clase derivada-2&lt;br /&gt;
  public: int fun (int x) {return x + 15;}          // L.11 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {         // =========&lt;br /&gt;
  B b; D1 d1; D2 d2;     // M.1&lt;br /&gt;
  B* bp = &amp;amp;b; B* bp1 = &amp;amp;d1; B* bp2 = &amp;amp;d2;           // M.1a&lt;br /&gt;
  D1* d1p = &amp;amp;d1; D2* d2p = &amp;amp;d2;     // M.1b&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;   // M.2a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp1-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.3a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp2-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.3b:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1p-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.4a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2p-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.4b:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
En este caso nos hemos limitado a añadir un segundo argumento a la definición de D1::fun de la clase derivada-1 (L8). Como consecuencia, la nueva función no es virtual, ya que no cumple con las condiciones exigidas . El resultado es que en las instancias de D1, la definición B::fun de la superclase queda ocultada por la nueva definición , con la consecuencia de que la sentencia M.4a, que antes de la modificación funcionaba correctamente, produce ahora un error de compilación porque los argumentos actuales (un entero) no concuerdan con los argumentos formales esperados por la función (dos enteros).&lt;br /&gt;
Además el compilador nos advierte de la ocultación mediante una advertecia; en Borland C++: 'D1::fun(int,int)' hides virtual function 'B::fun(int)'.&lt;br /&gt;
&lt;br /&gt;
Cuando se declare una función como virtual tenga en mente que:&lt;br /&gt;
•	Solo pueden ser métodos (funciones-miembro).&lt;br /&gt;
•	No pueden ser declaradas friend de otras clases.&lt;br /&gt;
•	No pueden ser miembros estáticos &lt;br /&gt;
•	Los constructores no pueden ser declarados virtuales &lt;br /&gt;
•	Los destructores sí pueden ser virtuales.&lt;br /&gt;
&lt;br /&gt;
Las funciones virtuales no necesitan ser redefinidas en todas las clases derivadas. Puede existir una definición en la clase base y todas, o algunas de las subclases, pueden llamar a la función-base.&lt;br /&gt;
Para redefinir una función virtual en una clase derivada, las declaraciones en la clase base y en la derivada deben coincidir en cuanto a número y tipo de los parámetros. Excepcionalmente pueden diferir en el tipo devuelto; este caso es discutido más adelante.&lt;br /&gt;
&lt;br /&gt;
Una función virtual redefinida, que solapa la función de la superclase, sigue siendo virtual y no necesita el especificador virtual en su declaración en la subclase. La propiedad virtual es heredada automáticamente por las funciones de la subclase. Aunque si la subclase va a ser derivada de nuevo, entonces sí es necesario el especificador.&lt;br /&gt;
Ejemplo:&lt;br /&gt;
class B {       // Superclase&lt;br /&gt;
   public:&lt;br /&gt;
   virtual int func();&lt;br /&gt;
};&lt;br /&gt;
...&lt;br /&gt;
class D1 : public B {     // Derivada&lt;br /&gt;
  public:&lt;br /&gt;
  int fun ();             // virtual por defecto&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {     // Derivada&lt;br /&gt;
  public:&lt;br /&gt;
  virtual int fun ();     // virtual explícita&lt;br /&gt;
};&lt;br /&gt;
class D1a : public D1 {   // Derivada&lt;br /&gt;
  public:&lt;br /&gt;
  int fun ();             // No virtual!!&lt;br /&gt;
};&lt;br /&gt;
class D2a : public D2 {   // Derivada&lt;br /&gt;
  public:&lt;br /&gt;
  int fun ();             // Ok Virtual!!&lt;br /&gt;
  int fun (char);         // No virtual!!&lt;br /&gt;
};&lt;br /&gt;
De la simple inspección de las dos últimas líneas, no es posible deducir que el método fun de la clase D2a es un método virtual. Esto representa en ocasiones un problema y puede ser motivo de confusión, ya que es muy frecuente que las definiciones de las superclases se encuentren en ficheros de cabecera, y el programador que utiliza tales superclases para derivar versiones específicas debe consultar dichos ficheros. Sobre todo, porque como se indicó en el epígrafe anterior, la declaración en la subclase debe coincidir en cuanto a número y tipo de los parámetros. En caso contrario se trataría de una nueva definición, con lo que estamos ante un caso de sobrecarga y se ignora el mecanismo de enlazado retrasado.&lt;br /&gt;
== Invocación de funciones virtuales ==&lt;br /&gt;
Lo que realmente caracteriza a las funciones virtuales es la forma muy especial que utiliza el compilador para invocarlas; forma que es posible gracias a su tipo de enlazado. Por lo demás, el mecanismo externo (la sintaxis utilizada) es exactamente igual que la del resto de funciones miembro. He aquí un resumen de esta sintaxis:&lt;br /&gt;
class CB {              // Clase-base&lt;br /&gt;
   public:&lt;br /&gt;
   void fun1(){...}     // definición-10&lt;br /&gt;
   void virtual fun2(){...}    // definición-20&lt;br /&gt;
   ...&lt;br /&gt;
};&lt;br /&gt;
class D1 : public CB {  // Derivada-1&lt;br /&gt;
   public:&lt;br /&gt;
   void fun1() {...}    // definición-11&lt;br /&gt;
   void fun2() {...}    // definición-12&lt;br /&gt;
};&lt;br /&gt;
class D2 : public CB {  // Derivada-2&lt;br /&gt;
   public:&lt;br /&gt;
   void fun1() {...}    // definición-21&lt;br /&gt;
   void fun2() {...}    // definición-22&lt;br /&gt;
};&lt;br /&gt;
...&lt;br /&gt;
CB obj; D1 obj1;  D2 obj2;     // se instancian objetos de las clases&lt;br /&gt;
...&lt;br /&gt;
obj.fun1();             // invoca definición-10&lt;br /&gt;
obj.fun2();             // invoca definición-20&lt;br /&gt;
obj1.fun1();            // invoca definición-11&lt;br /&gt;
obj1.fun2();            // invoca definición-12&lt;br /&gt;
obj1.CB::fun1();        // invoca definición-10&lt;br /&gt;
obj1.CB::fun2();        // invoca definición-20&lt;br /&gt;
obj2.fun1();            // invoca definición-21&lt;br /&gt;
obj2.fun2();            // invoca definición-22&lt;br /&gt;
obj2.CB::fun1();        // invoca definición-10&lt;br /&gt;
obj2.CB::fun2();        // invoca definición-20&lt;br /&gt;
La dierencia entre las invocaciones obj.fun1() y obj1.CB::fun1(), estriba en que la misma función se ejecuta sobre distinto juego de variables. Por contra, en obj.fun1() y obj.fun2(), funciones distintas se ejecutan sobre el mismo juego de variables.&lt;br /&gt;
CB* ptr = &amp;amp;obj;         // se definen punteros a los objetos&lt;br /&gt;
D1* ptr1= &amp;amp;obj1;&lt;br /&gt;
D2* ptr2= &amp;amp;obj2;&lt;br /&gt;
...&lt;br /&gt;
ptr-&amp;gt;fun1();            // invoca definición-10&lt;br /&gt;
ptr1-&amp;gt;fun1();           // invoca definición-11&lt;br /&gt;
ptr2-&amp;gt;fun1();           // invoca definición-21&lt;br /&gt;
&lt;br /&gt;
Cuando desde un objeto se invoca un método (virtual o no) utilizando el nombre del objeto mediante los operadores de acceso a miembros, directo, o indirecto,  se invoca el código de la función correspondiente a la clase de la que se instancia el objeto. Es decir, el código invocado solo depende del tipo de objeto (y de la sintaxis de la invocación). Esta información puede conocerse en tiempo de compilación, en cuyo caso se utilizaría enlazado estático. En otros casos este dato solo es conocido en tiempo de ejecución, por lo que debería emplearse enlazado dinámico.&lt;br /&gt;
Cualquiera que sea el mecanismo para referenciar al objeto que invoca a la función (operador de acceso directo -1- o indirecto -2-):&lt;br /&gt;
obj.fun1()      // -1-&lt;br /&gt;
ptr-&amp;gt;fun1()     // -2-&lt;br /&gt;
La función conoce cuál es el objeto que la invoca -que juego de variables debe utilizar- a través del argumento implícito this.&lt;br /&gt;
== Invocación en jerarquías de clases ==&lt;br /&gt;
Sea B es una clase base, y otra D derivada públicamente de B. Cada una contiene una función virtual vf, entonces si vf es invocada por un objeto de D, la llamada que se realiza es D::vf(), incluso cuando el acceso se realiza vía un puntero o referencia a la superclase B. Ejemplo:&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class C {               // Clase-base&lt;br /&gt;
  public: virtual int get() {return 10;}&lt;br /&gt;
};&lt;br /&gt;
class D : public C {    // Derivada&lt;br /&gt;
  public: virtual int get() {return 100;}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {        // =========&lt;br /&gt;
  D d;&lt;br /&gt;
  C* cptr = &amp;amp;d;&lt;br /&gt;
  C&amp;amp; cref = d;&lt;br /&gt;
  cout &amp;lt;&amp;lt; d.get()     &amp;lt;&amp;lt; endl;&lt;br /&gt;
  cout &amp;lt;&amp;lt; cptr-&amp;gt;get() &amp;lt;&amp;lt; endl;&lt;br /&gt;
  cout &amp;lt;&amp;lt; cref.get()  &amp;lt;&amp;lt; endl;&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
100&lt;br /&gt;
100&lt;br /&gt;
100&lt;br /&gt;
&lt;br /&gt;
==  Tabla de funciones virtuales ==&lt;br /&gt;
Las funciones virtuales pagan un tributo por su versatilidad. Cada objeto de la clase derivada tiene que incluir un puntero (vfptr) a una tabla de direcciones de funciones virtuales, conocida como vtable. La utilización de dicho puntero permite seleccionar desde el objeto, la función correspondiente en tiempo de ejecución. Como resultado, el mecanismo de invocación de estas funciones  es mucho menos eficiente que el de los métodos normales (enlazado estático), por lo que debe reservarse su utilización a los casos estrictamente necesarios.&lt;br /&gt;
Es fácil poner en evidencia la existencia del puntero vfptr mediante un sencillo experimento que utiliza el operador sizeof&lt;br /&gt;
struct S1 {&lt;br /&gt;
  int n;&lt;br /&gt;
  double get() { return n; } // método auxiliar normal&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct S2 {&lt;br /&gt;
  int n;&lt;br /&gt;
  virtual double get() { return n; } // método virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
size_t tamS1 = sizeof(S1);  // -&amp;gt; 4&lt;br /&gt;
size_t tamS2 = sizeof(S2);  // -&amp;gt; 8&lt;br /&gt;
Comentario&lt;br /&gt;
El resultado del tamaño de ambos tipos es respectivamente 4 y 8 en cualquiera de los compiladores comprobados: Borland C++ 5.5 y gcc-g++ 3.4.2-20040916-1 para Windows. La diferencia de 4 Bytes obtenida corresponde precisamente a la presencia del mencionado puntero oculto.&lt;br /&gt;
== Función virtual pura ==&lt;br /&gt;
En ocasiones se lleva al extremo el concepto &amp;quot;virtual&amp;quot; en la declaración de una súper clase (&amp;quot;esta función será redefinida más tarde en las clases derivadas&amp;quot;), por lo que en ella solo existe una declaración de la función, relegándose las distintas definiciones a las clases derivadas. Entonces se dice que esta función es virtual pura. Esta circunstancia hay que advertirla al compilador; es una forma de decirle que la falta de definición no es un olvido por nuestra parte (de lo contrario el compilador nos señala que se nos ha olvidado la definición); esto se hace igualando a cero la declaración de la función:&lt;br /&gt;
virtual int funct1(void);      // Declara función virtual&lt;br /&gt;
virtual int funct2(void) = 0;  // Declara función virtual pura&lt;br /&gt;
&lt;br /&gt;
La existencia de una función virtual basta para que la clase que estamos definiendo sea polimórfica. Si además igualamos la función a cero, la estaremos declarando como función virtual pura, lo que automáticamente declara la clase como abstracta &lt;br /&gt;
Es muy frecuente que las funciones virtuales puras se declaren además con el calificador const , de forma que es usual encontrar expresiones del tipo:&lt;br /&gt;
virtual int funct2(void) const = 0;  // Declara función virtual pura y constante&lt;br /&gt;
==  Ejemplo ==&lt;br /&gt;
El ejemplo que sigue es una modificación del anterior , en el que declaramos la función fun de la clase-base B como virtual pura, con lo que podemos omitir su definición.&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {              // L.4:  Clase-base&lt;br /&gt;
  public:  virtual int fun(int x) = 0;       // L.5 virtual pura&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {  // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 10;}  // L.8 virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {  // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 15;}  // L.11 virtual&lt;br /&gt;
};&lt;br /&gt;
int main(void) {       // =========&lt;br /&gt;
  D1 d1; D2 d2;        // M.1&lt;br /&gt;
&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.fun(10)    &amp;lt;&amp;lt; endl;  // M.3:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.fun(10)    &amp;lt;&amp;lt; endl;  // M.4:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
Comentario&lt;br /&gt;
El resto del programa se mantiene prácticamente igual al modelo anterior, con la salvedad de que ahora en M1 no podemos instanciar un objeto directamente de la superclase B; la razón es que la superclase está incompleta (falta la definición de fun). Si lo intentáramos, el compilador nos mostraría un error señalando que no se puede instanciar un objeto de la clase B y que dicha clase es abstracta; además las clases abstractas no son instanciables por definición.&lt;br /&gt;
En lo que respecta a las salidas, comprobamos que son los valores esperados.&lt;br /&gt;
&lt;br /&gt;
Una declaración de función no puede ser al mismo tiempo una definición y una declaración de virtual pura. Ejemplo:&lt;br /&gt;
struct Est {&lt;br /&gt;
    virtual void f() { /* ... */ } = 0;    // Error!!&lt;br /&gt;
};&lt;br /&gt;
La forma legal de proporcionar una definición es:&lt;br /&gt;
struct Est {&lt;br /&gt;
  virtual void f(void) = 0;    // declara f virtual pura&lt;br /&gt;
};&lt;br /&gt;
virtual void Est::f(void) {    // definición posterior de f&lt;br /&gt;
   /* código de la función f  */&lt;br /&gt;
};&lt;br /&gt;
== Un mundo de excepciones ==&lt;br /&gt;
Seguramente el lector que haya llegado hasta aquí experimente una cierta perplejidad (que comparto). En el párrafo §7  decimos que se utiliza el recurso de declarar una función virtual pura para poder omitir la definición, y a continuación, en el párrafo §7.2 exponemos la forma legal de proporcionarla...  El lector puede comprobar que esta aparente contradicción es asumida por el compilador sin protestas. En efecto, considere el ejemplo siguiente en el que modificamos el anterior añadiendo una definición a la función virtual pura fun.&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {               // L.4:  Clase-base&lt;br /&gt;
  public:  virtual int fun(int x) = 0;       // L.5 virtual pura&lt;br /&gt;
};&lt;br /&gt;
int B::fun(int x) {return x * x}             // L.7 definición de fun&lt;br /&gt;
&lt;br /&gt;
class D1 : public B {   // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 10;}  // L.9 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class D2 : public B {   // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 15;}  // L.12 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {        // =========&lt;br /&gt;
  D1 d1; D2 d2;         // M.1&lt;br /&gt;
&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.fun(10)    &amp;lt;&amp;lt; endl;  // M.3:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.fun(10)    &amp;lt;&amp;lt; endl;  // M.4:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.B::fun(10) &amp;lt;&amp;lt; endl;  // M.5:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.B::fun(10) &amp;lt;&amp;lt; endl;  // M.6:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
== Tipos devueltos por las funciones virtuales ==&lt;br /&gt;
Cuando se redefine una función virtual no se puede cambiarse el tipo de valor devuelto. Para redefinir una función virtual en alguna clase derivada, la nueva función debe coincidir exactamente en número y tipo con los parámetros de la declaración inicial (la &amp;quot;firma&amp;quot; -Signature- de ambas funciones deben ser iguales). Si no coinciden en esto, el compilador C++ considera que se trata de funciones diferentes (un caso de sobrecarga) y se ignora el mecanismo de funciones virtuales.&lt;br /&gt;
Para prevenir que puedan producirse errores inadvertidos, el compilador C++ GNU dispone de la opción  -Woverloaded-virtual, que produce un mensaje de aviso, si se redefine un método declarado previamente virtual en una clase antecesora, y no se cumple la condición de igualdad de firmas.&lt;br /&gt;
No obstante lo anterior, hay casos en que las funciones virtuales redefinidas en clases derivadas devuelven un tipo diferente del de la función virtual de la clase base. Esto es posible solo cuando se dan simultáneamente las dos condiciones siguientes:&lt;br /&gt;
•	La función virtual sobrecontrolada devuelve un puntero o referencia a clase base.&lt;br /&gt;
•	La nueva versión devuelve un puntero o referencia a la clase derivada.&lt;br /&gt;
=== Ejemplo ===&lt;br /&gt;
struct X {};            // clase base.&lt;br /&gt;
struct Y : X {};        // clase derivada (:public X por defecto).&lt;br /&gt;
struct B {              // clase base.&lt;br /&gt;
   virtual void vf1();  // L.4:&lt;br /&gt;
   virtual void vf2();&lt;br /&gt;
   virtual void vf3();&lt;br /&gt;
   void f();&lt;br /&gt;
   virtual X* pf();     /* L.8:  devuelve puntero a clase base,&lt;br /&gt;
                            esta función virtual puede ser sobrecontrolada */&lt;br /&gt;
};&lt;br /&gt;
class D : public B {    // clase derivada&lt;br /&gt;
   public:&lt;br /&gt;
   virtual void vf1();  // L.12: Especificador virtual, legal pero redundante&lt;br /&gt;
   void vf2(int);       /* L.13: No virtual, oculta B::vf2()&lt;br /&gt;
                            dado que usa otros argumentos */&lt;br /&gt;
// char vf3();          // L.14: Ilegal! cambia solo el tipo devuelto!&lt;br /&gt;
   void f();            // L.15: privativa de D (no virtual)&lt;br /&gt;
   Y*   pf();           /* L.16: función sobrecontrolante; difiere solo&lt;br /&gt;
                          en el tipo devuelto. Devuelve puntero a subclase */&lt;br /&gt;
};&lt;br /&gt;
void extf() {&lt;br /&gt;
   D d;                 // d objeto de la clase D (instancia)&lt;br /&gt;
   B* bp = &amp;amp;d;          /* L.20: Conversión estándar D* a B*&lt;br /&gt;
                  Inicializa bp con la tabla de funciones del objeto d.&lt;br /&gt;
                  Si no existe entrada para una función en dicha tabla,&lt;br /&gt;
                  utiliza la función de la tabla de la clase B */&lt;br /&gt;
   bp–&amp;gt;vf1();           // invoca D::vf1&lt;br /&gt;
   bp–&amp;gt;vf2();           // invoca B::vf2 (D::vf2 tiene diferentes argumentos)&lt;br /&gt;
   bp–&amp;gt;f();             // invoca B::f (not virtual)&lt;br /&gt;
   X* xptr = bp–&amp;gt;pf();  /* invoca D::pf() y convierte el resultado&lt;br /&gt;
                            en un puntero a X */&lt;br /&gt;
   D* dptr = &amp;amp;d;&lt;br /&gt;
   Y* yptr = dptr–&amp;gt;pf(); /* inicializa yptr; este puntero invocará a D::pf()&lt;br /&gt;
                            No se realiza ninguna conversión */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
L.12:  La versión D::vf1 es virtual automáticamente, dado que devuelve lo mismo y tiene los mismos parámetros que su homónima en la superclase B. El especificador virtual puede ser utilizado en estos casos pero no es estrictamente necesario a no ser que se vayan a derivar nuevas subclases de la clase derivada.&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Puede Contactar  ==&lt;br /&gt;
*[[Declaración de funciones|Declaración de funciones]] &lt;br /&gt;
*[[Sobrecarga de funciones (programación)|Sobrecarga de funciones (programación)]]&lt;br /&gt;
*[[Parámetros y argumentos (programación)|Parámetros y argumentos (programación)]]&lt;br /&gt;
*[[Invocación de funciones (programación)|Invocación de funciones (programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Sobrecarga de enumeraciones (Informática)|Sobrecarga de enumeraciones (Informática)]] &lt;br /&gt;
*[[Referencias (programación)|Referencias (programación)]]&lt;br /&gt;
== Fuentes  ==&lt;br /&gt;
* [http://www.zator.com/Cpp/E4_4.htm Funciones]&lt;br /&gt;
* [http://www.fismat.umich.mx/mn1/manual/node7.html Funciones en C ++]&lt;br /&gt;
*     [http://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Funciones#Definiendo_una_funci.C3.B3n    Programación en C++/Funciones]&lt;br /&gt;
*    [http://c.conclase.net/curso/?cap=020#inicio Funciones]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]] [[Category:Programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
	<entry>
		<id>https://www.ecured.cu/index.php?title=Funciones_virtuales&amp;diff=3024726</id>
		<title>Funciones virtuales</title>
		<link rel="alternate" type="text/html" href="https://www.ecured.cu/index.php?title=Funciones_virtuales&amp;diff=3024726"/>
		<updated>2017-12-12T18:06:56Z</updated>

		<summary type="html">&lt;p&gt;Majibacoa2 jc: Página creada con «&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Funciones virtuales |imagen=   |concepto= Las funciones virtuales permiten que clases derivadas de una misma base (clases hermana...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div align=&amp;quot;justify&amp;quot;&amp;gt;{{Definición|Nombre= Funciones virtuales |imagen=   |concepto=&lt;br /&gt;
Las funciones virtuales permiten que clases derivadas de una misma base (clases hermanas) puedan tener diferentes versiones de un método. Se utiliza la palabra-clave virtual para avisar al compilador que un método será polimórfico y que en las clases derivadas existen distintas definiciones del mismo}}&lt;br /&gt;
''' Funciones virtuales '''. Las funciones virtuales permiten que clases derivadas de una misma base (clases hermanas) puedan tener diferentes versiones de un método. Se utiliza la palabra-clave virtual para avisar al compilador que un método será polimórfico y que en las clases derivadas existen distintas definiciones del mismo. En respuesta, el &amp;quot;Linker&amp;quot; utiliza para ella una técnica especial, enlazado retrasado. La declaración de virtual en un método de una clase, implica que esta es polimórfica, y que probablemente no se utilizará directamente para instanciar objetos, sino como super-clase de una jerarquía&lt;br /&gt;
Esta posibilidad, que un mismo método puede exhibir distintos comportamientos en los descendientes de una base común, es precisamente lo que posibilita y define el polimorfismo. En estos casos se dice que las descendientes de la función virtual solapan o sobrecontrolan (&amp;quot;Override&amp;quot;) la versión de la superclase, pero esta versión de la superclase puede no existir en absoluto. Es probable que en ella solo exista una declaración del tipo: vitual void foo(); sin que exista una definición de la misma. Para que pueda existir la declaración de un método sin que exista la definición correspondiente, el método debe ser virtual puro  (un tipo particular dentro de los virtuales).&lt;br /&gt;
Utilizaremos la siguiente terminología:  &amp;quot;función sobrecontrolada&amp;quot; o &amp;quot;solapada&amp;quot;, para referirnos a la versión en la superclase y &amp;quot;función sobrecontroladora&amp;quot; o &amp;quot;que solapa&amp;quot; para referirnos a la nueva versión en la clase derivada. Cualquier referencia al sobrecontrol o solapamiento (&amp;quot;Overriding&amp;quot;) indica que se está utilizando el mecanismo C++ de las funciones virtuales. Parecido pero no idéntico al de sobrecarga; conviene no confundir ambos conceptos. Más adelante intentamos aclarar sus diferencias .&lt;br /&gt;
== Sintaxis ==&lt;br /&gt;
Para declarar que un método de una clase base es virtual, su prototipo se declara como siempre, pero anteponiendo la palabra-clave virtual, que indica al compilador algo así como: &amp;quot;Será definido más tarde en una clase derivada&amp;quot;. Ejemplo:&lt;br /&gt;
virtual void dibujar();&lt;br /&gt;
Cuando se aplica a métodos de clase, el especificador virtual debe ser utilizado en la declaración, pero no en la definición si esta se realiza offline (fuera del cuerpo de la clase). Ejemplo:&lt;br /&gt;
class CL {&lt;br /&gt;
  ...&lt;br /&gt;
  virtual void func1();&lt;br /&gt;
  virtual void func2();&lt;br /&gt;
  virtual void func3() { ... }    // Ok. definición inline&lt;br /&gt;
};&lt;br /&gt;
virtual void CL::func1() { ... }  // Error!!&lt;br /&gt;
void CL::func2() { ... }          // Ok. definición offline&lt;br /&gt;
== Descripción ==&lt;br /&gt;
Al tratar del enlazado se indicaron las causas que justifican la existencia de este tipo de funciones en los lenguajes orientados a objeto (que aconsejamos repasar ahora. Para ayudarnos a comprender el problema que se pretende resolver con este tipo de funciones, exponemos una continuación del ejemplo de la clase Poligono al que nos referimos al tratar de las clases polimórficas:&lt;br /&gt;
&lt;br /&gt;
class Color { public: int R, G, B; };   // clase auxiliar&lt;br /&gt;
class Punto { public: float x, y; };    // clase auxiliar&lt;br /&gt;
&lt;br /&gt;
class Poligono {        // clase-base (polimórfica)&lt;br /&gt;
  protected:            // interfaz para las clases derivadas&lt;br /&gt;
  Punto centro;&lt;br /&gt;
  Color col;&lt;br /&gt;
  ...&lt;br /&gt;
  public:               // interfaz para los usuarios de poligonos&lt;br /&gt;
  virtual void dibujar() const;&lt;br /&gt;
  virtual void rotar(int grados);&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class Circulo : public Poligono {       // Un tipo de polígono&lt;br /&gt;
  protected:&lt;br /&gt;
  int radio;&lt;br /&gt;
  ...&lt;br /&gt;
  public:&lt;br /&gt;
  void dibujar() const;&lt;br /&gt;
  void rotar(int) { }&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class Triangulo : public Poligono {     // Otro tipo de pológono&lt;br /&gt;
  protected:&lt;br /&gt;
  Punto a, b, c;&lt;br /&gt;
  ...&lt;br /&gt;
  public:&lt;br /&gt;
  void dibujar() const;&lt;br /&gt;
  void rotar(int);&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Lo que se pretende con este tipo de jerarquía es que los usuarios de subclases manejen los distintos polígonos a través de su interfaz pública (sus miembros públicos), mientras que los implementadores (creadores de los diversos tipos de polígonos que puedan existir en la aplicación), compartan los aspectos representados por los miembros protegidos.&lt;br /&gt;
Los miembros protegidos son utilizados también para aquellos aspectos que son dependientes de la implementación. Por ejemplo, aunque la propiedad color será compartida por todas las clases de polígonos, posiblemente su definición dependa de aspectos concretos de la implementación, es decir, del concepto de &amp;quot;color&amp;quot; del sistema operativo, que probablemente estará en definiciones en ficheros de cabecera.&lt;br /&gt;
Los miembros en la superclase (polimórfica) representan las partes que son comunes a todos los miembros (a todos los polígonos) pero en la mayoría de los casos no es sencillo decidir cuáles serán estos miembros (propiedades o métodos) compartidos por todas las clases derivadas. Por ejemplo, aunque se puede definir un centro para cualquier polígono, mantener su valor puede ser una molestia innecesaria en la mayoría de los polígonos y sobre todo en los triángulos, mientras es imprescindible en los círculos y muy útil en el resto de polígonos equiláteros.&lt;br /&gt;
=== Ejemplo ===&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {                 // L.4:  Clase-base&lt;br /&gt;
  public: virtual int fun(int x) {return x * x;}   // L.5 virtual&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {     // Clase derivada-1&lt;br /&gt;
  public:  int fun (int x) {return x + 10;}        // L.8 virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {     // Clase derivada-2&lt;br /&gt;
  public:  int fun (int x) {return x + 15;}        // L.11 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {          // =========&lt;br /&gt;
  B b; D1 d1; D2 d2;      // M.1&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; b.fun(10)     &amp;lt;&amp;lt; endl;  // M.2:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.fun(10)    &amp;lt;&amp;lt; endl;  // M.3:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.fun(10)    &amp;lt;&amp;lt; endl;  // M.4:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.B::fun(10) &amp;lt;&amp;lt; endl;  // M.5:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.B::fun(10) &amp;lt;&amp;lt; endl;  // M.6:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
Comentario&lt;br /&gt;
Definimos una clase-base B, en la que definimos una función virtual fun; a continuación derivamos de ella dos subclases D1 y D2, en las que definimos sendas versiones de fun que solapan la versión existente en la clase-base.&lt;br /&gt;
Las versiones de fun en L.8 y L.11 son virtuales, a pesar de no tener el declarador virtual indicado explícitamente. Estas versiones son un caso de polimorfismo, y solapan a la versión definida en la clase-base.&lt;br /&gt;
La línea M.1 instancia tres objetos de las clases anteriormente definidas.  En las líneas M.2 a M.4 comprobamos sus valores, que son los esperados (en cada caso se ha utilizado la versión de fun adecuada al objeto correspondiente).  Observe que la elección de la función adecuada no se realiza por el análisis de los argumentos pasados a la función como en el caso de la sobrecarga (aquí los argumentos son iguales en todos los casos), sino por la &amp;quot;naturaleza&amp;quot; del objeto que invoca la función;  esta es precisamente la característica distintiva del del polimorfismo.&lt;br /&gt;
Las líneas M.5 y M.6 sirven para recordarnos que a pesar del solapamiento, la versión de fun de la superclase sigue existiendo, y es accesible en los objetos de las clases derivadas utilizando el sobrecontrol adecuado.&lt;br /&gt;
Nota: la utilización del operador :: de acceso a ámbito anula el mecanismo de funciones virtuales, pero es aconsejable no usarlo en demasía, pues conduce a programas más difíciles de mantener. Como regla general, este tipo de calificación solo debe utilizarse para acceder a miembros del subobjeto heredado como es el caso del ejemplo.&lt;br /&gt;
Ejemplo-2&lt;br /&gt;
Hagamos ahora de abogados del diablo compilando el ejemplo anterior con la única modificación de que el método fun de B no sea virtual, sino un método normal. Es decir, la sentencia L.5, quedaría como:&lt;br /&gt;
public: int fun(int x) {return x * x;}    // L.5b no virtual!!&lt;br /&gt;
En este caso, comprobamos que el resultado coincide exactamente con el anterior, lo que nos induciría a preguntar ¿Para qué diablos sirven entonces las funciones virtuales?&lt;br /&gt;
Ejemplo-3&lt;br /&gt;
La explicación podemos encontrala fácilmente mediante una pequeña modificación en el programa: en vez de acceder directamente a los miembros de los objetos utilizando el selector directo de miembro, en las sentencias de salida, realizaremos el acceso mediante punteros a las clases correspondientes. De estos punteros declararemos dos tipos: a la superclase y a las clases derivadas (por brevedad hemos suprimido las sentencias de comprobación M.5 y M.6).&lt;br /&gt;
El nuevo diseño sería el siguiente:&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {                 // L.4: Clase-base&lt;br /&gt;
  public: virtual int fun(int x) {return x * x;}  // L.5 virtual&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {     // Clase derivada-1&lt;br /&gt;
  public: int fun (int x) {return x + 10;}        // L.8 virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {     // Clase derivada-2&lt;br /&gt;
  public: int fun (int x) {return x + 15;}        // L.11 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {          // =========&lt;br /&gt;
  B b; D1 d1; D2 d2;      // M.1&lt;br /&gt;
  B* bp = &amp;amp;b; B* bp1 = &amp;amp;d1; B* bp2 = &amp;amp;d2;           // M.1a&lt;br /&gt;
  D1* d1p = &amp;amp;d1; D2* d2p = &amp;amp;d2;                     // M.1b&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;   // M.2a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp1-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.3a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp2-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.3b:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1p-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.4a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2p-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.4b:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
Comentario&lt;br /&gt;
La sentencia M.1a define tres punteros a la clase-base. No obstante, dos de ellos se utilizan para señalar objetos de las sub-clases. Esto es típico de los punteros en jerarquías de clases. Precisamente se introdujo esta &amp;quot;relajación&amp;quot; en el control de tipos, para facilitar ciertas funcionalidades de las clases polimórficas.&lt;br /&gt;
La sentencia M.1b define sendos punteros a subclase, que en este caso si son aplicados a entidades de su mismo tipo.&lt;br /&gt;
Teniendo en cuenta las modificaciones efectuadas, y como no podía ser menos, las nuevas salidas son exactamente análogas a las del ejemplo inicial.&lt;br /&gt;
Ejemplo-4&lt;br /&gt;
Si suprimimos la declaración de virtual para la sentencia L.5 y volvemos a compilar el programa, se obtienen los resultados siguientes:&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
En ausencia de enlazado retrasado, las sentencias M.3a y M.3b, que acceden a métodos de objetos a través de punteros a la superclase, se refieren a los métodos heredados (que se definieron en la superclase). En este contexto pueden considerarse equivalentes los siguientes pares de expresiones:&lt;br /&gt;
bp1-&amp;gt;fun(10)  ==  d1.B::fun(10)&lt;br /&gt;
bp2-&amp;gt;fun(10)  ==  d2.B::fun(10)&lt;br /&gt;
&lt;br /&gt;
Hay ocasiones es que este comportamiento no interesa. Precisamente en las clases abstractas, en las que la definición de B::fun() no existe en absoluto, y expresiones como M.3a y M.3b conducirían a error si fun() no fuese declarada virtual pura en B.&lt;br /&gt;
Ejemplo-5&lt;br /&gt;
Presentamos una variación muy interesante del primer ejemplo, en el que simplemente hemos eliminado la línea 11, de forma que no existe definición específica de fun en la subclase D2.&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {                 // L.4:  Clase-base&lt;br /&gt;
  public:  virtual int fun(int x) {return x * x;}   // L.5 virtual&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {     // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 10;}         // L.8 virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B { };  // Clase derivada&lt;br /&gt;
&lt;br /&gt;
int main(void) {          // =========&lt;br /&gt;
  B b; D1 d1; D2 d2;      // M.1&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; b.fun(10)     &amp;lt;&amp;lt; endl;  // M.2:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.fun(10)    &amp;lt;&amp;lt; endl;  // M.3:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.fun(10)    &amp;lt;&amp;lt; endl;  // M.4:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.B::fun(10) &amp;lt;&amp;lt; endl;  // M.5:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.B::fun(10) &amp;lt;&amp;lt; endl;  // M.6:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
Comentario&lt;br /&gt;
El objeto d2 no dispone ahora de una definición específica de la función virtual fun, por lo que cualquier invocación a la misma supone utilizar la versión heredada de la superclase. En este caso las invocaciones en M.4 y M.6 utilizan la misma (y única) versión de dicha función.&lt;br /&gt;
&lt;br /&gt;
No confundir el mecanismo de las funciones virtuales con el de sobrecarga y ocultación. Sea el caso siguiente:&lt;br /&gt;
class Base {&lt;br /&gt;
  public:&lt;br /&gt;
  void fun (int);    // No virtual!!&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
class Derivada : public Base {&lt;br /&gt;
  public:&lt;br /&gt;
  void fun (int);    // Oculta a Base::fun&lt;br /&gt;
  void fun (char);   // versión sobrecargada de la anterior&lt;br /&gt;
  ...&lt;br /&gt;
};&lt;br /&gt;
Aquí pueden declararse las funciones void Base::fun(int) y void Derivada::fun(int); incluso sin ser virtuales. En este caso, se dice que void Derivada::fun(int) oculta cualquier otra versión de fun(int) que exista en cualquiera de sus ancestros. Además, si la clase Derivada define otras versiones de fun(), es decir, existen versiones de Derivada::fun() con diferentes definiciones, entonces se dice de estas últimas son versiones sobrecargadas de Derivada::fun(). Por supuesto, estas versiones sobrecargadas deberán seguir las reglas correspondientes.&lt;br /&gt;
Ejemplo-6&lt;br /&gt;
Para ilustrar el mecanismo de ocultación en un ejemplo ejecutable, utilizaremos una pequeña variación del ejemplo anterior (Ejemplo-3  ):&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {                // L.4: Clase-base&lt;br /&gt;
  public: virtual int fun(int x) {return x * x;}    // L.5 virtual&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {    // Clase derivada-1&lt;br /&gt;
  public: int fun (int x, int y) {return x + 10;}   // L.8 NO virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {    // Clase derivada-2&lt;br /&gt;
  public: int fun (int x) {return x + 15;}          // L.11 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {         // =========&lt;br /&gt;
  B b; D1 d1; D2 d2;     // M.1&lt;br /&gt;
  B* bp = &amp;amp;b; B* bp1 = &amp;amp;d1; B* bp2 = &amp;amp;d2;           // M.1a&lt;br /&gt;
  D1* d1p = &amp;amp;d1; D2* d2p = &amp;amp;d2;     // M.1b&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;   // M.2a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp1-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.3a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; bp2-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.3b:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1p-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.4a:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2p-&amp;gt;fun(10) &amp;lt;&amp;lt; endl;  // M.4b:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
En este caso nos hemos limitado a añadir un segundo argumento a la definición de D1::fun de la clase derivada-1 (L8). Como consecuencia, la nueva función no es virtual, ya que no cumple con las condiciones exigidas . El resultado es que en las instancias de D1, la definición B::fun de la superclase queda ocultada por la nueva definición , con la consecuencia de que la sentencia M.4a, que antes de la modificación funcionaba correctamente, produce ahora un error de compilación porque los argumentos actuales (un entero) no concuerdan con los argumentos formales esperados por la función (dos enteros).&lt;br /&gt;
Además el compilador nos advierte de la ocultación mediante una advertecia; en Borland C++: 'D1::fun(int,int)' hides virtual function 'B::fun(int)'.&lt;br /&gt;
&lt;br /&gt;
Cuando se declare una función como virtual tenga en mente que:&lt;br /&gt;
•	Solo pueden ser métodos (funciones-miembro).&lt;br /&gt;
•	No pueden ser declaradas friend de otras clases.&lt;br /&gt;
•	No pueden ser miembros estáticos &lt;br /&gt;
•	Los constructores no pueden ser declarados virtuales &lt;br /&gt;
•	Los destructores sí pueden ser virtuales.&lt;br /&gt;
&lt;br /&gt;
Las funciones virtuales no necesitan ser redefinidas en todas las clases derivadas. Puede existir una definición en la clase base y todas, o algunas de las subclases, pueden llamar a la función-base.&lt;br /&gt;
Para redefinir una función virtual en una clase derivada, las declaraciones en la clase base y en la derivada deben coincidir en cuanto a número y tipo de los parámetros. Excepcionalmente pueden diferir en el tipo devuelto; este caso es discutido más adelante.&lt;br /&gt;
&lt;br /&gt;
Una función virtual redefinida, que solapa la función de la superclase, sigue siendo virtual y no necesita el especificador virtual en su declaración en la subclase. La propiedad virtual es heredada automáticamente por las funciones de la subclase. Aunque si la subclase va a ser derivada de nuevo, entonces sí es necesario el especificador.&lt;br /&gt;
Ejemplo:&lt;br /&gt;
class B {       // Superclase&lt;br /&gt;
   public:&lt;br /&gt;
   virtual int func();&lt;br /&gt;
};&lt;br /&gt;
...&lt;br /&gt;
class D1 : public B {     // Derivada&lt;br /&gt;
  public:&lt;br /&gt;
  int fun ();             // virtual por defecto&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {     // Derivada&lt;br /&gt;
  public:&lt;br /&gt;
  virtual int fun ();     // virtual explícita&lt;br /&gt;
};&lt;br /&gt;
class D1a : public D1 {   // Derivada&lt;br /&gt;
  public:&lt;br /&gt;
  int fun ();             // No virtual!!&lt;br /&gt;
};&lt;br /&gt;
class D2a : public D2 {   // Derivada&lt;br /&gt;
  public:&lt;br /&gt;
  int fun ();             // Ok Virtual!!&lt;br /&gt;
  int fun (char);         // No virtual!!&lt;br /&gt;
};&lt;br /&gt;
De la simple inspección de las dos últimas líneas, no es posible deducir que el método fun de la clase D2a es un método virtual. Esto representa en ocasiones un problema y puede ser motivo de confusión, ya que es muy frecuente que las definiciones de las superclases se encuentren en ficheros de cabecera, y el programador que utiliza tales superclases para derivar versiones específicas debe consultar dichos ficheros. Sobre todo, porque como se indicó en el epígrafe anterior, la declaración en la subclase debe coincidir en cuanto a número y tipo de los parámetros. En caso contrario se trataría de una nueva definición, con lo que estamos ante un caso de sobrecarga y se ignora el mecanismo de enlazado retrasado.&lt;br /&gt;
== Invocación de funciones virtuales ==&lt;br /&gt;
Lo que realmente caracteriza a las funciones virtuales es la forma muy especial que utiliza el compilador para invocarlas; forma que es posible gracias a su tipo de enlazado. Por lo demás, el mecanismo externo (la sintaxis utilizada) es exactamente igual que la del resto de funciones miembro. He aquí un resumen de esta sintaxis:&lt;br /&gt;
class CB {              // Clase-base&lt;br /&gt;
   public:&lt;br /&gt;
   void fun1(){...}     // definición-10&lt;br /&gt;
   void virtual fun2(){...}    // definición-20&lt;br /&gt;
   ...&lt;br /&gt;
};&lt;br /&gt;
class D1 : public CB {  // Derivada-1&lt;br /&gt;
   public:&lt;br /&gt;
   void fun1() {...}    // definición-11&lt;br /&gt;
   void fun2() {...}    // definición-12&lt;br /&gt;
};&lt;br /&gt;
class D2 : public CB {  // Derivada-2&lt;br /&gt;
   public:&lt;br /&gt;
   void fun1() {...}    // definición-21&lt;br /&gt;
   void fun2() {...}    // definición-22&lt;br /&gt;
};&lt;br /&gt;
...&lt;br /&gt;
CB obj; D1 obj1;  D2 obj2;     // se instancian objetos de las clases&lt;br /&gt;
...&lt;br /&gt;
obj.fun1();             // invoca definición-10&lt;br /&gt;
obj.fun2();             // invoca definición-20&lt;br /&gt;
obj1.fun1();            // invoca definición-11&lt;br /&gt;
obj1.fun2();            // invoca definición-12&lt;br /&gt;
obj1.CB::fun1();        // invoca definición-10&lt;br /&gt;
obj1.CB::fun2();        // invoca definición-20&lt;br /&gt;
obj2.fun1();            // invoca definición-21&lt;br /&gt;
obj2.fun2();            // invoca definición-22&lt;br /&gt;
obj2.CB::fun1();        // invoca definición-10&lt;br /&gt;
obj2.CB::fun2();        // invoca definición-20&lt;br /&gt;
La dierencia entre las invocaciones obj.fun1() y obj1.CB::fun1(), estriba en que la misma función se ejecuta sobre distinto juego de variables. Por contra, en obj.fun1() y obj.fun2(), funciones distintas se ejecutan sobre el mismo juego de variables.&lt;br /&gt;
CB* ptr = &amp;amp;obj;         // se definen punteros a los objetos&lt;br /&gt;
D1* ptr1= &amp;amp;obj1;&lt;br /&gt;
D2* ptr2= &amp;amp;obj2;&lt;br /&gt;
...&lt;br /&gt;
ptr-&amp;gt;fun1();            // invoca definición-10&lt;br /&gt;
ptr1-&amp;gt;fun1();           // invoca definición-11&lt;br /&gt;
ptr2-&amp;gt;fun1();           // invoca definición-21&lt;br /&gt;
&lt;br /&gt;
Cuando desde un objeto se invoca un método (virtual o no) utilizando el nombre del objeto mediante los operadores de acceso a miembros, directo, o indirecto,  se invoca el código de la función correspondiente a la clase de la que se instancia el objeto. Es decir, el código invocado solo depende del tipo de objeto (y de la sintaxis de la invocación). Esta información puede conocerse en tiempo de compilación, en cuyo caso se utilizaría enlazado estático. En otros casos este dato solo es conocido en tiempo de ejecución, por lo que debería emplearse enlazado dinámico.&lt;br /&gt;
Cualquiera que sea el mecanismo para referenciar al objeto que invoca a la función (operador de acceso directo -1- o indirecto -2-):&lt;br /&gt;
obj.fun1()      // -1-&lt;br /&gt;
ptr-&amp;gt;fun1()     // -2-&lt;br /&gt;
La función conoce cuál es el objeto que la invoca -que juego de variables debe utilizar- a través del argumento implícito this.&lt;br /&gt;
== Invocación en jerarquías de clases ==&lt;br /&gt;
Sea B es una clase base, y otra D derivada públicamente de B. Cada una contiene una función virtual vf, entonces si vf es invocada por un objeto de D, la llamada que se realiza es D::vf(), incluso cuando el acceso se realiza vía un puntero o referencia a la superclase B. Ejemplo:&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class C {               // Clase-base&lt;br /&gt;
  public: virtual int get() {return 10;}&lt;br /&gt;
};&lt;br /&gt;
class D : public C {    // Derivada&lt;br /&gt;
  public: virtual int get() {return 100;}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {        // =========&lt;br /&gt;
  D d;&lt;br /&gt;
  C* cptr = &amp;amp;d;&lt;br /&gt;
  C&amp;amp; cref = d;&lt;br /&gt;
  cout &amp;lt;&amp;lt; d.get()     &amp;lt;&amp;lt; endl;&lt;br /&gt;
  cout &amp;lt;&amp;lt; cptr-&amp;gt;get() &amp;lt;&amp;lt; endl;&lt;br /&gt;
  cout &amp;lt;&amp;lt; cref.get()  &amp;lt;&amp;lt; endl;&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
100&lt;br /&gt;
100&lt;br /&gt;
100&lt;br /&gt;
&lt;br /&gt;
==  Tabla de funciones virtuales ==&lt;br /&gt;
Las funciones virtuales pagan un tributo por su versatilidad. Cada objeto de la clase derivada tiene que incluir un puntero (vfptr) a una tabla de direcciones de funciones virtuales, conocida como vtable. La utilización de dicho puntero permite seleccionar desde el objeto, la función correspondiente en tiempo de ejecución. Como resultado, el mecanismo de invocación de estas funciones  es mucho menos eficiente que el de los métodos normales (enlazado estático), por lo que debe reservarse su utilización a los casos estrictamente necesarios.&lt;br /&gt;
Es fácil poner en evidencia la existencia del puntero vfptr mediante un sencillo experimento que utiliza el operador sizeof&lt;br /&gt;
struct S1 {&lt;br /&gt;
  int n;&lt;br /&gt;
  double get() { return n; } // método auxiliar normal&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct S2 {&lt;br /&gt;
  int n;&lt;br /&gt;
  virtual double get() { return n; } // método virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
size_t tamS1 = sizeof(S1);  // -&amp;gt; 4&lt;br /&gt;
size_t tamS2 = sizeof(S2);  // -&amp;gt; 8&lt;br /&gt;
Comentario&lt;br /&gt;
El resultado del tamaño de ambos tipos es respectivamente 4 y 8 en cualquiera de los compiladores comprobados: Borland C++ 5.5 y gcc-g++ 3.4.2-20040916-1 para Windows. La diferencia de 4 Bytes obtenida corresponde precisamente a la presencia del mencionado puntero oculto.&lt;br /&gt;
== Función virtual pura ==&lt;br /&gt;
En ocasiones se lleva al extremo el concepto &amp;quot;virtual&amp;quot; en la declaración de una súper clase (&amp;quot;esta función será redefinida más tarde en las clases derivadas&amp;quot;), por lo que en ella solo existe una declaración de la función, relegándose las distintas definiciones a las clases derivadas. Entonces se dice que esta función es virtual pura. Esta circunstancia hay que advertirla al compilador; es una forma de decirle que la falta de definición no es un olvido por nuestra parte (de lo contrario el compilador nos señala que se nos ha olvidado la definición); esto se hace igualando a cero la declaración de la función:&lt;br /&gt;
virtual int funct1(void);      // Declara función virtual&lt;br /&gt;
virtual int funct2(void) = 0;  // Declara función virtual pura&lt;br /&gt;
&lt;br /&gt;
La existencia de una función virtual basta para que la clase que estamos definiendo sea polimórfica. Si además igualamos la función a cero, la estaremos declarando como función virtual pura, lo que automáticamente declara la clase como abstracta &lt;br /&gt;
Es muy frecuente que las funciones virtuales puras se declaren además con el calificador const , de forma que es usual encontrar expresiones del tipo:&lt;br /&gt;
virtual int funct2(void) const = 0;  // Declara función virtual pura y constante&lt;br /&gt;
==  Ejemplo ==&lt;br /&gt;
El ejemplo que sigue es una modificación del anterior , en el que declaramos la función fun de la clase-base B como virtual pura, con lo que podemos omitir su definición.&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {              // L.4:  Clase-base&lt;br /&gt;
  public:  virtual int fun(int x) = 0;       // L.5 virtual pura&lt;br /&gt;
};&lt;br /&gt;
class D1 : public B {  // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 10;}  // L.8 virtual&lt;br /&gt;
};&lt;br /&gt;
class D2 : public B {  // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 15;}  // L.11 virtual&lt;br /&gt;
};&lt;br /&gt;
int main(void) {       // =========&lt;br /&gt;
  D1 d1; D2 d2;        // M.1&lt;br /&gt;
&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.fun(10)    &amp;lt;&amp;lt; endl;  // M.3:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.fun(10)    &amp;lt;&amp;lt; endl;  // M.4:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
Comentario&lt;br /&gt;
El resto del programa se mantiene prácticamente igual al modelo anterior, con la salvedad de que ahora en M1 no podemos instanciar un objeto directamente de la superclase B; la razón es que la superclase está incompleta (falta la definición de fun). Si lo intentáramos, el compilador nos mostraría un error señalando que no se puede instanciar un objeto de la clase B y que dicha clase es abstracta; además las clases abstractas no son instanciables por definición.&lt;br /&gt;
En lo que respecta a las salidas, comprobamos que son los valores esperados.&lt;br /&gt;
&lt;br /&gt;
Una declaración de función no puede ser al mismo tiempo una definición y una declaración de virtual pura. Ejemplo:&lt;br /&gt;
struct Est {&lt;br /&gt;
    virtual void f() { /* ... */ } = 0;    // Error!!&lt;br /&gt;
};&lt;br /&gt;
La forma legal de proporcionar una definición es:&lt;br /&gt;
struct Est {&lt;br /&gt;
  virtual void f(void) = 0;    // declara f virtual pura&lt;br /&gt;
};&lt;br /&gt;
virtual void Est::f(void) {    // definición posterior de f&lt;br /&gt;
   /* código de la función f  */&lt;br /&gt;
};&lt;br /&gt;
== Un mundo de excepciones ==&lt;br /&gt;
Seguramente el lector que haya llegado hasta aquí experimente una cierta perplejidad (que comparto). En el párrafo §7  decimos que se utiliza el recurso de declarar una función virtual pura para poder omitir la definición, y a continuación, en el párrafo §7.2 exponemos la forma legal de proporcionarla...  El lector puede comprobar que esta aparente contradicción es asumida por el compilador sin protestas. En efecto, considere el ejemplo siguiente en el que modificamos el anterior añadiendo una definición a la función virtual pura fun.&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
class B {               // L.4:  Clase-base&lt;br /&gt;
  public:  virtual int fun(int x) = 0;       // L.5 virtual pura&lt;br /&gt;
};&lt;br /&gt;
int B::fun(int x) {return x * x}             // L.7 definición de fun&lt;br /&gt;
&lt;br /&gt;
class D1 : public B {   // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 10;}  // L.9 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class D2 : public B {   // Clase derivada&lt;br /&gt;
  public:  int fun (int x) {return x + 15;}  // L.12 virtual&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main(void) {        // =========&lt;br /&gt;
  D1 d1; D2 d2;         // M.1&lt;br /&gt;
&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.fun(10)    &amp;lt;&amp;lt; endl;  // M.3:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.fun(10)    &amp;lt;&amp;lt; endl;  // M.4:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d1.B::fun(10) &amp;lt;&amp;lt; endl;  // M.5:&lt;br /&gt;
  cout &amp;lt;&amp;lt; &amp;quot;El valor es: &amp;quot; &amp;lt;&amp;lt; d2.B::fun(10) &amp;lt;&amp;lt; endl;  // M.6:&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
Salida:&lt;br /&gt;
El valor es: 20&lt;br /&gt;
El valor es: 25&lt;br /&gt;
El valor es: 100&lt;br /&gt;
El valor es: 100&lt;br /&gt;
== Tipos devueltos por las funciones virtuales ==&lt;br /&gt;
Cuando se redefine una función virtual no se puede cambiarse el tipo de valor devuelto. Para redefinir una función virtual en alguna clase derivada, la nueva función debe coincidir exactamente en número y tipo con los parámetros de la declaración inicial (la &amp;quot;firma&amp;quot; -Signature- de ambas funciones deben ser iguales). Si no coinciden en esto, el compilador C++ considera que se trata de funciones diferentes (un caso de sobrecarga) y se ignora el mecanismo de funciones virtuales.&lt;br /&gt;
Para prevenir que puedan producirse errores inadvertidos, el compilador C++ GNU dispone de la opción  -Woverloaded-virtual, que produce un mensaje de aviso, si se redefine un método declarado previamente virtual en una clase antecesora, y no se cumple la condición de igualdad de firmas.&lt;br /&gt;
No obstante lo anterior, hay casos en que las funciones virtuales redefinidas en clases derivadas devuelven un tipo diferente del de la función virtual de la clase base. Esto es posible solo cuando se dan simultáneamente las dos condiciones siguientes:&lt;br /&gt;
•	La función virtual sobrecontrolada devuelve un puntero o referencia a clase base.&lt;br /&gt;
•	La nueva versión devuelve un puntero o referencia a la clase derivada.&lt;br /&gt;
=== Ejemplo ===&lt;br /&gt;
struct X {};            // clase base.&lt;br /&gt;
struct Y : X {};        // clase derivada (:public X por defecto).&lt;br /&gt;
struct B {              // clase base.&lt;br /&gt;
   virtual void vf1();  // L.4:&lt;br /&gt;
   virtual void vf2();&lt;br /&gt;
   virtual void vf3();&lt;br /&gt;
   void f();&lt;br /&gt;
   virtual X* pf();     /* L.8:  devuelve puntero a clase base,&lt;br /&gt;
                            esta función virtual puede ser sobrecontrolada */&lt;br /&gt;
};&lt;br /&gt;
class D : public B {    // clase derivada&lt;br /&gt;
   public:&lt;br /&gt;
   virtual void vf1();  // L.12: Especificador virtual, legal pero redundante&lt;br /&gt;
   void vf2(int);       /* L.13: No virtual, oculta B::vf2()&lt;br /&gt;
                            dado que usa otros argumentos */&lt;br /&gt;
// char vf3();          // L.14: Ilegal! cambia solo el tipo devuelto!&lt;br /&gt;
   void f();            // L.15: privativa de D (no virtual)&lt;br /&gt;
   Y*   pf();           /* L.16: función sobrecontrolante; difiere solo&lt;br /&gt;
                          en el tipo devuelto. Devuelve puntero a subclase */&lt;br /&gt;
};&lt;br /&gt;
void extf() {&lt;br /&gt;
   D d;                 // d objeto de la clase D (instancia)&lt;br /&gt;
   B* bp = &amp;amp;d;          /* L.20: Conversión estándar D* a B*&lt;br /&gt;
                  Inicializa bp con la tabla de funciones del objeto d.&lt;br /&gt;
                  Si no existe entrada para una función en dicha tabla,&lt;br /&gt;
                  utiliza la función de la tabla de la clase B */&lt;br /&gt;
   bp–&amp;gt;vf1();           // invoca D::vf1&lt;br /&gt;
   bp–&amp;gt;vf2();           // invoca B::vf2 (D::vf2 tiene diferentes argumentos)&lt;br /&gt;
   bp–&amp;gt;f();             // invoca B::f (not virtual)&lt;br /&gt;
   X* xptr = bp–&amp;gt;pf();  /* invoca D::pf() y convierte el resultado&lt;br /&gt;
                            en un puntero a X */&lt;br /&gt;
   D* dptr = &amp;amp;d;&lt;br /&gt;
   Y* yptr = dptr–&amp;gt;pf(); /* inicializa yptr; este puntero invocará a D::pf()&lt;br /&gt;
                            No se realiza ninguna conversión */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
L.12:  La versión D::vf1 es virtual automáticamente, dado que devuelve lo mismo y tiene los mismos parámetros que su homónima en la superclase B. El especificador virtual puede ser utilizado en estos casos pero no es estrictamente necesario a no ser que se vayan a derivar nuevas subclases de la clase derivada.&lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
== Puede Contactar  ==&lt;br /&gt;
*[[Declaración de funciones|Declaración de funciones]] &lt;br /&gt;
*[[Sobrecarga de funciones (programación)|Sobrecarga de funciones (programación)]]&lt;br /&gt;
*[[Parámetros y argumentos (programación)|Parámetros y argumentos (programación)]]&lt;br /&gt;
*[[Invocación de funciones (programación)|Invocación de funciones (programación)]]&lt;br /&gt;
*[[Enumeraciones (Informática)|Enumeraciones (Informática)]] &lt;br /&gt;
*[[Sobrecarga de enumeraciones (Informática)|Sobrecarga de enumeraciones (Informática)]] &lt;br /&gt;
*[[Referencias (programación)|Referencias (programación)]]&lt;br /&gt;
== Fuentes  ==&lt;br /&gt;
* [http://www.zator.com/Cpp/E4_4.htm Funciones]&lt;br /&gt;
* [http://www.fismat.umich.mx/mn1/manual/node7.html Funciones en C ++]&lt;br /&gt;
*     [http://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Funciones#Definiendo_una_funci.C3.B3n    Programación en C++/Funciones]&lt;br /&gt;
*    [http://c.conclase.net/curso/?cap=020#inicio Funciones]&lt;br /&gt;
[[Category:Informática]] [[Category:Lenguajes_de_programación]] [[Category:Programación]]&lt;/div&gt;</summary>
		<author><name>Majibacoa2 jc</name></author>
		
	</entry>
</feed>