Модифицированная вами программа:
#include <iostream>
using namespace std;
class Foo {
public:
Foo () { c = 'a'; cout << "Foo()" << endl; }
Foo (char ch) { c = ch; cout << "Foo(char)" << ch << endl; }
~Foo () { cout << "~Foo()"<< c << endl; }
protected:
char c;
};
class Bar : public Foo {
public:
Bar () { cout << "Bar()" << endl; }
Bar (char ch) : Foo(ch) { cout << "Bar(char)" << ch << endl; }
~Bar () { cout << "~Bar()" << c << endl; }
};
Foo f1('a'); static Bar b1('b');
int main()
{
Bar b2('c');
{
static Foo f2('d');
Foo f3('e');
Bar b3 ('f');
}
return 0;
}
, который генерирует следующий вывод в g ++ 4.5.2:
Foo(char)a
Foo(char)b
Bar(char)b
Foo(char)c
Bar(char)c
Foo(char)d
Foo(char)e
Foo(char)f
Bar(char)f
~Bar()f
~Foo()f
~Foo()e
~Bar()c
~Foo()c
~Foo()d
~Bar()b
~Foo()b
~Foo()a
Вы видите, что последней разрушенной является нестатическая глобальная переменная Foo f1
.
EDIT:
Как уже упоминалось, порядок инициализации переменных со статической продолжительностью хранения является неопределенным, если переменные относятся к разным единицам перевода, но их можно определить, если они находятся в одной единице перевода.
Инициализация вызовами конструктора (как в этих примерах) называется dynamic initialization
и
Динамическая инициализация нелокальной переменной со статическим хранилищем
длительность либо упорядочена, либо неупорядочена . Определения явно
члены статического класса шаблона специализированных классов заказали
инициализация. Другие члены статических данных шаблона класса (т.е.
неявно или явно созданные специализации) имеют неупорядоченные
инициализация. Другие нелокальные переменные со статической продолжительностью хранения
заказал инициализацию. Переменные с упорядоченной инициализацией
определенный в пределах одной единицы перевода, инициализируется в
порядок их определения в переводческой единице.
Это определяется реализацией, является ли динамическая инициализация
нелокальная переменная со статической продолжительностью хранения выполняется до
первое изложение основного. Если инициализация откладывается до некоторого
момент времени после первого изложения основного, это должно произойти до
первое использование odr (3.2) любой функции или переменной, определенной в
та же единица перевода, что и для инициализируемой переменной.
Инициализация локальных статических переменных указывается как
... такая переменная
инициализируется при первом прохождении контроля через его объявление; ...
А поскольку уничтожение переменных со статической продолжительностью хранения должно осуществляться в порядке, обратном их построению, то порядок построения и уничтожения переменных с типами Foo
и Bar
в этом примере фактически определен.
Опять же, когда у вас есть несколько переводов, вам лучше не полагаться на порядок инициализации.