Konstruktory bezparametrowe

2008-06-28 12:12

W C++ konstruktor domyślny jest generowany automatycznie, jeśli w klasie nie zostanie zdefiniowany żaden inny. W przeciwnym wypadku nie jst on tworzony, co może prowadzić do sytuacji, gdy klasa posiada jedynie takie konstruktory, które wymagają podania parametrów. Jest ona niekorzystna przynajmniej z dwóch powodów:

  1. Gdy dziedziczymy po takiej klasie, musimy jakoś zapewnić, że w klasie pochodnej zostanie wywołany konstruktor klasy bazowej. Zwykle robi się to za pomocą listy inicjalizacyjnej:
    1. Derived(int param1, int param2) : Base(param1, param2) { /*... */ }

    Kiedy jednak zmieni się postać konstruktora klasy bazowej, wówczas modyfikacja będzie musiała dotyczyć wszystkich bezpośrednich potomków tej klasy. W nowej wersji standardu C++ ma być aczkolwiek wprowadzone nowe zadanie dla słowa kluczowego using, które pozwoli na automatyczne utworzenie konstruktorów “przekaźnikowych” – takich, których jedyną rolą jest wywołanie konstuktorów bazowych z takimi samymi parametrami jak te otrzymane w konstruktorze pochodnym. Jeśli jednak przy okazji chcemy coś zmienić czy pominąć, to nie ma rady: trzeba całą tę “sztafetę” zakodować ręcznie.

  2. Jeszcze gorzej jest, kiedy klasa bez konstruktora domyślnego jest wirtualną klasą bazową. Wówczas o jej prawidłowej inicjalizacji muszą pamiętać nie tylko klasy bezpośrednio pochodne, ale w ogóle wszystkie potomne! Dokładnie tak: nawet w piątym czy dziesiątym pokoleniu hierarchii o korzeniu w wirtualnej klasie bazowej, klasy pochodne muszą w swoich konstruktorach wywoływać konstruktory owego korzenia. To oczywiście sprawia, że każda zmiana musi być rozpropagowana na całe to drzewo dziedziczenia (a właściwie graf, bo pewnie zawiera on cykle :>).

Dlatego też klasy będące przede wszystkim klasami bazowymi w dziedziczeniu dobrze jest wyposażać w konstruktory bezparametrowe. Może to aczkolwiek wymagać wyróżnienia w obiekcie stanów Zainicjowany-Niezainicjowany, które powinny być sprawdzane w jego metodach i w razie potrzeby odpowiednio sygnalizowane.

Tags: ,
Author: Xion, posted under Programming »


5 comments for post “Konstruktory bezparametrowe”.
  1. Reg:
    June 29th, 2008 o 11:07

    Cykle w dziedziczeniu klas? Raczej nie. Co najwyżej złączenia gałęzi. Wtedy faktycznie to już nie jest drzewo, tylko dag (Directed Acyclic Graph).

  2. SiwyEd:
    June 29th, 2008 o 19:44

    Heh cykl przy dziedziczeniu –
    Class A;
    Class B public: A
    {…};
    Class A public: B
    {…};
    – to całkiem ciekawy pomysł, jeśli dałoby się to skompilować, to próba utworzenia obiektu A lub B powodowałaby nieskończoną rekurencję :D

  3. lukaszw:
    June 29th, 2008 o 23:33

    class A;
    class B : public A{};
    class A : public B{};

    “base class ‘A’ has incomplete type”

    Albo nie działa, albo mi sie myslenie już dziś wyłączyło ;)

  4. Xion:
    June 30th, 2008 o 19:32

    Faktycznie zasadniczo chodziło mi właśnie o złączenie gałęzi, które w grafie skierowanym (a takimi są grafy dziedziczenia) cyklem oczywiście nie jest. Przepraszam za zamieszanie :)

  5. moriturius:
    July 1st, 2008 o 9:08

    @lukaszw: nie wylaczylo. Jesli dobrze pamietam to do dziedziczenia potrzeba “calej” klasy a nie tylko jej deklaracji. Dlatego też trick z “class A;” nie podziała ;)

Comments are disabled.
 


© 2017 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.