Klasy parametryzowane wytycznymi - Google

Klasy parametryzowane wytycznymi

Z Wikipedii

Skocz do: nawigacji, szukaj

Klasy parametryzowane wytycznymi spopularyzował i omówił Andrei Alexandrescu[1]. Wytyczne są techniką metaprogramowania w C++ z wykorzystaniem szablonów, umożliwiającą uzyskanie dużo większej elastyczności w projektowaniu klas.

Konstruowanie klas parametryzowanych wytycznymi polega na składaniu klasy z wykorzystaniem innych klas (tzw. wytycznych), z których każda określa pewien fragment zachowania głównej klasy. W praktyce, można myśleć o klasach wytycznych jako o pewnym rodzaju pluginów, które doczepiane do klas, umożliwiają elastyczne, bezpieczne typologicznie i efektywne dostosowywanie klas przez użytkownika, bez ręcznego pisania setek różnych wariantów, które różnią się tylko szczegółami działania. Jest to technika bardzo podobna do wzorca projektowego Strategia, tyle tylko że tam zmiana działania obiektów może następować dynamiczne, podczas działania programu, natomiast wytyczne ustalają zachowanie już podczas kompilacji.

[edytuj] Przykład

Załóżmy że piszemy klasę inteligentnego wskaźnika i, ze względów efektywnościowych, chcemy dać użytkownikowi możliwość określenia czy danym przypadku ma zachodzić przeprowadzane testowanie poprawności, czy nie. Jednym z możliwych rozwiązań tego problemu jak dodanie parametru do konstruktora obiektu, który determinuje jak inteligentny wskaźnik ma się zachowywać. Jednak wspomniane względy efektywnościowe przestrzegają nas przed tym, gdyż należałoby przeprowadzać testowanie if w każdym miejscu kodu, co wprowadzałoby dodatkowy narzut nawet wtedy, gdy użytkownik wybrałby wariant bez testowania poprawności.

Standardowa klasa SmartPtr może zostać skrótowo zapisana w ten sposób:

 template <class T>
 class SmartPtr
  {
   // ...
  };

Aby wykorzystać wytyczne, do klasy SmartPtr musimy dodać jeszcze jeden parametr szablonu, który będzie ustalał sposób obsługi błędów. Tak więc, od tej pory nasza klasa SmartPtr może wyglądać np. tak:

 template <class T, class ErrorHandling>
 class SmartPtr : public ErrorHandling
  {
   // ...
  };

Dziedziczymy publicznie od klasy ErrorHandling, tak więc wszystkie metody tej klasy od tej pory wchodzą w skład klasy SmartPtr. Co więcej, zachowanie tych metod zmienia się w zależności od tego jaką klasę wyślemy w miejsce ErrorHandling. Tak więc, gdy wywołamy np. metodę void ErrorHandling :: Check(), to gdy ErrorHandling będzie równe NoChecking, wtedy nie będzie żadnego sprawdzania. Natomiast gdy wyślemy StrictCheckcing, to każda dereferencja wskaźnika przy wywołaniu (w tym przypadku) metody Get() będzie sprawdzana:

 template <class T>
 struct NoChecking
  {
   void Check(T * _ptr) { /* pusto, brak sprawdzania poprawności */ }
  }
 
 template <class T>
 struct StrictChecking
  {
   void Check(T * _ptr) { if (0 == ptr) { /* obsłuż błąd */ } }
  }
 
 // Opis klasy:
 //  Wytyczna ErrorHandling musi posiadać metodę void Check(T*)
 template <class T, class ErrorHandling>
 class SmartPtr : public ErrorHandling
  { 
   public:
 
   T * Get() const
    { 
     Check(ptr);  // <----- !!! zmienia się w zależności od ErrorHandling
     return ptr;
    }
 
   private:
 
    T * ptr;
 };
 
 // Używanie:
 
 struct Foo
  {
   void Bar() { }
  };
 
 
 SmartPtr<Foo, NoChecking<Foo> > ptrNoCheck = new Foo();
 
 ptrNoCheck.Get()->Bar();  // Get() nie sprawdzane
 
 
 SmartPtr<Foo, StrictChecking<Foo> > ptrChecked = new Foo();
 
 ptrChecked.Get()->Bar();  // Get() sprawdzane


Aby dodać wsparcie dla np. wielowątkowości i liczenia referencji, i jednocześnie pozostawić użytkownikowi możliwość wyboru zachowania klasy, jak również dodawania własnych "strategii zachowań", wystarczy dodać kolejne wytyczne. W przypadku stosowania innych technik, osiągnięcie podobnych rezultatów najprawdopodobniej nie byłoby tak łatwe.

Wytyczne są techniką użyteczną szczególnie dla twórców bibliotek i silników, ponieważ umożliwiają pisanie kodu, który może być w łatwy, przenośny, efektywny i bezpieczny typologicznie sposób rozszerzany przez użytkowników.

[edytuj] Referencje

  1. Andrei Alexandrescu, Nowoczesne projektowanie w C++, WNT, 2005

[edytuj] Linki zewnętrzne

Przykładowy, pierwszy rozdział z powyższej pozycji, zawierający opis wytycznych (po angielsku)

Zastosowanie wytycznych w grach komputerowych do stworzenia elastycznego systemu cząsteczkowego

Przykłady wykorzystania wytycznych


Nowe odkrycia w twierdzy Heroda
W twierdzy króla Heroda, słynnym Herodionie na Pustyni Judzkiej niedaleko Betlejem, archeolodzy odkryli rzymski amfiteatr z freskami na ścianach - poinformował izraelski archeolog Ehud Netzer, prowadzący tam od 35 lat badania.
Polacy nie odróżniają plazmy od LCD
Wybierając telewizor, Polacy kierują się raczej marką niż technologią - mówił dr inż. Piotr Garbat z Politechniki Warszawskiej podczas konferencji prasowej poświęconej telewizyjnym preferencjom mieszkańców naszego kraju.
Europeana - europejska biblioteka w internecie
Rękopisy, książki, fotografie, mapy i arcydzieła europejskiego malarstwa znajdą się w internetowej bibliotece Europeana, której uroczysta inauguracja nastąpiła w czwartek w Brukseli.
Greenpeace wysypał tony głów tuńczyka w Paryżu
Pięć ton głów tuńczyka wysypali przed gmachem ministerstwa rolnictwa w Paryżu działacze organizacji Greenpeace, domagając się zaprzestania połowu tych ryb.
Cyfrowe zdjęcia mają swój "odcisk palca"
Dzięki charakterystycznym cechom zapisanym w każdym cyfrowym zdjęciu specjalista może ustalić, jakim aparatem je zrobiono - informuje "New Scientist".
Linki: Strona gwna