2011-08-16 13 views
8

Zawsze uważałem, że tworzenie nowego obiektu zawsze wywoływałoby domyślny konstruktor obiektu i to, czy konstruktor był jawny, czy automatycznie generowany przez kompilator, nie robiło różnicy. Według this highly regarded answer do innej kwestii, to zmieniło się w subtelny sposób między C++ 98 i C++ 03 i działa teraz tak:Różnica między inicjowaniem domyślnym a zainicjowaniem wartości w C++ 03?

struct B { ~B(); int m; }; // non-POD, compiler generated default ctor 
new B; // default-initializes (leaves B::m uninitialized) 
new B(); // value-initializes B which zero-initializes all fields since its default ctor is compiler generated as opposed to user-defined. 

ktoś może mi powiedzieć:

  1. dlaczego standard się zmienił, tj. jaką korzyść daje to, lub co jest teraz możliwe, czego wcześniej nie było;
  2. Co dokładnie oznaczają terminy "default-initialize" i "value-initialize"?
  3. Jaka jest istotna część standardu?
+0

Odpowiednią częścią nowego standardu C++ 11 jest 8.5 ("Inicjatory") klauzule 5,6,7. –

+0

Może daje ludziom opcję użycia domyślnego ctor, czy nie. W starej wersji C++ nawiasy były zwykle pomijane, gdy nie było żadnych parametrów. Zatem posiadanie nawiasów w nowej opcji wpłynie na mniejszy kod starszy. – QuentinUK

+0

Nie nazwałbym tego zmianą, ale raczej poprawką. Ma to przynajmniej sens w kontekście np. std :: map gdzie wartości utworzone przez [] są zinicjalizowane, np. std :: map wszystkie U * są inicjowane do 0 – PlasmaHH

Odpowiedz

2

nie wiem co uzasadnieniem wokół zmian (lub jak standard był wcześniej), ale jak to jest w zasadzie default-inicjalizacji jest albo wywołanie użytkownika zdefiniowanego konstruktora albo nic nie robi (dużo hand-falowanie tutaj: jest to rekursywnie stosowane do każdego podobiektu, co oznacza, że ​​podobiekty z domyślnym konstruktorem zostaną zainicjowane, podobiekty bez konstruktorów zdefiniowanych przez użytkownika pozostaną niezainicjowane).

To wchodzi w zakres płacić tylko za to, co chcesz, filozofii języka i jest kompatybilny z C we wszystkich typach, które są kompatybilne C. Z drugiej strony można żądać inicjowania wartości i jest to odpowiednik wywołania konstruktora domyślnego dla obiektów, dla których jest on konwertowany na odpowiedni typ dla pozostałych podobiektów.

Jest to opisane w §8.5 Inicjatory i nawigacja nie jest banalna. Definicje zerowej inicjalizacji, default-zainicjować i wartości zainicjować są 5th ustęp:

zero-zainicjować obiekt typu T oznacza:

- jeśli T jest typ skalarny (3.9), obiekt jest ustawiony na wartość 0 (zero) konwertowany na T;

- jeśli T jest typem klasy niezłączonym, każdy niestatyczny element danych i każdy obiekt podrzędny klasy podstawowej jest zerowany;

- jeżeli T jest typem związku, pierwszy nazwany element danych89) jest inicjowany od zera;

- jeśli T jest typem tablicy, każdy element jest inicjowany od zera;

- jeżeli T jest typem referencyjnym, inicjalizacja nie jest wykonywana.

do wartości domyślnych zainicjować obiekt typu T oznacza

- jeśli T jest nie-POD klasy typu (punkt 9), konstruktor domyślną T nazywa (i inicjalizacji źle tworzy czy T nie ma dostępnego domyślnego konstruktora);

- jeśli T jest typem tablicy, każdy element jest domyślnie inicjowany;

- w przeciwnym razie obiekt jest inicjowany od zera.

Do wartości zainicjować obiekt typu T oznacza:

- jeśli T jest typem klasy (pkt 9) z konstruktora użytkownika zadeklarowana (12,1), a następnie konstruktor domyślny dla T nazywa (i inicjalizacja jest źle sformułowana, jeśli T nie ma dostępnego domyślnego konstruktora);

- jeśli T jest klasą niepowiązaną bez konstruktora deklarowanego przez użytkownika, wówczas każdy niestatyczny element danych i składnik bazowy T jest zainicjowany wartością;

- jeśli T jest typem tablicy, to każdy element jest inicjowany wartością;

- w przeciwnym razie obiekt jest zero-zainicjowany

Program, który wzywa do domyślnej-inicjalizacji lub od wartości inicjalizacji jednostki typu odniesienia illformed. Jeśli T jest typem kwalifikowanym cv, to wersja T bez cv jest używana dla definicji zeroinitializacji, inicjalizacji domyślnej i inicjalizacji wartości.

+0

Twój wiodący akapit definiuje zachowanie Default-initialization jako albo za pomocą ctorka lub jego lewej niezainicjowanej. Moje pytanie dotyczy interpretacji zawartego cytatu z sekcji 8.5 Initializer definiującej domyślną inicjał, który ma jako ostatni krok ... "- w przeciwnym razie obiekt jest inicjowany od zera". Jego wydaje się zasugerować, że jeśli nie ma ctor, użyj zasady zero-zainicjować vs pozostawiając niezainicjowany. – TheChrisONeil

+0

@CBO: Ten konkretny cytat pochodzi z C++ 03, w C++ 11 ostatnia pozycja zmieniła się i brzmi: * w przeciwnym razie nie zostanie przeprowadzona inicjalizacja *. Kluczem w tym miejscu jest to, co zostało napisane kilka akapitów później. Dla obiektu bez inicjalizatora, w C++ 03 obiekt pozostaje niezainicjowany (w/9), w C++ 11 obiekt jest * domyślnie zainicjowany * (/ 12).Nie jestem pewien, czy to odpowiada na twoje wątpliwości. –

+0

Ma sens i dzięki za obserwację. Polecam aktualizację twojego postu, aby teraz zawierał treść C++ 11. – TheChrisONeil