Kiedy inicjowane są statyczne Członkowie klasy C++?
Wydaje się, że nie ma łatwej odpowiedzi na to pytanie, ale czy są jakieś założenia, które można bezpiecznie sformułować, kiedy statyczne pole klasy może być dostępne?
EDIT: jedynym bezpiecznym założeniem wydaje się być to, że wszystkie statyki są inicjowane przed uruchomieniem programu (wywołanie do main
). Tak więc, dopóki nie odwołuję się do statyki z innego statycznego kodu inicjującego, nie powinienem mieć się o co martwić?
7 answers
Standard gwarantuje dwie rzeczy - że obiekty zdefiniowane w tej samej jednostce tłumaczeniowej (zwykle oznacza .plik cpp) są inicjalizowane w kolejności ich definicji ( nie deklaracje):
3.6.2
Przechowywanie obiektów o statycznym czasie przechowywania (basic.stc.statyczna) jest zerowa (dcl.init) przed jakąkolwiek inną inicjalizacją. Zero-inicjalizacja i inicjalizacja z wyrażeniem stałym są zbiorczo nazywane statycznymi inicjalizacja; wszystkie inne inicjalizacje są inicjalizacją dynamiczną. Obiekty typu POD (basic.typy) ze statycznym czasem przechowywania zainicjalizowanym wyrażeniami stałymi (expr.const) należy zainicjować przed jakąkolwiek dynamiczną inicjalizacją. Obiekty o statycznym czasie przechowywania zdefiniowanym w przestrzeni nazw w tej samej jednostce tłumaczenia i dynamicznie inicjalizowanym są inicjalizowane w kolejności, w jakiej ich definicja pojawia się w jednostce tłumaczenia.
The other gwarantowane jest to, że inicjalizacja obiektów statycznych z jednostki tłumaczeniowej zostanie wykonana przed użyciem dowolnego obiektu lub funkcji z tej jednostki tłumaczeniowej:
Jest definiowane przez implementację, czy dynamiczna inicjalizacja (dcl.init, Klasa.statyczne, Klasa.ctor, Klasa.expl.INIT) obiektu przestrzeni nazw scope jest wykonywane przed pierwszą instrukcją main. Jeśli inicjalizacja zostanie odroczona do pewnego punktu w czasie po pierwszej instrukcji main, nastąpi to przed pierwsze użycie dowolnej funkcji lub obiektu zdefiniowanego w tej samej jednostce tłumaczeniowej co inicjowany obiekt.
Nic innego nie gwarantowałem (szczególnie kolejność inicjalizacji obiektów zdefiniowanych w różnych jednostkach translacyjnych jest zdefiniowana implementacja).
edytuj
Jak zaznaczono w komentarzu Sumy, gwarantuje się również, że zostaną one zainicjowane przed wpisaniem main
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-07 09:17:28
Są inicjowane przed uruchomieniem programu (tj. przed wprowadzeniem main
).
Gdy w pojedynczym pliku CPP znajdują się dwie lub więcej definicji (danych statycznych), są one inicjalizowane w kolejności, w jakiej są zdefiniowane w pliku (Ta zdefiniowana wcześniej/wyższa w pliku jest inicjowana przed następną).
Jeśli istnieją dwie lub więcej definicji (danych statycznych) w więcej niż jednym pliku CPP, Sekwencja, w której przetwarzane są pliki CPP jest undefined/implementation-specific. Problem polega na tym, że konstruktor zmiennej globalnej (wywołanej przed uruchomieniem programu) odwołuje się do innej zmiennej globalnej zdefiniowanej w innym pliku CPP, która mogła jeszcze nie zostać skonstruowana. Jednak pozycja 47 efektywnego C++ (który nosi tytuł zapewnia, że obiekty globalne są inicjalizowane przed ich użyciem ) opisuje obejście ...
-
Definiowanie zmiennej statycznej w pliku nagłówkowym (jest to statyczna możesz więc mieć wiele jego instancji bez narzekania linkera)
-
Niech konstruktor tej zmiennej wywoła wszystko, czego potrzebujesz (w szczególności, zbuduj globalne singletony zadeklarowane w nagłówkach)
... jest to technika, która może być użyta w niektórych plikach nagłówkowych systemu, np. w celu zapewnienia, że zmienna globalna cin
jest zainicjalizowana, zanim nawet konstruktory zmiennych statycznych jej użyją.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-14 14:21:35
Twój ostateczny wniosek w edycji jest poprawny. Ale problem polega na tym, że klasa sama w sobie jest statyczna. Łatwiej jest powiedzieć, że mój kod będzie miał członków klasy static, które nie odnoszą się do innych globalnych danych/ członków klasy static, ale gdy wybierzesz tę trasę, wkrótce wszystko pójdzie nie tak. Jedno podejście, które uznałem za przydatne w praktyce, aby nie mieć klasy static data members, ale klasy static wrapper methods. Metody te mogą następnie trzymać statyczny obiekt w sobie. Na np.
TypeX* Class2::getClass1Instance()
{
static TypeX obj1;
return &obj1;
}
Uwaga: wcześniejsza odpowiedź mówi:
Inną gwarantowaną rzeczą jest to, że inicjalizacja obiektów statycznych z jednostki tłumaczeniowej zostanie wykonana przed użyciem jakiegokolwiek obiektu lub function from this translation unit
Nie jest to całkowicie poprawne i norma jest błędnie wnioskowana tutaj. Może to nie być prawdziwe, jeśli funkcja z jednostki tłumaczeniowej zostanie wywołana przed wprowadzeniem main.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-22 09:57:31
Wierzę, że można uzyskać do niego dostęp w każdej chwili podczas egzekucji. To, co pozostaje nieokreślone, to kolejność inicjalizacji zmiennych statycznych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-14 13:57:29
Mogą być inicjowane w pliku implementacji (.C/cpp / CC) plików. Nie inicjuj ich .H jako kompilator będzie narzekał na wiele definicji.
Są zazwyczaj inicjowane przed main, jednak kolejność jest uknown, dlatego należy unikać zależności. Z pewnością mogą być dostępne w ramach funkcji członka. Należy pamiętać, że kolejność inicjalizacji nie jest znana dla statycznych członków. Proponuję zamknąć statyczny element w funkcji statycznej, która sprawdzi, czy element ma zainicjowany.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-14 13:58:17
Nie ma całkowicie trywialnej odpowiedzi na to pytanie, ale zasadniczo są one inicjowane tuż przed przekazaniem kontroli do punktu wejścia (głównego) programu. Kolejność ich inicjalizacji jest (według mojej wiedzy) niezdefiniowana i może być specyficzna dla kompilatora.
EDIT: aby wyjaśnić, twoje dodane założenie jest poprawne. Tak długo, jak masz do niego dostęp tylko po wpisie głównym, tak naprawdę nie musisz się martwić o to, kiedy/jak zostanie zainicjowany. Zostanie zainicjowany do tego czasu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-14 14:14:03
Myślę, że główny wątek procesu wykona następujące pięć kroków w kolejności
-
Inicjalizacja biblioteki CRT
-
Inicjalizacja statyczna
-
Wykonanie funkcji main ()
-
Unitializacja statyczna
-
Unitializacja biblioteki CRT
Chcesz statyki odniesienia z innego statycznego kodu inicjalizacyjnego? może działają następujące Kody:
class A;
static auto_ptr<A> a(auto_ptr<A>(&GetStaticA()));
A &GetStaticA(void)
{
static A *a = NULL; //the static basic type variables initialized with constant experession will be initialized earlier than the other static ones
if (a == NULL)
{
a = new A();
return *a;
}
}