b'\n_START_ARTICLE_\nKlasy parametryzowane wytycznymi\n_START_PARAGRAPH_\nKlasy parametryzowane wytycznymi spopularyzowa\xc5\x82 i om\xc3\xb3wi\xc5\x82 Andrei Alexandrescu. Wytyczne s\xc4\x85 technik\xc4\x85 metaprogramowania w C++ z wykorzystaniem szablon\xc3\xb3w, umo\xc5\xbcliwiaj\xc4\x85c\xc4\x85 uzyskanie du\xc5\xbco wi\xc4\x99kszej elastyczno\xc5\x9bci w projektowaniu klas._NEWLINE_Konstruowanie klas parametryzowanych wytycznymi polega na sk\xc5\x82adaniu klasy z wykorzystaniem innych klas (tzw. wytycznych), z kt\xc3\xb3rych ka\xc5\xbcda okre\xc5\x9bla pewien fragment zachowania g\xc5\x82\xc3\xb3wnej klasy. W praktyce, mo\xc5\xbcna my\xc5\x9ble\xc4\x87 o klasach wytycznych jako o pewnym rodzaju wtyczek, kt\xc3\xb3re doczepiane do klas, umo\xc5\xbcliwiaj\xc4\x85 elastyczne, bezpieczne typologicznie i efektywne dostosowywanie klas przez u\xc5\xbcytkownika, bez r\xc4\x99cznego pisania setek r\xc3\xb3\xc5\xbcnych wariant\xc3\xb3w, kt\xc3\xb3re r\xc3\xb3\xc5\xbcni\xc4\x85 si\xc4\x99 tylko szczeg\xc3\xb3\xc5\x82ami dzia\xc5\x82ania. Jest to technika bardzo podobna do wzorca projektowego Strategia, tyle tylko \xc5\xbce tam zmiana dzia\xc5\x82ania obiekt\xc3\xb3w mo\xc5\xbce nast\xc4\x99powa\xc4\x87 dynamiczne, podczas dzia\xc5\x82ania programu, natomiast wytyczne ustalaj\xc4\x85 zachowanie ju\xc5\xbc podczas kompilacji.\n_START_SECTION_\nPrzyk\xc5\x82ad\n_START_PARAGRAPH_\nZa\xc5\x82\xc3\xb3\xc5\xbcmy \xc5\xbce piszemy klas\xc4\x99 inteligentnego wska\xc5\xbanika i, ze wzgl\xc4\x99d\xc3\xb3w efektywno\xc5\x9bciowych, chcemy da\xc4\x87 u\xc5\xbcytkownikowi mo\xc5\xbcliwo\xc5\x9b\xc4\x87 okre\xc5\x9blenia czy w danym przypadku ma zachodzi\xc4\x87 przeprowadzane testowanie poprawno\xc5\x9bci, czy nie. Jednym z mo\xc5\xbcliwych rozwi\xc4\x85za\xc5\x84 tego problemu jak dodanie parametru do konstruktora obiektu, kt\xc3\xb3ry determinuje jak inteligentny wska\xc5\xbanik ma si\xc4\x99 zachowywa\xc4\x87. Jednak wspomniane wzgl\xc4\x99dy efektywno\xc5\x9bciowe przestrzegaj\xc4\x85 nas przed tym, gdy\xc5\xbc nale\xc5\xbca\xc5\x82oby przeprowadza\xc4\x87 testowanie if w ka\xc5\xbcdym miejscu kodu, co wprowadza\xc5\x82oby dodatkowy narzut nawet wtedy, gdy u\xc5\xbcytkownik wybra\xc5\x82by wariant bez testowania poprawno\xc5\x9bci._NEWLINE_Standardowa klasa SmartPtr mo\xc5\xbce zosta\xc4\x87 skr\xc3\xb3towo zapisana w ten spos\xc3\xb3b:_NEWLINE__NEWLINE_ template <class T>_NEWLINE_ class SmartPtr_NEWLINE_  {_NEWLINE_   // ..._NEWLINE_  };_NEWLINE_Aby wykorzysta\xc4\x87 wytyczne, do klasy SmartPtr musimy doda\xc4\x87 jeszcze jeden parametr szablonu, kt\xc3\xb3ry b\xc4\x99dzie ustala\xc5\x82 spos\xc3\xb3b obs\xc5\x82ugi b\xc5\x82\xc4\x99d\xc3\xb3w. Tak wi\xc4\x99c, od tej pory nasza klasa SmartPtr mo\xc5\xbce wygl\xc4\x85da\xc4\x87 np. tak:_NEWLINE__NEWLINE_ template <class T, class ErrorHandling>_NEWLINE_ class SmartPtr : public ErrorHandling_NEWLINE_  {_NEWLINE_   // ..._NEWLINE_  };_NEWLINE_Dziedziczymy publicznie od klasy ErrorHandling, tak wi\xc4\x99c wszystkie metody tej klasy od tej pory wchodz\xc4\x85 w sk\xc5\x82ad klasy SmartPtr. Co wi\xc4\x99cej, zachowanie tych metod zmienia si\xc4\x99 w zale\xc5\xbcno\xc5\x9bci od tego jak\xc4\x85 klas\xc4\x99 wy\xc5\x9blemy w miejsce ErrorHandling. Tak wi\xc4\x99c, gdy wywo\xc5\x82amy np. metod\xc4\x99 void ErrorHandling\xc2\xa0:: Check(), to gdy ErrorHandling b\xc4\x99dzie r\xc3\xb3wne NoChecking, wtedy nie b\xc4\x99dzie \xc5\xbcadnego sprawdzania. Natomiast gdy wy\xc5\x9blemy StrictCheckcing, to ka\xc5\xbcda dereferencja wska\xc5\xbanika przy wywo\xc5\x82aniu (w tym przypadku) metody Get() b\xc4\x99dzie sprawdzana:_NEWLINE_template <class T>_NEWLINE_ struct NoChecking_NEWLINE_  {_NEWLINE_   void Check(T * _ptr) { /* pusto, brak sprawdzania poprawno\xc5\x9bci */ }_NEWLINE_  }_NEWLINE__NEWLINE_ template <class T>_NEWLINE_ struct StrictChecking_NEWLINE_  {_NEWLINE_   void Check(T * _ptr) { if (0 == _ptr) { /* obs\xc5\x82u\xc5\xbc b\xc5\x82\xc4\x85d */ } }_NEWLINE_  }_NEWLINE__NEWLINE_ // Opis klasy:_NEWLINE_ //  Wytyczna ErrorHandling musi posiada\xc4\x87 metod\xc4\x99 void Check(T*)_NEWLINE_ template <class T, class ErrorHandling>_NEWLINE_ class SmartPtr : public ErrorHandling_NEWLINE_  {_NEWLINE_   public:_NEWLINE__NEWLINE_   T * Get() const_NEWLINE_    {_NEWLINE_     Check(_ptr);  // <----- !!! zmienia si\xc4\x99 w zale\xc5\xbcno\xc5\x9bci od ErrorHandling_NEWLINE_     return _ptr;_NEWLINE_    }_NEWLINE__NEWLINE_   private:_NEWLINE__NEWLINE_    T * _ptr;_NEWLINE_ };_NEWLINE__NEWLINE_ // U\xc5\xbcywanie:_NEWLINE__NEWLINE_ struct Foo_NEWLINE_  {_NEWLINE_   void Bar() { }_NEWLINE_  };_NEWLINE__NEWLINE_ SmartPtr<Foo, NoChecking<Foo> > ptrNoCheck = new Foo();_NEWLINE__NEWLINE_ ptrNoCheck.Get()->Bar();  // Get() nie sprawdzane_NEWLINE__NEWLINE_ SmartPtr<Foo, StrictChecking<Foo> > ptrChecked = new Foo();_NEWLINE__NEWLINE_ ptrChecked.Get()->Bar();  // Get() sprawdzane_NEWLINE_Aby doda\xc4\x87 wsparcie dla np. wielow\xc4\x85tkowo\xc5\x9bci i liczenia referencji, i jednocze\xc5\x9bnie pozostawi\xc4\x87 u\xc5\xbcytkownikowi mo\xc5\xbcliwo\xc5\x9b\xc4\x87 wyboru zachowania klasy, jak r\xc3\xb3wnie\xc5\xbc dodawania w\xc5\x82asnych \xe2\x80\x9estrategii zachowa\xc5\x84\xe2\x80\x9d, wystarczy doda\xc4\x87 kolejne wytyczne. W przypadku stosowania innych technik, osi\xc4\x85gni\xc4\x99cie podobnych rezultat\xc3\xb3w najprawdopodobniej nie by\xc5\x82oby tak \xc5\x82atwe._NEWLINE_Wytyczne s\xc4\x85 technik\xc4\x85 u\xc5\xbcyteczn\xc4\x85 szczeg\xc3\xb3lnie dla tw\xc3\xb3rc\xc3\xb3w bibliotek i silnik\xc3\xb3w, poniewa\xc5\xbc umo\xc5\xbcliwiaj\xc4\x85 pisanie kodu, kt\xc3\xb3ry mo\xc5\xbce by\xc4\x87 w \xc5\x82atwy, przeno\xc5\x9bny, efektywny i bezpieczny typologicznie spos\xc3\xb3b rozszerzany przez u\xc5\xbcytkownik\xc3\xb3w.'