An aggregate class gives users direct access to its members and has special initialization syntax. A class is an aggregate if
• All of its data members are public
• It does not define any constructors
• It has no in-class initializers (§ 2.6.1, p. 73)
• It has no base classes or virtual
functions, which are class-related features that we’ll cover in Chapter 15
For example, the following class is an aggregate:
struct Data {
int ival;
string s;
};
We can initialize the data members of an aggregate class by providing a braced list of member initializers:
// val1.ival = 0; val1.s = string("Anna")
Data val1 = { 0, "Anna" };
The initializers must appear in declaration order of the data members. That is, the initializer for the first member is first, for the second is next, and so on. The following, for example, is an error:
// error: can't use "Anna" to initialize ival, or 1024 to initialize s
Data val2 = { "Anna", 1024 };
As with initialization of array elements (§ 3.5.1, p. 114), if the list of initializers has fewer elements than the class has members, the trailing members are value initialized (§ 3.5.1, p. 114). The list of initializers must not contain more elements than the class has members.
It is worth noting that there are three significant drawbacks to explicitly initializing the members of an object of class type:
• It requires that all the data members of the class be public
.
• It puts the burden on the user of the class (rather than on the class author) to correctly initialize every member of every object. Such initialization is tedious and error-prone because it is easy to forget an initializer or to supply an inappropriate initializer.
• If a member is added or removed, all initializations have to be updated.