27 czerwca 2013

[C++] Trochę o wirtualności (kiedy stosować wirtualne destruktory) i metodach szablonowa

Szukając informacji na temat stosowania destruktorów wirtualnych natknąłem się na artykuł (http://www.gotw.ca/publications/mill18.htm) Herba Suttera, dotyczący stosowania tego mechanizmu i troszkę więcej. Poniżej moje notatki.

Metody wirtualne bardzo rzadko powinny być publiczne (jeśli w ogóle). Publiczna wirtualna metoda, robi dwie rzeczy: specyfikuje interfejs i pokazuje detale implementacyjne - pozwalające na zmianę zachowania. Dobrze by było rozdzielić te dwie rzeczy. Sutter zaleca stosowania NVI (Non-virtual interface - wersja wzorca projektowego "metoda szblonowa" - definiuje szkielet algorytmu, który korzysta m.in. z operacji pierwotnych przedefiniowanych przez klasy pochodne). Korzyści: Interfejs staje się stabilny, a wszystkie modyfikacje oddelegowane zostają do klas pochodnych.
  • Porada #1: Preferuj tworzenie interfejsu jako nonvirutal, korzystająć z wzorca projektowego "metoda szablonowa"
  • Porada #2: Preferuj tworzenie metod wirtualnych jako prywatne. Metoda wirtualne stosuje się tylko by umożliwić modyfikacje działania.
  • Porada #3: Jeżeli klasa pochodna, potrzebuje wykonać metodę z klasy bazowej tylko wtedy może być zmieniona na protected.
Klasa powinna mieć wirtualny destruktor, jeżeli zamierzamy niszczyć (polimorficznie) obiekt korzystając ze wskaźnika na klasę bazową.
  • Porada #4: Destruktor klasy bazowej powinien być publiczny i wirtualny, albo protected i niewirtualny (gdy nie stosujemy polimorfizmu).
  • O ile stosowanie publicznego wirtualnego destruktor do mnie jeszcze przemawia, to nie jestem w stanie w tej chwili znaleźć zastosowania dla protected nonvirtual.
  • Porada #5: Nie dziedzicz po klasach konkretnych - pozostaw klasy nie będące liśćmi jako abstrakcyjne.
Oczywiście nietrudno znaleźć głosy, które nie do końca się z tym zgadzają. C++FAQ [23.4], zaleca stosowanie chronionych (protected) metod wirtualnych, ponieważ dla wielu deweloperów jest zaskoczeniem to, że prywatne wirtualne metody mogą zostać nadpisane. Marshall Cline, podaje też, dwa przypadki (C++FAQ [23.3]), dla których jego zdaniem wirtualne metody powinny być publiczne.

Pierwsza jest odwróceniem, metody szablonowej tj. chcemy by główny algorytm, mógł być modyfikowany przez klasy pochodne, natomiast prymitywne metody pozostały stałe w klasie bazowej - nie muszą być one wirtualne, bo i tak klasa pochodna zdecyduje, czy będzie chciała z nich skorzystać, czy z czegoś innego (C++FAQ [23.2]).

Ze zrozumieniem drugiej (C++FAQ [23.9]) mam niestety problem.

Brak komentarzy:

Prześlij komentarz