Snapshot s;// receives no initializationSnapshot s ={};// value initializes all members
Drugi spowoduje, że wszyscy członkowie będą zero, pierwszy pozostawi ich na nieokreślonych wartościach. Pamiętaj, że jest rekurencyjny:
structParent{Snapshot s;};Parent p;// receives no initializationParent p ={};// value initializes all members
Drugi spowoduje p.s.{x,y}zero. Nie możesz używać tych zagregowanych list inicjalizacyjnych, jeśli masz w swoim konstruktorze konstruktory. W takim przypadku konieczne będzie dodanie odpowiedniej inicjalizacji do tych konstruktorów
structSnapshot{int x;double y;Snapshot():x(0),y(0){}// other ctors / functions...};
Zainicjuje zarówno x, jak i y do 0. Zauważ, że możesz użyć x(), y()do zainicjowania ich bez względu na ich typ: To jest następnie inicjalizacja wartości i zwykle daje prawidłową wartość początkową (0 dla int, 0,0 dla podwójnego, wywoływanie domyślnego konstruktora dla zdefiniowanego przez użytkownika typy, które mają zadeklarowane przez użytkownika konstruktory, ...). Jest to ważne, zwłaszcza jeśli twój struct jest szablonem.
Roger: Spróbuj użyć nazwanej struktury w inicjalizatorze, to właśnie robię i nie otrzymuję żadnych ostrzeżeń w VC 2012: Snapshot s = Snapshot ();
Kit10
@Johannes Schaub - litb Czy będzie Snapshot s = {};działał dla członków spoza POD (do ich zerowania)?
ontherocks
2
C ++ 11 pozwala teraz na inicjalizację ich w definicji struktury lub klasy, na przykład: struct Snapshot {double x {0}; // z nawiasami klamrowymi y = 0; // lub po prostu oldschoolowy styl „przez przypisanie”, który tak naprawdę jest również inicjalizacją};
ikku100
1
Czy „Snapshot s = {};” część standardu?
Stefan
40
Nie, domyślnie nie są to 0. Najprostszym sposobem upewnienia się, że wszystkie wartości lub domyślnie 0 to zdefiniowanie konstruktora
Snapshot(): x(0), y(0){}
Zapewnia to, że wszystkie zastosowania migawki będą miały zainicjowane wartości.
Minusem jest to, że struct nie jest już typem POD, ponieważ ma konstruktor. Spowoduje to uszkodzenie niektórych operacji, takich jak zapisanie go do pliku tymczasowego.
finnw
16
@finnw: C ++ 11 naprawia to, chociaż struct nie jest POD, to jest „standardowy układ”.
Ben Voigt,
19
Ogólnie nie. Jednak struktura zadeklarowana jako zakres pliku lub statyczna w funkcji / will / zostanie zainicjowana na 0 (podobnie jak wszystkie inne zmienne tych zakresów):
int x;// 0int y =42;// 42struct{int a, b;} foo;// 0, 0void foo(){struct{int a, b;} bar;// undefinedstaticstruct{int c, d;} quux;// 0, 0}
To naprawdę nie jest bezpieczne założenie. nie powinieneś polegać na wartości niczego, czego nie zainicjowałeś
Hasturkun
24
Obiekty statycznego czasu przechowywania są zawsze inicjowane na zero - patrz cytat ze standardu na stackoverflow.com/questions/60653/ ... Czy to dobry styl, to inna sprawa.
bdonlan
12
Z POD możesz także pisać
Snapshot s ={};
Nie powinieneś używać memset w C ++, memset ma tę wadę, że jeśli w strukturze nie ma POD, to go zniszczy.
lub tak:
struct init
{template<typename T>operator T *(){returnnew T();}};Snapshot* s = init();
@Andy Most Vexing Parse przekształca rzeczy, które wyglądają jak normalne ctors - SomeType foo();jest typowy, choć może się zdarzyć z innymi - w definicje funkcji (w takim przypadku funkcja, fooktóra zwraca SomeType). Przepraszam za nekro, ale jeśli ktokolwiek natknie się na to, pomyślałem, że odpowiem.
Pozew funduszu Moniki
7
W C ++ użyj konstruktorów bez argumentów. W C nie możesz mieć konstruktorów, więc użyj jednego memsetlub - ciekawe rozwiązanie - wyznaczonych inicjatorów:
Myślę, że to C, a nie C ++. Nie uda się skompilować w niektórych kompilatorach C ++. Wystąpił błąd kompilacji w Cygwin lub MinGW.
jww
3
Uważam, że poprawną odpowiedzią jest to, że ich wartości są niezdefiniowane. Często są one inicjowane na 0 podczas uruchamiania debugowanych wersji kodu. Zwykle nie dzieje się tak podczas uruchamiania wersji.
To samo dotyczy podwójnego; all-bit-zero niekoniecznie jest 0,0. Możesz jednak sprawdzić, czy masz podwójne IEEE754, w którym to przypadku musi działać.
MSalters
1
Przenieś członków kapsuły do klasy podstawowej, aby skrócić listę inicjalizującą:
Odpowiedzi:
Nie są zerowe, jeśli nie zainicjujesz struktury.
Drugi spowoduje, że wszyscy członkowie będą zero, pierwszy pozostawi ich na nieokreślonych wartościach. Pamiętaj, że jest rekurencyjny:
Drugi spowoduje
p.s.{x,y}
zero. Nie możesz używać tych zagregowanych list inicjalizacyjnych, jeśli masz w swoim konstruktorze konstruktory. W takim przypadku konieczne będzie dodanie odpowiedniej inicjalizacji do tych konstruktorówZainicjuje zarówno x, jak i y do 0. Zauważ, że możesz użyć
x(), y()
do zainicjowania ich bez względu na ich typ: To jest następnie inicjalizacja wartości i zwykle daje prawidłową wartość początkową (0 dla int, 0,0 dla podwójnego, wywoływanie domyślnego konstruktora dla zdefiniowanego przez użytkownika typy, które mają zadeklarowane przez użytkownika konstruktory, ...). Jest to ważne, zwłaszcza jeśli twój struct jest szablonem.źródło
Snapshot s = {};
działał dla członków spoza POD (do ich zerowania)?Nie, domyślnie nie są to 0. Najprostszym sposobem upewnienia się, że wszystkie wartości lub domyślnie 0 to zdefiniowanie konstruktora
Zapewnia to, że wszystkie zastosowania migawki będą miały zainicjowane wartości.
źródło
Ogólnie nie. Jednak struktura zadeklarowana jako zakres pliku lub statyczna w funkcji / will / zostanie zainicjowana na 0 (podobnie jak wszystkie inne zmienne tych zakresów):
źródło
Z POD możesz także pisać
Nie powinieneś używać memset w C ++, memset ma tę wadę, że jeśli w strukturze nie ma POD, to go zniszczy.
lub tak:
źródło
SomeType foo();
jest typowy, choć może się zdarzyć z innymi - w definicje funkcji (w takim przypadku funkcja,foo
która zwracaSomeType
). Przepraszam za nekro, ale jeśli ktokolwiek natknie się na to, pomyślałem, że odpowiem.W C ++ użyj konstruktorów bez argumentów. W C nie możesz mieć konstruktorów, więc użyj jednego
memset
lub - ciekawe rozwiązanie - wyznaczonych inicjatorów:źródło
Uważam, że poprawną odpowiedzią jest to, że ich wartości są niezdefiniowane. Często są one inicjowane na 0 podczas uruchamiania debugowanych wersji kodu. Zwykle nie dzieje się tak podczas uruchamiania wersji.
źródło
0
w tych miejscach w pamięci. To nie to samo, co inicjalizacja!Ponieważ jest to POD (zasadniczo struktura C), inicjowanie go w sposób C ma niewielką szkodę:
lub podobnie
Nie posunąłbym się jednak tak daleko, aby użyć go
calloc()
w programie C ++.źródło
Przenieś członków kapsuły do klasy podstawowej, aby skrócić listę inicjalizującą:
źródło