Es más sutil que las otras respuestas sugieren. No existe una división absoluta entre los datos en la pila y los datos en el montón basados en cómo lo declaras. Por ejemplo:
std::vector<int> v(10);
En el cuerpo de una función, que declara un (array dinámico) vector
de diez números enteros en la pila. Pero el almacenamiento administrado por vector
no está en la pila.
Ah, pero (las otras respuestas sugieren) la vida útil de ese almacenamiento está limitada por la duración del vector
, que aquí está basado en la pila, por lo que no importa cómo se implemente, solo podemos tratarlo como un objeto basado en pila con semántica de valores.
No es así. Supongamos que la función era:
void GetSomeNumbers(std::vector<int> &result)
{
std::vector<int> v(10);
// fill v with numbers
result.swap(v);
}
Así que cualquier cosa con una función swap
(y cualquier tipo de valor complejo debe tener uno) puede servir como una especie de referencia rebindable a algunos datos del montón, bajo un sistema que garantiza un único propietario del esa información
Por lo tanto, el enfoque moderno de C++ es nunca almacena la dirección de los datos del montón en variables de puntero local desnudas. Todas las asignaciones de montón deben estar ocultas dentro de las clases.
Si hace eso, puede pensar en todas las variables de su programa como si fueran simples tipos de valor, y olvidarse completamente del montón (excepto cuando escribe una nueva clase contenedora de valor para algunos datos de montón, que deberían ser inusual).
Usted sólo tiene que mantener un bit especial de conocimiento para ayudarle a optimizar: siempre que sea posible, en lugar de asignar una variable a otra así:
a = b;
ellas se comparten la siguiente manera:
a.swap(b);
porque es mucho más rápido y no arroja excepciones. El único requisito es que no necesita b
para continuar manteniendo el mismo valor (en su lugar obtendrá el valor a
, que se descartará en a = b
).
La desventaja es que este enfoque obliga a devolver valores de funciones a través de parámetros de salida en lugar del valor de retorno real. Pero lo están arreglando en C++ 0x con rvalue references.
En las situaciones más complicadas de todas, llevaría esta idea al extremo general y usaría una clase de puntero inteligente como shared_ptr
que ya está en tr1. (Aunque yo argumentaría que si pareces necesitarlo, posiblemente te hayas movido fuera del punto óptimo de aplicabilidad de Standard C++.)
posible duplicado de [¿Cuándo es mejor usar la pila en lugar del montón y viceversa?] (Http://stackoverflow.com/questions/102009/when-is-it-best-to-use -the-stack-instead-of-the-heap-and-vice-versa) –