Wertinitialisierung in C++
Eine Initialisierung mit geschweiften Klammern gilt zunächst als Initialisierung mit einer Initialisierungsliste. Bei leeren geschweiften Klammern wird diese Initialisierung aber dann meist als Wertinitialisierung (value initialization ) interpretiert.
Wertinitialisierung bei fundamentalen Typen
Bei fundamentalen Typen ist eine Initialisierung mit leeren geschweiften Klammern immer eine Wertinitialisierung (2016: 8.5.4p3.9).
Die Wertinitialisierung bei fundamentalen Typen bedeutet bedeutet eine 0-Initialisierung (2016: 8.5p8.4)
main.cpp
#include <iostream> /* ::std::cout */
#include <ostream> /* << */
#include <string> /* ::std::string */
#include <initializer_list>
int main()
{ int const i{}; ::std::cout << '>' << i << "<\n";
double const d{}; ::std::cout << '>' << d << "<\n"; }::std::cout
>0<
>0<
Wertinitialisierung bei Objekten von Klassen
Falls ein Objekt einer Klasse mit einem Fehlkonstruktor mit einer leeren Initialisierungsliste initialisiert wird, wird das Objekt wertinitialisiert (2016: 5.4.2p3.4).
Die Wertinitialisierung bei einem Objekt einer Klasse ist ebenfalls eine Fehlinitialisierung (2016: 8.5p8). (Dieser geht in bestimmten Fällen noch eine 0-Initialisierung voran, diese Details sollen hier aber noch nicht vertieft werden.)
Die Fehlinitialisierung bei einem Objekt einer Klasse erfolgt mit dem Konstruktor für den Initialisierer »()« (2016: 8.5p7).
main.cpp
#include <iostream> /* ::std::cout */
#include <ostream> /* << */
#include <string> /* ::std::string */
#include <initializer_list>
int main()
{ ::std::string const s{}; ::std::cout << '>' << s << "<\n"; }::std::cout
><
Der Zustand, den ein Exemplar nach dieser Form der Initialisierung hat, kann der Dokumentation der verwendeten Klasse entnommen werden. Bei der Klasse »::std::string« wird der Fehlkonstruktor verwendet, der ein leeres ::std::string-Exemplar anlegt.
- Dokumentation der Klasse »::std::string« nach C++ 2015, 21.4.2 (vereinfacht und übersetzt)
::std::string();
- Anlegen eines leeren ::std::string-Exemplars.
::std::string …( ::std::initializer_list< char >l );
- Anlegen eines ::std::string-Exemplars mit dem Text der Zeichen einer Initialisierungsliste
::std::string( ::std::string const & s );
- Anlegen eines ::std::string-Exemplars mit dem Text eines anderen ::std::string-Exemplars »s«.
::std::string( char const * s );
- Anlegen eines ::std::string-Exemplars mit dem Text einer Zeichenfolge »s«.
::std::string( int n, char c );
- Anlegen eines ::std::string-Exemplars mit dem Text einer n-fachen Wiederholung des Zeichens »c«.
Initialisierung mit leeren runden Klammern
Der Teil »::std::string s();« mit leeren runden Klammern, wie in dem folgenden Programm, ist gar keine Definition eines Exemplars. Er wird von C++ als Deklaration einer parameterlosen Funktion mit dem Rückgabetyp »::std::string const« interpretiert (“C++'s most vexing parse ”). Daher sollten zur Wertinitialisierung eines Objekts bevorzugt leere geschweifte Klammern, aber nicht leere runde Klammern, verwendet werden sollten. Da runde Klammern an dieser Stelle auch noch in einigen anderen Fällen zu Mißverständnissen führen könnten sind geschweifte Klammern in Definitionen zu bevorzugen.
main.cpp
#include <iostream> /* ::std::cout */
#include <ostream> /* << */
#include <string> /* ::std::string */
int main() { ::std::string const s(); ::std::cout << '>' << s << "<\n"; }::std::cout
>1<