Przejdź do głównej zawartości

Posty

Fabryka

Witam, dawno mnie tu nie było i nie mam dobrego usprawiedliwienia tego stanu rzeczy. W tym artykule przeanalizujemy wzorzec projektowy fabryka (factory, wirtualny konstruktor, metoda wytwórcza). Sprawa jest dość prosta wzorzec ten opisuje sytuacje w której proces tworzenia obiektu delegowany jest do specjalnej klasy(functora lub zwykłej funkcji lub singletona). Korzyść z takiego podejścia to scentralizowanie tworzenia skomplikowanych obiektów będących podklasami jednego ogólnego obiektu. Poniżej uogólniona implementacja metody wytwórczej: template <typename T> class Factory { public:   static Factory<T>& getInstance()   {     static Factory<T>* instance = NULL;     if(!instance)     {       std::lock_guard<std::mutex> guard( Factory<T>::factoryCreationMutex );       if(!instance)       {         instance = new Factory<T>();       }     }     return *instance;   }   T* createObject(std::stri
Najnowsze posty

C++ metaprogramowanie z wykorzystaniem szablonów cz. 3

Dzisiaj omówię ostatnie z podstawowych zastosowań dla metaprogramowania. Nie przeciągając dziś będzie o „pętlach bez pętli”. W wielu przypadkach (a może i nie w aż tak wielu ale w kilku na pewno) mamy do czynienia z pętlą której ilość iteracji jest znana już w momencie kompilacji programu. W takich sytuacjach kompilator potrafi sam powielić kod zachowując odpowiedni indeks iteratora np.: for(int i=0; i<3; i++) {   func(i); } func(0); func(1); func(2);  Taki kod zadziała nieco szybciej gdyż nie ma potrzeby inkrementowania zmiennej i oraz jej alokacji dealokacji. Niestety nie mamy gwarancji że kompilator tak postąpi. Prezentowane zachowanie zależne jest od samego kompilatora jego wersji oraz wykorzystywanych optymalizacji. Aby wymusić wygenerowanie kodu przez kompii lator można skorzystać z template'ów. A oto rozwiązanie problemu void func(int i){std::cout<< i << std::endl;} template<int i, typename FuncType> class MetaInlineLoop {  publi

C++11 Variadic templates – szablony ze zmienną liczba parametrów

Witam w nowym roku. Dziś będzie o nowym elemencie szablonów czyli o szablonach ze zmienną liczbą parametrów. Ich implementacja i zachowanie różni się nieco od klasycznych szablonów. Nowa funkcjonalność pozwala na tworzenie bezpiecznych list typów. template<typename ...Ts> void variadic_template(){} Pierwszą nowością jest zastosowanie ...(wielokropka) przy określaniu typów szablonu. W ten sposób sygnalizujemy mnogość typów. Niestety nie mamy możliwości iterowania po kolejnych typach wewnątrz naszego szablonu. Ponadto taka definicja pozwala na stworzenie/wywołanie naszej szablonowej funkcji bez typów. variadic_template<>(); Aby tego uniknąć można uciec się do następującej sztuczki: template<typename T1, typename ...Ts> void variadic_template(T1 arg, Ts... args) W powyższym przykładzie jawnie wymuszamy podanie przynajmniej jednego typ dla naszej funkcji szablonowej. Jak już wspomniałem nie możemy jawnie iterować po typach przekazanych do

Metaprogramowanie cz2 – polimorfizm inaczej

Jak działa polimorfizm wie każdy programista języka C++ jest to przecież najpopularniejsza cech programowania obiektowego. Za pomocą funkcji wirtualnych, klas abstrakcyjnych jesteśmy w stanie tworzyć kod ogólny, bazując jedynie na interfejsach, zrzucając jednocześnie sposób rozwiązania na klasy pochodne dostarczające implementację. Wszystko pięknie ładnie i elastycznie. Niestety funkcje wirtualne są najzwyczajniej w świecie wolne. Jak wiadomo są miejsca w każdym dużym projekcie które wymagają minimalizacji opóźnień. Czy w tych miejscach należy zatem rezygnować z polimorfizmu i oferowanej przez niego elastyczności na rzecz maksymalizacji czasu działania kodu? Na szczęście są sposoby na obejście tego problemu, z pomocą przychodzą nam jak zwykle szablony. Zacznijmy od zaprezentowania szablonu który w pozwala na zdefiniowanie typu na podstawie wartości (więcej szczegółów na ten temat można znaleźć w Nowoczesne projektowanie w C++. Uogólnione implementacje wzorców projektowych ). te

C++ metaprogramowanie z wykorzystaniem szablonów cz. 1

Ten wpis rozpoczyna cykl dotyczący metaprogramowania, ilość oraz częstotliwość publikacji kolejnych części pozostaje nieustalona. Poniżej zaprezentowane zostanie absolutny elementarz, czyli wyznaczanie dowolnego elementów wyrazu ciągu Fibonacciego w czasie kompilacji. #include <iostream> template<unsigned int N> struct Fib {   static const unsigned int el = Fib<N-1>::el + Fib<N-2>::el; }; template<> struct Fib<0> {   static const unsigned int el = 0; }; template<> struct Fib<1> {   static const unsigned int el = 1; }; int main(void) {   const unsigned int N = 5;   std::cout << "fib( " << N << " ) = " << Fib<N>::el << std::endl;   return 0; } Tych parę linijek zmusza do wyliczenia 5 elementu ciągu Fibonacciego kompilator, co oznacza że jedynymi instrukcjami jakie zostaną wykonane przez nasz program po sko

Makra i preprocesor

Jako programista klasycznego C przyszło mi wielokrotnie ścierać się z makrami. Makro to zestaw instrukcji umieszczanych w kodzie są jednak interpretowane nie przez kompilator ale przez preprocesor. Preprocesor jest „pomocnikiem” kompilatora, zajmuje się on np. wstawianiem treści plików nagłówkowych do plików z kodem za pomocą instrukcji #include. Preprocesor należy rozumieć jako prymitywny edytor tekstu dokonujący „korekcji” plików z kodem źródłowym przed rozpoczęciem ich przetwarzania przez kompilator. Jakie są zalety wykorzystywania tych rozwiązań w kodzie? Tak naprawdę w języku C w czasach przed wprowadzeniem słowa kluczowego inline umożliwiały wstawianie kodu we wskazane miejsce. Należy bowiem pamiętać że każdorazowe wstawienie makroinstrukcji powoduje ingerencję w kod źródłowy (innymi słowy we wskazanym miejscu zostanie wstawiony stosowny fragment kodu). Łatwo obserwowalnym efektem częstego wykorzystywania makr w plikach z kodem jest rozrost pliku binarnego oraz jego szybsze d

Dlaczego nie lubię zintegrowanych środowisk programistycznych?

Czym jest zintegrowane środowisko programistyczne(IDE) nie trzeba tłumaczyć. Do najpopularniejszych należą Visual Studio, Eclipse, NetBeans, QTCreator, Borland Developer Studio, Xcode. Posiadają wiele przydatnych narzędzi do refaktoringu kodu, podpowiadają składnie, indeksują symbole w obrębie projektu, integrują się z systemem kontroli wersji i posiadają tysiące funkcji „ułatwiających” codzienną pracę. Skoro są takie cudowne to czy można im coś zarzucić? Moja odpowiedź brzmi TAK. A jest to przede wszystkim konfiguracja projektu do pracy z zewnętrznymi niestandardowymi bibliotekami i sposób budowania. W większości wymienionych środowisk nie jest generowany automatycznie plik makefile, ustawienia sposobu budowy projektu i linkowania zaszyte są gdzieś po zakładkach, i opcjach konfiguracyjnych. Jestem jednocześnie świadom że każde z tych środowisk pozwala na wczytanie własnego makefila i na jego podstawie potrafi utworzyć, zindeksować projekt, tym nie mniej nie jest to opcja