Aggregatinitialisierungen in C++
Wir hatten uns schon früher mit Aggregatinitialisierungen beschäftigt, allerdings damals nur an Hand von Reihungen.
Reihungen sind Aggregate, also Objekte, die als eine Folge von Unterobjekten aufgefaßt werden können. Aber auch die einfachen bisher behandelten Klassenobjekte sind Aggregate. (Unter einem Klassenobjekt verstehen wir hier ein Objekt, dessen Typ eine Klasse ist. Es gibt auch Klassenobjekte, die keine Aggregate sind, welche wir aber erst später behandeln werden.)
Aggregat-Klassenobjekte können ähnlich wie Reihungen behandelt werden.
Die Aggregatinitialisierung erfolgt in der Form einer Listeninitialisierung. Bei der Aggregatinitialisierung wird jedes nicht-statische Feld der Klasse aus dem ihm gemäß der Position entsprechenden Eintrag der Initialisierungsliste kopierinitialisiert. Dabei sind implizite Typwandlungen also (wie bei einer Kopierinitialisierung) erlaubt, solange sie nicht verengend (wie bei einer Wandlung von »double« nach »int«) wirken.
Das folgende Programmbeispiel zeigt die Aggregatinitialisierung eines Objekts der Klasse »::entity«.
main.cpp
#include <iostream>
#include <ostream>
#include <string>using namespace ::std::literals;
struct entity { ::std::string string; };
int main()
{ ::entity const entity{ "abc"s }; /* <- Aggregatinitialisierung */
::std::cout << entity.::entity::string << '\n';
::std::cout << entity.string << '\n'; }::std::cout
abc
abc
Bei der Aggregatinitialisierung in dem obenstehendem Quelltext wird das Objekt »entity« in der Funktion »::main« mit dem Initialisierer »{ "abc"s }« aggregatinitialisiert. Dabei wird der Eintrag »::entity::string« mit dem Initialisierer »"abc"s« initialisiert.
Vor die öffnende geschweifte Klammer kann auch ein Gleichheitszeichen eingefügt werden. Wir zeigen diese Schreibweise in dem folgenden Beispielprogramm, aber verwenden danach bevorzugt die Schreibweise ohne Gleichheitszeichen und zeigen die Schreibweise mit Gleichheitszeichen nicht immer wieder.
Das folgende Programm zeigt die Aggregatinitialisierung mit einem Gleichheitszeichen.
main.cpp
#include <iostream>
#include <ostream>
#include <string>using namespace ::std::literals;
struct entity { ::std::string entity; };
int main()
{ ::entity const entity ={ "abc"s };
::std::cout << entity.entity << '\n'; }::std::cout
abc
Es ist möglich, daß verschachtelt aggregatinitialisiert wird. Dabei wird für die inneren Einträg auch wieder eine Kopierinitialisierung durchgeführt. Unten ist »{ { "abc"s }}« der Initialisierer für »container«, »{ "abc"s }« der für »contents« und »"abc"s « der für »string«.
main.cpp
#include <iostream>
#include <ostream>
#include <string>using namespace ::std::literals;
struct entity { ::std::string string; };
struct container { ::entity contents; };
int main()
{ ::container container{ { "abc"s }};
::std::cout << container.contents.string << '\n'; }::std::cout
abc
Es ist erlaubt, daß die inneren Klammern weggelassen werden, solange dadurch keine Mißverständnisse hervorgerufen werden.
main.cpp
#include <iostream>
#include <ostream>
#include <string>using namespace ::std::literals;
struct entity { ::std::string string; };
struct container { ::entity contents; };
int main()
{ ::container container{ "abc"s };
::std::cout << container.contents.string << '\n'; }::std::cout
abc
Zitate *
- n3797, 8.5.1p1
- An aggregate is an array or a class with no user-provided constructors, no private or protected non-static data members, no base classes, and no virtual functions.
Quellen *
- URIs
http://en.cppreference.com/w/cpp/language/aggregate_initialization