Ответ 1
Да, автоматические переменные будут уничтожены в конце закрывающего кодового блока. Но продолжайте читать.
В заголовке вопроса спрашивается, будет ли вызван деструктор, когда переменная выходит за пределы области видимости. Предположительно, что вы хотели спросить:
будет вызываться Foo destructor в конце main()?
Учитывая предоставленный вами код, ответ на этот вопрос нет, поскольку объект Foo имеет динамическую продолжительность хранения, как мы вскоре увидим.
Обратите внимание, что такое автоматическая переменная:
Foo* leedle = new Foo();
Здесь leedle
- это автоматическая переменная, которая будет уничтожена. leedle
- это просто указатель. То, что указывает leedle
, не имеет автоматической продолжительности хранения и не будет уничтожено. Итак, если вы это сделаете:
void DoIt()
{
Foo* leedle = new leedle;
}
Вы просачиваете память, выделенную new leedle
.
Вы должны delete
все, что было выделено с помощью new
:
void DoIt()
{
Foo* leedle = new leedle;
delete leedle;
}
Это делается намного проще и надежнее, используя интеллектуальные указатели. В С++ 03:
void DoIt()
{
std::auto_ptr <Foo> leedle (new Foo);
}
Или в С++ 11:
void DoIt()
{
std::unique_ptr <Foo> leedle = std::make_unique <Foo> ();
}
Умные указатели используются как автоматические переменные, как указано выше, и когда они выходят из области действия и уничтожаются, они автоматически (в деструкторе) delete
указывают на объект. Поэтому в обоих случаях выше утечка памяти отсутствует.
Попробуйте прояснить здесь немного языка. В С++ переменные имеют продолжительность хранения. В С++ 03 существует 3 периода хранения:
1: автоматический: переменная с автоматической продолжительностью хранения будет уничтожена в конце защищающего блока кода.
Рассмотрим:
void Foo()
{
bool b = true;
{
int n = 42;
} // LINE 1
double d = 3.14;
} // LINE 2
В этом примере все переменные имеют автоматическую продолжительность хранения. Оба b
и d
будут уничтожены в LINE 2. n
будет уничтожен в LINE 1.
2: static: переменная со статической продолжительностью хранения будет выделена до начала программы и уничтожена, когда программа закончится.
3: динамический: переменная с динамической продолжительностью хранения будет выделена при ее распределении с использованием функций распределения динамической памяти (например, new
) и будет уничтожена при ее уничтожении с использованием динамической памяти функции распределения (например, delete
).
В моем первоначальном примере выше:
void DoIt()
{
Foo* leedle = new leedle;
}
leedle
- переменная с автоматическим временем хранения и будет уничтожена в концевой скобке. То, что указывает leedle
, имеет динамическую продолжительность хранения и не разрушается в коде выше. Вы должны вызвать delete
, чтобы освободить его.
С++ 11 также добавляет четвертую продолжительность хранения:
4: thread: переменные с продолжительностью хранения потока выделяются, когда поток начинается и освобождается при завершении потока.