Co oznaczają następujące frazy w C ++:
inicjalizacja zerowa,
domyślna inicjalizacja oraz
inicjalizacja wartości
Co powinien wiedzieć o nich programista C ++?
Co oznaczają następujące frazy w C ++:
inicjalizacja zerowa,
domyślna inicjalizacja oraz
inicjalizacja wartości
Co powinien wiedzieć o nich programista C ++?
Odpowiedzi:
Należy zdać sobie sprawę z tego, że inicjalizacja wartości jest nowa w standardzie C ++ 2003 - nie istnieje w oryginalnym standardzie z 1998 roku (myślę, że może to być jedyna różnica, która jest czymś więcej niż wyjaśnieniem). Zobacz odpowiedź Kirilla V. Lyadvinsky'ego na definicje prosto ze standardu.
Zobacz poprzednią odpowiedź na temat zachowania, operator new
aby uzyskać szczegółowe informacje na temat różnych zachowań tego typu inicjowania i kiedy się uruchamiają (i kiedy różnią się od c ++ 98 do C ++ 03):
Głównym punktem odpowiedzi jest:
Czasami pamięć zwrócona przez nowego operatora zostanie zainicjowana, a czasem nie będzie zależeć od tego, czy nowy typ jest POD, czy też jest klasą zawierającą elementy POD i używa domyślnego konstruktora generowanego przez kompilator .
- W C ++ 1998 istnieją 2 rodzaje inicjalizacji: zero i domyślna
- W C ++ 2003 dodano trzeci typ inicjalizacji, inicjalizację wartości.
Mówiąc najprościej, jest to dość skomplikowane i kiedy różne metody są subtelne.
Należy z pewnością pamiętać, że MSVC przestrzega zasad C ++ 98, nawet w VS 2008 (VC 9 lub cl.exe wersja 15.x).
Poniższy fragment pokazuje, że MSVC i Digital Mars przestrzegają zasad C ++ 98, podczas gdy GCC 3.4.5 i Comeau przestrzegają zasad C ++ 03:
#include <cstdio>
#include <cstring>
#include <new>
struct A { int m; }; // POD
struct B { ~B(); int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m
int main()
{
char buf[sizeof(B)];
std::memset( buf, 0x5a, sizeof( buf));
// use placement new on the memset'ed buffer to make sure
// if we see a zero result it's due to an explicit
// value initialization
B* pB = new(buf) B(); //C++98 rules - pB->m is uninitialized
//C++03 rules - pB->m is set to 0
std::printf( "m is %d\n", pB->m);
return 0;
}
int
, ale m()
w trzecim wierszu wartość inicjuje m. Ważne, jeśli zmienisz int m;
na B m;
. :)
A
i C
nie są używane w tym przykładzie (zostały przeniesione z innej połączonej odpowiedzi). Mimo że C ++ 98 i C ++ 03 używają innej terminologii przy opisywaniu sposobu A
i C
budowy, wynik jest taki sam w obu standardach. struct B
Powoduje tylko inne zachowanie.
struct C { C() : m() {}; ~C(); B m; };
, to będziesz mieć m.m
0. Ale jeśli byłaby to inicjalizacja domyślna m
tak jak mówisz C ++ 03, to m.m
nie byłaby inicjowana jak w C ++ 98.
C ++ 03 Standard 8.5 / 5:
Do zera inicjalizacji przedmiot oznacza typ T:
- jeśli T typu skalarny (3,9), których celem jest ustawiana na wartość 0 (zerowy) w przeliczeniu na T;
- jeżeli T jest niekluczowym typem klasy, każdy niestatyczny element danych i każdy podklucz klasy podstawowej jest inicjowany na zero;
- jeśli T jest typem unii, pierwszy nazwany element danych obiektu jest inicjowany na zero;
- jeśli T jest typem tablicy, każdy element jest inicjowany zerem;
- jeżeli T jest typem odniesienia, inicjalizacja nie jest przeprowadzana.Do domyślnych zainicjować obiekt środków typ T:
- jeśli T jest non-POD typ zajęć (pkt 9), konstruktor domyślny dla T nazywa (i inicjalizacji jest źle sformułowane jeśli T ma dostępnego domyślnego konstruktora);
- jeśli T jest typem tablicy, każdy element jest inicjowany domyślnie;
- w przeciwnym razie obiekt jest inicjowany na zero.Do wartości inicjalizacji przedmiot oznacza typ T:
- jeśli T typu klasy (punkt 9) z konstruktora dla deklarowanej (12,1), a następnie konstruktor domyślną T nazywa (i inicjalizacji źle tworzy jeśli T nie ma dostępnego domyślnego konstruktora);
- jeżeli T jest niezwiązkowym typem klasy bez konstruktora zadeklarowanego przez użytkownika, to każdy niestatyczny element danych i składnik klasy podstawowej T jest inicjalizowany pod względem wartości;
- jeśli T jest typem tablicy, to każdy element jest inicjowany wartością;
- w przeciwnym razie obiekt jest inicjowany na zeroProgram, który wymaga inicjalizacji domyślnej lub inicjalizacji wartości encji typu odniesienia jest źle sformułowany. Jeśli T jest typem kwalifikowanym do cv, w tych definicjach zerowej inicjalizacji, domyślnej inicjalizacji i inicjalizacji wartości używana jest wersja T niekwalifikowana do CV.