Chyba trochę komplikujecie w zasadzie prostą sprawę. Bez opisu.. kod:
#include <iostream>
// Usuwaj i dodawaj komentarz w linii 6
// by zobaczyć róźnicę pomiędzy inicjalizacją przez
// listę inicjalizacyjną i bez.
//#define INIT_LIST
struct Checker {
Checker() {
std::clog << "default constructor Checker\n";
}
Checker(int a): a{a} {
std::clog << "int arg constructor Checker\n";
}
private:
int a;
};
struct MyClass {
#ifdef INIT_LIST
MyClass(int a): checker{a} {
}
#else
MyClass(int a) {
checker = a;
}
#endif
private:
Checker checker;
};
int main() {
MyClass myClass{42};
}
Konsekwencją takiego działania jest konieczność inicjalizacji atrybutów stałych w liście inicjalizacyjnej.
Jeszcze tylko niespodzianka z kolejnością inicjalizacji. Odpowiednie ostrzeżenie w kompilatorze wytyka tę potencjalną pomyłkę.
#include <iostream>
struct Checker {
Checker() {
std::clog << "default constructor Checker\n";
}
Checker(int a): a{a} {
std::clog << "int arg constructor Checker a = "
<< a << '\n';
}
int getA() const {
return a;
}
private:
int a;
};
struct MyClass {
// Mimo innej kolejności w liście inicjalizacyjnej,
// inicjalizacja przebiegnie w kolejności definicji atrybutów
// w klasie czyli: checker1, checker2, checker3
MyClass(int a): checker3{}, checker1{a}, checker2{12} {
}
private:
Checker checker1;
Checker checker2;
Checker checker3;
};
int main() {
MyClass myClass{42};
}
I tu tylko należy uważać by inicjalizacja atrybutów nie była od siebie zależna bo zawsze wykonywana jest w kolejności definicji atrybutów.
Jak się da, inicjuj w liście. Jeśli się nie da/nie umiesz/niezręczna klasa, trzeba będzie to zrobić w konstruktorze wiedząc o koszcie lub... zmienić klasę która się temu nie poddaje :)
I tyle..