Это более тонкий, чем другие рекомендации. Абсолютного разрыва между данными в стеке и данными в куче нет, основываясь на том, как вы его объявляете. Например:
std::vector<int> v(10);
В теле функции, которая объявляет vector
(динамический массив) из десяти целых чисел в стеке. Но хранилище, управляемое vector
, не находится в стеке.
А, но (как утверждают другие источники) время жизни этого хранилища ограничено временем жизни самого vector
, которое здесь основано на стеках, поэтому не имеет значения, как оно реализовано - мы можем рассматривать его только как объект на основе стека с семантикой значений.
Не так. Пусть функция была:
void GetSomeNumbers(std::vector<int> &result)
{
std::vector<int> v(10);
// fill v with numbers
result.swap(v);
}
Так что ничего с swap
функции (и любого сложного типа значения должны иметь один) может служить своего рода rebindable ссылкой на некоторые данные кучи, в рамках системы, которая гарантирует единый владелец это данные.
Поэтому современный подход на С ++ относится к никогда. сохраняет адрес данных кучи в голых переменных локального указателя. Все распределения кучи должны быть скрыты внутри классов.
Если вы это сделаете, вы можете думать обо всех переменных в своей программе, как если бы они были простыми типами значений, и вообще забыть о куче (кроме того, когда вы пишете новый класс-класс-оболочку для некоторых данных кучи, что должно быть необычным).
Вы просто должны сохранить один специальный бит знаний, чтобы помочь вам оптимизировать: где это возможно, вместо того, чтобы назначить одну переменную в другую, как это:
a = b;
поменять их местами, как это:
a.swap(b);
, потому что это намного быстрее, и это не бросает исключений. Единственное требование - вам не нужно b
, чтобы продолжить удерживать ту же величину (вместо этого получится значение a
, которое будет разбито в a = b
).
Недостатком является то, что этот подход заставляет вас возвращать значения из функций через выходные параметры вместо фактического возвращаемого значения. Но они фиксируют это в C++ 0x с rvalue references.
В самых сложных ситуациях вы должны использовать эту идею в целом и использовать класс интеллектуальных указателей, такой как shared_ptr
, который уже находится в tr1. (Хотя я бы утверждал, что, если вам это кажется, вы, возможно, перешли на сладость сорта Standard C++ применимости.)
Возможный дубликат [Когда лучше использовать стек вместо кучи и наоборот?] (Http://stackoverflow.com/questions/102009/when-is-it-best-to-use -the-stack-вместо-heap-and-vice-versa) –