void fun()
{
A *a = new A; //Here A is a class
} //a should be deleted in fun()'s scope
int main()
{
fun();
return 0;
}
Созданный объект существует в бесплатном хранилище и не может использоваться функцией main (). Почему объекты должны быть созданы в бесплатном магазине. Да, мы можем передать ссылку на объект в основную функцию, но мы можем даже передать копию объекта (даже если она не создана с помощью оператора new). Тогда каково точное использование оператора new и delete?
В вашем примере их нет, и не стоит
использовать динамическое распределение. Динамическое распределение используется, когда объекты
иметь идентичность (или не может быть скопирована по какой-либо другой причине), и
время жизни объекта не соответствуют некоторым
заданный срок службы, например, статический или автоматический. динамический
распределение может также использоваться в нескольких случаях, когда копирование
дорого, и профилировщик показывает, что копирование
узкое место; в таких случаях, используя динамическое распределение и
Копирование указателя может устранить узкое место. (Но это должно
никогда не делайте, пока профилирование не покажет это необходимым.)
Краткий ответ: выделить память во время выполнения.
Для получения дополнительной информации рассмотрите: http://www.cplusplus.com/doc/tutorial/dynamic/
Хороший вопрос. Обычно это не нужно — явно. Конечно, есть другой ответ, говорящий «выделить память во время выполнения» и аналогичный комментарий. Но вы можете достичь того же с std::vector<>
, std::string
и т.д. Они сделают все эти воспоминания за сценой для вас, в нужные моменты.
Это одна из причин new/delete
— полезно реализовать некоторые классы.
Вы упоминаете, что копии объектов могут быть переданы. Это может быть немного дороже, поэтому в целях оптимизации может оказаться целесообразным заменить самые дорогие копии на new/delete
, Существуют инструменты, называемые «профилировщики», которые можно использовать для определения того, какие копии стоят дорого.
Третья причина — полиморфизм. Вы можете иметь код, похожий на Base* ptr = (foo>7) ? new Derived1 : new Derived2(foo);
где вы не знаете заранее, какой объект вам понадобится, как он должен себя вести. Поскольку размер Derived1
а также Derived2
как правило, не связаны, вы только знаете во время выполнения, сколько памяти вам нужно.
Важная причина в том, как стек работает. Он имеет только push и pop операции. Вы не можете выпустить что-либо в стеке, пока не отпустили все, что вытолкнулось после него. Или, другими словами, если что-то освобождается из стека, например, кадр стека вызова функции при возврате функции, то и вся память над ней в стеке также будет освобождена (и вам лучше убедиться, что она уничтожена должным образом, см. Ниже). ).
Программы обычно должны хранить данные независимо от стека. Есть два способа: выделить память во время компиляции, как статические данные, или выделить его в бесплатный магазин, также называемый кучей.
Конечно, было бы возможно иметь несколько стеков, и на самом деле это обычно делается тоже, когда это удобно и полезно. Но это делается с помощью переменной контейнера стека с таким типом, как std::stack
, затем использовать это как дополнительный стек только для данных. Обычные архитектуры процессоров имеют только один «родной» стек для каждого процесса / потока, который используется для вызовов функций и переменных стека. Эти дополнительные стеки всегда разделены и создаются программным кодом, просто простые структуры данных, такие же как списки, карты и т. Д.
Что касается кода в вашем вопросе, то стоит отметить, что в современном C ++ это голый new
как правило, осуждают. Вы должны использовать механизм RAII, такой как умный указатель:
void fun()
{
auto a = std::unique_ptr<A>{ new A }; // C++11 syntax
// object is automatically destroyed when a goes out of scope, no leak
// note: heap should be used like this only if there's a reason, including:
// - A is big, and might conceivably overflow the stack
// - ownership of object may get moved and outlive the unique_ptr
}
И твой конкретный вопросСозданный объект существует в бесплатном хранилище и не может использоваться функцией main (). Почему объекты должны быть созданы в бесплатном магазине.«, ну, в коде вопроса, он не должен создаваться в бесплатном хранилище, нет причин. Это должна быть просто автоматическая переменная, которая автоматически уничтожается, когда выходит из области видимости.