Lista inicjalizacyjna konstruktora

Z Wikipedii, wolnej encyklopedii

Lista inicjalizacyjna konstruktora (zwana też jego preambułą) – opcjonalny fragment definicji konstruktora zawierający listę wartości, które mają być użyte do inicjalizacji wybranych składowych każdego obiektu tworzonego tym konstruktorem.

Geneza[edytuj | edytuj kod]

Obiektowe języki programowania z reguły umożliwiają tworzenie obiektów tej samej klasy na wiele różnych sposobów. Wymaga się przy tym, by każdy obiekt tuż po utworzeniu był w pełni gotowy do użycia. Oznacza to, że zasadniczo konstruktory powinny dokonywać pełnej inicjalizacji wszystkich danych przechowywanych w obiektach. Jednak sposób inicjalizacji składowych może zależeć od sposobu konstrukcji samego obiektu (np. różne konstruktory mogą przyjmować inne założenia co do wartości domyślnych pewnych składowych). Dlatego informacji potrzebnych do inicjalizacji składowych obiektu nie można podawać w miejscu ich definicji (jak ma to miejsce w przypadku stałych, zmiennych lub całych obiektów), lecz muszą one stanowić integralną część każdego konstruktora.

Zastosowanie[edytuj | edytuj kod]

  • Nadanie wartości danym podczas konstrukcji obiektu. Dla danej stałej (oznaczonej jako const) jest to jedyna możliwość nadania jej wartości początkowej, podczas gdy zmienne nie-const mogą zostać zainicjalizowane zarówno na liście inicjalizacyjnej jak też w formie zwykłego przypisania im wartości.
  • Wywołanie konstruktorów obiektów składowych - jest to jedyny sposób na wywołanie takich konstruktorów.
  • Wywołania konstruktora klas bazowych - jest to jedyny sposób na wywołanie takich konstruktorów.

Gdy klasa bazowa lub obiekt składowy klasy posiada konstruktor domniemany, jego wywołanie nie musi się pojawić na liście inicjalizacyjnej

Przykład[edytuj | edytuj kod]

W języku C++ lista inicjalizacyjna znajduje się w definicji konstruktora. Znajduje się pomiędzy zamykającym nawiasem listy parametrów konstruktora (oddzielona dwukropkiem) a klamrą otwierającą ciało konstruktora. Przykład w języku C++:

class Bazowa {
  public:
    int dana;
    
    Bazowa() { // konstruktor domyślny
      dana = 0;
    } 
    Bazowa( int wartosc ) {
      dana = wartosc;
    } 
};

class Pochodna : public Bazowa {
  public:
    int x;
    int y;
    const int z;
    Bazowa obiektSkladowy;

    Pochodna( int xx , int yy , int zz )
      :             // rozpoczecie listy inicjalizacyjnej
      x( xx + 3 ) , // inicjalizacja zwyklej zmiennej
      z( zz ) ,     // inicjalizacja stalej
      Bazowa( xx + yy + zz ) // wywolanie konstruktora klasy bazowej
      {
        y = yy;  // zwykle przypisanie do zmiennej
      }
};
Widzimy listę inicjalizacyjną konstruktora w klasie Pochodna. Rozpoczyna się od dwukropka następnie występuje nazwa zmiennej i w nawiasach okrągłych wartość jaką chcemy jej przypisać. Przypisaniem może być takie samo wyrażenie jak zwykłe przypisanie wartości zmiennej, a więc może to być zarówno wynik operacji arytmetycznych jak i wynik działania jakiejś funkcji. Następnie znajduje się inicjalizacja stałej. Jest to jedyna możliwość nadania jej wartości w momencie tworzenia obiektu. Nie można wykonać zwykłego przypisania wartości do stałej w ciele konstruktora - wtedy jest już za późno, musimy to zrobić właśnie na liście inicjalizacyjnej. Dalej widzimy wywołanie konstruktora klasy bazowej Bazowa( xx + yy + zz ). W tym przypadku wywołujemy konstruktor który nie jest domyślny, stąd też jego wywołanie musi się pojawić na liście inicjalizacyjnej konstruktora klasy pochodnej. Gdybyśmy chcieli wywołać konstruktor domyślny Bazowa() nie musielibyśmy takiego wywołania umieszczać na liście inicjalizacyjnej. Następnie można by umieścić wywołanie konstruktora obiektu składowego Bazowa obiektSkladowy. Jest to jedyny sposób na wywołanie takiego konstruktora dla obiektu składowego. W tym przypadku wywoływany jest konstruktor domyślny, stąd też wywołanie to możemy pominąć na liście inicjalizacyjnej.

Właściwości[edytuj | edytuj kod]

  • Lista inicjalizacyjna nie może inicjalizować statycznego składnika klasy.
  • Lista inicjalizacyjna może się pojawić tylko w definicji konstruktora.
  • Kolejność wywołań konstruktorów klasy bazowej czy też obiektów składowych jest ściśle określona (zobacz: konstruktor) i nie jest ważna kolejność w jakiej zostaną napisane wywołania konstruktorów klas bazowych na liście inicjalizacyjnej.
  • Zaleca się aby jeśli to tylko możliwe inicjalizować jak najwięcej składowych na liście inicjalizacyjnej konstruktora.

Zobacz też[edytuj | edytuj kod]