Основная задача конструктора это инициализация (P.S НЕ СТАТИЧЕСКИХ) полей класса.
Это можно сделать разными способами, присвоением в теле конструктора:
class A{
public:
A(const int & _a, const double &_b){
a = _a;
b = _b;
}
private:
int a;
double b;
};
Или с помощью списка инициализации:
class B{
public:
B(const int &_a, const double &_b): a(_a),b(_b){}
private:
int a;
double b;
};
В конкретно этом примере, не будет никакой разницы.Но что если у нас будет переменной-членом константа или ссылка?
Как вы знаете константам как и ссылкам не может быть присвоено значение после определения , так же они должны быть иницилизированы в момент их создания.
Рассмотрим клас A c константным полем:
class A{
public:
A(const int & _a, const double &_b , const int &_c){
a = _a;
b = _b;
c = _c; //expression must be a modifiable lvalue
}
private:
int a;
double b;
const int c;
};
Получаем ошибку так как константам нельзя присвоить значение после определения.
Но что делать если нам нужно добавить ссылку или константу в наш класс?
Для решения этой проблемы добавили member initializer list.C помощью него мы можем инициализировать константные поля класса(+ ссылки) значениями непосредственно перед выполнением тела конструктора.
Теперь рассмотрим класс B с константым полем:
class B{
public:
B(const int & _a, const double &_b , const int &_c): a(_a), b(_b), c(_c) {}
private:
int a;
double b;
const int c;
};
Все работает и поле
с наделено значением с параметра _с.Также хочу отметить одну особенность такой формы инициализации полей - инициализация объектов в классе происходит не в порядке member init list а в том порядке, в котором они объявлены в классе.То есть от перестановки выражений a(_a), b(_b) и c(_c) порядок инициализации не поменяется.Сначала получит значение а , потом b , и только в конце c.
Именно поэтому в прошлом посте ответ BA
P.S хочу отметить что список иниц полей важен не только для ссылок и констант, если в классе поля-объекта нету default конструктора то мы также получим ошибку как и со вторым примером класса А.
