# Initializer List

Now let's go back to the *Goods* class we wrote before. Suppose we want to add a production date to the goods, with a *Data* class:

```cpp
class Date {
 public:
  Date(int y, int m, int d) {
    _year = y;
    _month = m;
    _date = d;
  }
​
  void show() { 
      cout << _year << "/" << _month << "/" << _day << endl; 
  }
​
 private:
  int _yead;
  int _month;
  int _date;
}
```

Then we can make the data as one of the member attributes:

```cpp
class Goods {
    ...
private:
      char _name[20];
      double _price;
      int _amount;
      Date _date;
}
```

But an error raises: *Date* does not have a default constructor. Remember that the declaration of an object includes both memory allocation and construction. We have already defined a customized constructor in *Date*, so there is no default constructor. But the constructor requires three parameters: year, month and date, which is provided when a *Goods* object is created. How can we pass them inside? A **initializer list** is used in initializing data members of a class. The list of members to be initialized is indicated with constructor as a comma-separated list followed by a colon:

```cpp
Goods::Goods(const char *name, double price, int amount, int y, int m, int d) 
    : _date(y, m, d) {
  strcpy(_name, name);
  _price = price;
  _amount = amount;
}
```

In this way, *y*, *m* and *d* can be passed inside the constructor of *Date*. Not only can objects be initialized in this way, we can also use initializer list to initialize a normal member variable:

```cpp
Goods::Goods(const char *name, double price, int amount, int y, int m, int d) 
    : _date(y, m, d), _price(price), _amount(amount) {
  strcpy(_name, name);
}
```

Notice that this initialization simply assigns values to variables, so *\_name* has to be initialized inside the constructor with *strcpy()*.

What's the initialization sequence of the initializer list? Does it follows the order from left to right? Let's look at this case.

```cpp
class Test {
public:
    Test(int data = 10) : mb(_data), ma(mb) {}
    void show() {cout << "ma: " << ma << " mb " << mb << endl;}
private:
    int ma;
    int mb;
};
​
int main() {
    Test t;
    t.show();   // ma: -858993460 mb: 10
    return 0;
}
```

When *t.show()* is called, we find that *mb* is 10, but *ma* is a weird number. This is actually the default initial value in Visual Studio, which means that *ma* is not initialized correctly with *mb*. In fact, the initialization order only depends on the order we declared the variables, and has nothing to do with the initializer list. In the above case, we declared *ma* before *mb*, so *ma* is initialized first.<br>
