C'est plus subtil que les autres réponses suggèrent. Il n'est pas absolue fossé entre les données sur la pile et les données sur le tas en fonction de comment vous le déclarer. Par exemple:
std::vector<int> v(10);
Dans le corps d'une fonction, qui déclare vector
(tableau dynamique) de dix entiers sur la pile. Mais l'espace de stockage gérés par l' vector
n'est pas sur la pile.
Ah, mais (les autres réponses suggèrent) de la durée de stockage est limitée par la durée de vie de l' vector
lui-même, qui, ici, est basée sur la pile, de sorte qu'il ne fait aucune différence comment il est mis en œuvre - nous ne pouvons la traiter comme une pile d'objets basé sur la valeur sémantique.
De ne pas faire. Supposons que la fonction est:
void GetSomeNumbers(std::vector<int> &result)
{
std::vector<int> v(10);
// fill v with numbers
result.swap(v);
}
Si quoi que ce soit avec un swap
de la fonction (et de tout complexe de type de valeur devrait en avoir un) peut servir comme une sorte de rebindable référence à un tas de données, dans un système qui garantit un seul propriétaire des données.
Donc le C++ moderne approche est de ne jamais stocker l'adresse de segment de données dans nu pointeur variables. Toutes les allocations de tas doivent être cachés à l'intérieur des classes.
Si vous faites cela, vous pouvez penser à toutes les variables de votre programme comme s'ils étaient de simples types de valeur, et oublier le tas tout (sauf lors de l'écriture d'une nouvelle valeur de type classe wrapper pour certains tas de données, ce qui devrait être rare).
Il vous suffit simplement de retenir les services d'un bit spécial de connaissances pour vous aider à optimiser: si possible, au lieu d'affecter une variable à une autre, comme ceci:
a = b;
swap comme ceci:
a.swap(b);
parce que c'est beaucoup plus rapide et il ne jette pas des exceptions. La seule exigence est que vous n'avez pas besoin d' b
de continuer à garder la même valeur (c'est pour obtenir a
par rapport au lieu, qui serait mis à la corbeille en a = b
).
L'inconvénient est que cette approche vous oblige à les valeurs de retour des fonctions via les paramètres de sortie au lieu de la valeur de retour. Mais ils sont de fixation que dans C++0x avec des références rvalue.
Dans les situations les plus complexes de tous, vous devez prendre cette idée au général extrême et l'utilisation d'un pointeur intelligent de la classe comme l' shared_ptr
ce qui est déjà dans tr1. (Bien que je dirais que si vous avez l'impression d'en avoir besoin, vous avez probablement déplacé à l'extérieur de la Norme C++'sweet spot de l'applicabilité.)