Historia pytania:
W wczesnych wersjach C++ wszystkie człony klasy musiały być inicjalizowane albo w liście inicjalizacji konstruktora, albo w ciele konstruktora. Od momentu wprowadzenia C++11 stała się możliwa inicjalizacja niestatystycznych członów klasy bezpośrednio w miejscu ich definicji — znacznie poprawiło to czytelność i zmniejszyło prawdopodobieństwo błędów z nieinicjalizowanymi zmiennymi.
Problem:
Brak inicjalizacji domyślnej prowadził do nieoczywistego zachowania dla programistów, szczególnie przy pojawianiu się nowych konstruktorów. Nie było gwarancji, że człony klasy są zawsze inicjalizowane. Piękno i nowość podejścia polega na zmniejszeniu ilości boilerplate-kodu.
Rozwiązanie:
Inicjalizacja inline nadaje wartość domyślną dla członu klasy, jeśli nie był on jawnie zainicjalizowany w liście inicjalizacji konstruktora.
Przykład kodu:
class Widget { int value = 42; std::string name{"default"}; public: Widget() {} Widget(int v) : value(v) {} };
Kluczowe cechy:
Czy wartość z inicjalizacji inline będzie użyta, jeśli człon jest podany w liście inicjalizacji konstruktora?
Nie, użyta będzie wartość z listy inicjalizacji konstruktora. Przykład:
class Test { int a = 10; public: Test(int x) : a(x) {} }; Test t(42); // a == 42
Czy można inicjalizować statyczne człony klasy inline?
Nie, tylko niestatystyczne. Statyczne człony klasy są inicjalizowane osobno poza klasą.
Czy można używać wyrażeń do inicjalizacji członów klasy inline?
Dla prostych członów — tak (na przykład, wywołanie konstruktora lub literał). Dla złożonych obliczeń użyj funkcji lub inicjalizacji w konstruktorze.
Zespół dodał nowy konstruktor, ale zapomniał o inicjalizacji pola. Pozostało ono z nieinicjalizowaną wartością. Pojawiały się błędy przy dostępie do zmiennej.
Zalety:
Wady:
Zastosowano inicjalizację inline dla wszystkich pól klasy. W nowych konstruktorach nie trzeba było jawnie pisać inicjalizacji, zmniejszono ilość boilerplate-kodu i błędów.
Zalety:
Wady: