2014-12-08 7 views
11

Pozdrowienia i hth. - Alf napisał w tym numerze answer, że inicjalizacja wartości jest prawdopodobnie nową cechą C++ 03 w porównaniu z C++ 98. Zastanawiam się, co miał na myśli.Czy inicjalizacja wartości jest częścią standardu C++ 98? Jeśli nie, dlaczego został dodany w standardzie C++ 03?

Czy value initialization jest częścią C++ 98? Czy jest obecny w koncepcji, ale nie w nazwie? Dlaczego został dodany do standardu C++ 03?

Mam kopię standardu '03, ale nie '98. Oto definicja domyślnej inicjalizacji i inicjowania wartości.

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 -formowane, jeśli 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 (klauzula 9) z konstruktora użytkownika zadeklarowana (12,1), a następnie konstruktor domyślny dla T nazywamy (i inicjalizacja jest źle sformułowana, jeśli T nie ma dostępnego domyślnego konstruktora);

- jeśli T jest nie do związków klasy typu bez konstruktora dla deklarowanej, wówczas każdy niż statyczna składowa element danych i baza klasy T ma wartość inicjowany;

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

- inaczej, obiekt jest zero-zainicjowany

Domyślam się, że '98 miał domyślną inicjalizacji ale nie inicjalizacji wartości i że istnieje jakaś zasadnicza różnica między tymi dwoma. Szczerze mówiąc mam problem z analizą standardese tutaj i nie rozumiem różnicy między definicjami.

Odpowiedz

9

Cytowanie the ISO/IEC 14882:1998 standard document (który został wycofany z ISO):

do domyślnych zainicjować obiekt typu T oznacza

  • jeśli T jest nie-POD typ klasy (klauzula 9), domyślny konstruktor dla T jest wywoływany (a inicjalizacja jest źle sformułowana, jeśli T nie ma dostępnego domyślnego konstruktora);
  • jeśli T jest typem tablicy, każdy element jest domyślnie zainicjowany;
  • W przeciwnym razie pamięć dla obiektu zostanie zainicjalizowana od zera.

I w pkt 7:

Obiekt, którego inicjator jest zbiorem pustym nawiasów, to znaczy (), będzie domyślnym zainicjowany.

Szczegóły na uzasadnienie tej zmiany można znaleźć w the defect report że tak się stało:

Definicja ta jest odpowiednia dla zmiennych lokalnych, ale nie dla obiektów, które są inicjowane w wyniku wykonywania wyrażenia w postaci w postaci T(), ponieważ obiekty wygenerowane przez takie wyrażenia zostaną natychmiast skopiowane, a zatem powinny mieć wartości, które są zapewnione z możliwością ich kopiowania.
W tym celu, I proponują dodanie po nowym tekstem do 8,5, ustęp 5,

do wartości inicjalizacji obiekt typu T oznacza

  • jeśli T typu klasy (klauzula 9 [klasa]) z konstruktem deklarowanym przez użytkownika (12.1), następnie wywoływany jest domyślny konstruktor dla T (i inicjalizacja jest źle sformułowana, jeśli T nie ma dostępnego domyślnego konstruktora );
  • jeśli T jest typem klasy bez konstruktora deklarowanego przez użytkownika, wówczas każdy niestatyczny element danych i element podstawowy składowej T jest zainicjowana wartość;
  • jeśli T jest typem tablicy, to każdy element jest inicjowany wartością;
  • W przeciwnym razie pamięć dla obiektu zostanie zainicjalizowana od zera.

Dodatkowo, proponuję zmienić '' default '' inicjalizację do '' od wartości inicjalizacji '' w pkt 5.2.3 2.

, a po tym, historyczne wyjaśnienie :

Historia starożytna

Dawno, dawno temu, AT & T kompilatora deweloper imieniem Laura Okap poprosił mnie: „«Jaka powinna być wartość int()?»” Moja pierwsza myśl była, że ​​ powinno mieć taką samą wartość jak x ma po mówiąc

int x; 

ale szybko zorientował się, że ta definicja nie zrobi. Powodem jest , że x ma nieokreśloną wartość (przy założeniu, że jest to lokalna zmienna ), ale nie mamy nic przeciwko temu, że x jest nieokreślona, ​​ponieważ jesteśmy prawdopodobnie przypisze wartość x zanim go użyjemy. Natomiast lepiej nie mieć nieokreślonej wartości, ponieważ kopiowanie takiej wartości ma nieokreślony efekt.Głupotą byłoby zabraniać kompilatorowi przed oznaczeniem int() podczas kompilacji, aby umożliwić mu oznaczenie go podczas wykonywania w trybie . [...]

+0

Masz to. Proponuję, aby niektóre z racjonalnych przesłanek z DR skierowane były na odpowiedź, aby była zamknięta. Daj mi znać, kiedy to zrobisz, abym mógł cię pochwalić. :) –

+0

Denerwujące w stosunku do wersji C++ 98 jest to, że jeśli posiadasz klasę zawierającą zmienne 'std :: string' i niektóre' int', nie ma możliwości, aby ją zera zainicjować ints inne niż jawnie wymień je wszystkie na liście inicjalizatora konstruktora. –

+0

@MattMcNabb Nie podążałem. Wymień je wszystkie na liście inicjalizującej, a nie co? Jeśli nie umieścisz ich na liście inicjalizacyjnej w C++ 03, to są one zerowane? – Praxeolitic

Powiązane problemy