Beginner's Guide

# Simple Aggregate TypesSimple Aggregate TypesAggregates

## Type Categories (simplified)Type Categories

###### Fundamental Types
`void`, `bool`, `char`, `int`, `double`, …
###### Simple AggregatesPODs(Plain Old Data Types)
• may contain one/many fundamental or other types (that can be initialized in an aggregate-compatible way)
• default construction / destruction / copy / assignment
• standard memory layout
• unrestricted member access
• no user-defined member initialization
###### Non-Trivial Types

may have/be

• member functions / restricted member access
• user-defined construction / member initialization
• user-defined destruction / copy / assignment
• non-standard memory layout
• polymorphic (contain virtual member functions)

## Simple Aggregates / PODsPODs

##### Example: Type point with 2 integer coordinates
``````struct point {
int x;  // ← "member variable"
int y;
};
// create new object (on stack)
point p {44, 55};
// read members' values
cout << p.x <<' '<< p.y;  // 44 55``````

Member variables are stored in the same order as they are declared.

 -7682 STACK 23988 p.y 55 top p.x 44 ⋮

Assigning to member values:

``````p.x = 10;
p.y = 20;
cout << p.x <<' '<< p.y;  // 10 20``````
 -7682 STACK 23988 p.y 20 top p.x 10 ⋮

Fundamental types are not default-initialized ⇒ members get whatever value was in memory at the time:

``````point u;      // uninitialized
cout << u.x;  // random value!``````
 141 STACK u.y -7682 top u.x 23988 p.y 20 p.x 10 ⋮

## Why Custom Types / Data Aggregation?Why Custom Types?Why?

• semantic data grouping: `point`, `date`, …
• avoids many function parameters and thus, confusion
• can return multiple values from function with one dedicated type instead of multiple non-const reference output parameters
``void closest_point_on_line(double lx2, double ly1, double lx2i, double ly2, double px, double py, double& cpx, double& cpy) { … }``
• many parameters of same type ⇒ easy to write bugs
• non-const reference output parameters ⇒ error-prone
• internal representation of a line is also baked into the interface
``````struct point { double x; double y; };
struct line  { point a; point b; };
point closest_point_on_line(line const& l, point const& p) { … }``````
• straight-forward interface
• easy to use correctly
• If internal representation of line changes ⇒ implementation of `closest_point_on_line` needs to be changed too, but interface does not ⇒ calling code can stay the same most of the times!

## Aggregate InitializationInitialization

``Type { arg1, arg2, …, argN }``
• brace-enclosed list of member values
• in order of member declaration
``````enum class month {jan = 1, feb = 2,…, dec = 12};
struct date {
int yyyy;
month mm;
int dd;
};
int main() {
date today {2020, month::mar, 15};
// C++98, but also still OK:
date tomorrow = {2020, month::mar, 16};
}``````

## Compounds

##### Example: date as member of person
``````enum class month { jan=1, feb=2,… , dec=12 };
struct date {
int yyyy;
month mm;
int dd;
};
struct person {
std::string name;
date bday;
};
int main() {
person jlp { "Jean-Luc Picard",              {2305, month::jul, 13} };
cout << jlp.name;     // Jean-Luc Picard
cout << jlp.bday.dd;  // 13

date yesterday { 2020, month::jun, 16 };
person rv = { "Ronald Villiers", yesterday };
}``````

## Copying

##### Copies are always deep copies of all members!
``````enum class month {jan = 1, … };
struct date {
int yyyy;  month mm;  int dd;
};
int main() {
date a {2020, month::mar, 7};
date b = a;  // deep copy of a
b.dd = 22;   // change b
}``````

State after last line of main:

 STACK b.dd 22 top b.mm 3 b.yyyy 2020 a.dd 7 a.mm 3 a.yyyy 2020 ⋮
• Copy Construction = create new object with same values as source
• Copy Assignment = overwrite existing object's values with that of source
``````struct point { int x; int y; };
point p1 {1, 2};  // construction
point p2 = p1;    // copy construction
point p3 ( p1 );  // copy construction
point p4 { p1 };  // copy construction
auto  p5 = p1;    // copy construction
auto  p6 ( p1 );  // copy construction
auto  p7 { p1 };  // copy construction
p3 = p2;  // copy assignment
// (both p2 & p3 existed before)``````

## `std::vector` of PODsinside `std::vector`

• `vector<T>`'s storage contains objects of type `T` themselves, not just references or pointers to them (as in Java/C#/…)
• if vector object gets destroyed ⇒ contained `T` objects get destroyed
``vector<int> v { 0,1,2,3,4 };``
``````struct p2d { int x; int y; };
vector<p2d> v {{1,2},{5,6},{8,9}};``````

## The Most Vexing Parse

Can't use empty parentheses for object construction due to an ambiguity in C++'s grammar:

``````struct A { … };
A a ();  // declares function 'a'
// without parameters
// and return type 'A'
A a;     // constructs an object of type A
A a {}   // constructs an object of type A``````