class A
{
public:
A(const char *sz)
{
printf("%s ", sz);
}
~A()
{
printf("~A ");
}
};
class B
{
public:
B(const char *sz)
{
printf("%s ", sz);
}
~B()
{
printf("~B ");
}
};
class C
{
public:
C(const char *sz)
{
printf("%s ", sz);
}
~C()
{
printf("~C ");
}
};
class App
{
public:
App() :
a("A"), b("B"),
c("C") {printf("App");}
private:
C c;
B b;
A a;
};
int main()
{
{
App
m;
printf("\n");
}
printf("\n");
}
C B A App
~A ~B ~C
Nie wierzycie? Sprawdźcie sami. Co zatem z tego wynika? Elementy na liście inicjalizacyjnej konstruktora inicjowane są przed wywołaniem samego konstruktora (co jest dość oczywiste). Dodatkowo kolejność inicjalizacji jest zgodna z kolejnością deklaracji pól w klasie. Destrukcja zaś odbywa się od ostatniego pola.
Generalnie żeby nie robić zamieszania należy inicjować elementy na liście w kolejności ich występowania w deklaracji klasy. AFAIR gcc pluje w warningach o tym, że kolejność jest zła.
OdpowiedzUsuńMyślę, że warto by dodać, że nie jest to zachowanie zależne od kompilatora, tylko wymagane przez standard.
OdpowiedzUsuń12.6.2.10:
Then, non-static data members are initialized in the order they were declared in the class definition
(again regardless of the order of the mem-initializers).
I przy okazji, imho łatwiej zapamiętać, że destrukcja obiektów ma tylko jedną zasadę: odwrotnie do kierunku inicjalizacji.