Professional Documents
Culture Documents
sfider@students.mimuw.edu.pl
Marcin widerski
Metaprogramowanie
Metaprogramowanie to pisanie programw komputerowych, ktre modyfikuj lub generuj kod innego programu, bd te wykonuj cz pracy w trakcie kompilacji. W C++ metaprogramowanie jest moliwe do zrealizowania za pomoc mechanizmu programowania uoglnionego, jakim s szablony.
Klasy parametryzowane wytycznymi Inteligentne wskaniki Programowanie statyczne Funktory uoglnione Implementacja singletonu Fabryki obiektw Fabryki abstrakcyjne
Wytyczna
Implementuje fragment funkcjonalnoci projektowanej klasy Jest oparta na skadni, a nie na sygnaturze Potrafi wzbogaci projektowan klas o dodatkowe funkcjonalnoci Umoliwia modyfikacj struktury klasy W poczeniu z innymi wytycznymi tworzy wykadnicz ilo wersji projektowanej klasy
Wytyczna Creator
Implementacje wytycznej Creator:
template< class T > struct OpNewCreator { static T* create() { return new T; } }; template< class T > struct MallocCreator { static T* create() { void* buf = std::malloc(sizeof(T)); if (!buf) return 0; return new(buf) T; } };
Korzystanie z wytycznych
// Kod biblioteki template< template <class> class CreationPolicy = OpNewCreator > class WidgetManager : public CreationPolicy< Widget > { ... }; // Kod uytkownika typedef WidgetManager< MallocCreator > MyWidgetManager;
Destruktory wytycznych
template< class T > struct OpNewCreator { static T* create() { return new T; } protected: ~OpNewCreator() {...} };
Chroniony, aby jedynie klasa-gospodarz moga niszczy obiekt wytycznej Niewirtualny, aby zminimalizowa narzut czasowy i pamiciowy
Inteligentne wskaniki
Speniaj rol analogiczn do zwykych wskanikiw W C++ mog udawa zwyke wskaniki syntaktycznie Potrafi zniszczy wskazywany obiekt Wiedz kiedy zniszczy wskazywany obiekt Potrafi pilnowa swojej integralnoci Mog, ale nie musz, by konwertowane do zwykych wskanikw
Inteligentne wskaniki
Rozkad na wytyczne ortogonalne:
Storage:
OwnerShip:
Definiuje moment niszczenia obiektu DeepCopy, RefCounted, RefCountedMT, COMRefCounted, RefLinked, DestructiveCopy, NoCopy
Inteligentne wkaniki
Rozkad na wytyczne ortogonalne c.d.:
Conversion:
Definiuje, czy dozwolona jest konwersja inteligentnego do zwykego wskanika AllowConverion, DisallowConversion Mechanizm kontroli integralnoci AssertCheck, AssertStrictCheck, RejectNullStatic, RejectNull, RejectNullStrict, NoCheck
Checking:
Programowanie statyczne
Jest to termin, ktrego A. Alexandrescu uywa w swojej ksice w odniesieniu do programowania za pomoc szablonw. Programowanie statyczne wykorzystuje szablony do tworzenia pewnego rodzaju funkcji oraz funkcji rekurencyjnych, ktrych argumentami oraz wartociami zwracanymi mog by statycznie wyliczane stae (np. liczby cakowite) oraz typy.
Wybr typu
template< bool flag, class T, class U > struct Select { typedef T Result; }; template< class T, class U > struct Select< false, T, U > { typedef U Result; }; template< class T, bool isPolymorphic > class NiftyContainer { ... typedef typename Select< isPolymorphic, T*, T >::Result ValueType; ... };
Cig Fibonacciego
template<> struct Fib; template<> struct Fib< 0 > { enum { value = 1 }; }; template<> struct Fib< 1 > { enum { value = 1 }; }; template< int f > struct Fib { enum { value = Fib< f 1 >::value + Fib< f 2 >::value; }; };
Inne sztuczki
Statyczne wykrywanie dziedziczenia i moliwoci konwersji Opakowanie dla type_info nadaje semantyk wartoci NullType warto kompletnie nieinteresujca EmptyType dobry domylny argument szablonu Cechowanie typw
Listy typw
Pozwalaj na powielenie kodu dla wielu typw Umoliwiaj implementacj np. Fabryki Abstrakcyjnej
template< class T, class U > struct TypeList { typedef T Head; typedefU Tail; }; #define TYPELIST_1(T1) TypeList< T1, NullType > #define TYPELIST_2(T1, T2) TypeList< T1, TYPELIST_1(T2) > ... #define TYPELIST_50(...)...
Length< TList > TypeAt< TList, idx > TypeAtNonStrict< TList, idx > IndexOf< TList, T > Append< TList, T > Erase< TList, T > EraseAll< TList, T > NoDuplicates< TList > Replace< TList, T, U > ReplaceAll< TList, T, U > MostDerived< TList, T > DerivedToFront< TList >
Hierarchia rozlega
Generowanie krotek
template<class T > struct Holder { T value_; }; typedef GenScatterHierarchy< TYPELIST_4(int, string, float, bool), Holder > MixedTuple; MixedTuple tuple; ... int i = Field< 0 >(tuple).value_; string s = Field< 1 >(tuple).value_; float f = Field< 2 >(tuple).value_; bool b = Field< 3 >(tuple).value_;
Hierarchia liniowa
template< class T, class Base > class EevntHandler : public Base { public: virtual void onEvent( T& obj, int eventId); };
Funktory uoglnione
Kapsukuj dowolne polecenie przetwarzania (funkcj, funkcj skadow, funktor, funktor uoglniony) Bezpieczne typologicznie Semantyka wartoci Uatwiaj implementacj wzorca projektowego Polecenie Pozwalaj na wizanie argumentw oraz czenie wielu funktorw sekwencyjnie (domknicia?)
Implementacja singletonu
template< class T, template< class > class CreationPolicy = CreateUsingNew, template< class > class LifetimePolicy = DefaultLifetime, template< class > class ThreadingModel = SingleThreaded > class SingletonHolder;
Szablon SingletonHolder zarzdza jedynie cyklem ycia obiektu, ktry sam musi by singletonem Tworzenie: CreateUsingNew, CreateStatic, CreateUsingMalloc, Cykl ycia: DefaultLifetime, NoDestroy, PhoenixSingleton, SingletonWithLongevity Wielowtkowo: SingleThreaded, ClassLevelLockable
Fabryka obiektw
template< class AbstractProduct, class IdentifierType, class ProductCreator = AbstractProduct*(*)(), template< class, class > class FactoryErrorPolicy = DefaultFactoryError > class Factory;
Fabryka tworzy obiekty na podstawie identyfikatorw typw (np. w celu serializacji) Kada klasa w hierarchii, dla ktrej utworzona jest fabryka musi sama si w fabryce zarejestrowa Odmian fabryki obiektw jest fabryka klonw, w ktrej kluczem jest typ obiektu (RTTI)
Fabryka abstrakcyjna
Fabryka abstrakcyjna suy do tworzenia rodzin powizanych lub zalenych od siebie obiektw polimorficznych Implementacja fabryki abstrakcyjnej korzysta z list typw do przekazania listy produktw Fabryk abstrakcyjn implementuj dwa szablony: AbstractFactory, ConcreteFactory
Szablon AbstractFactory
template< class TList, template< class > class Unit = AbstractFactoryUnit > class AbstractFactory;
Konkretyzacja AbstractFactoryUnit< T > definiuje funkcj czysto wirtualn T* DoCreate(Type2Type< T >) AbstractFactory udostpnia szablon szablon funkcyjny skadowy Create, ktry mona skonkretyzowa dla dowolnego z typw produktw fabryki abstrakcyjnej
Soldier *soldier = factory->Create< Soldier >();
Szablon ConcreteFactory
template< class AbstractFact, template< class, class > class FactoryUnit = OpNewFactoryUnit, class TList = AbstractFactory::ProductList > class ConcreteFactory; typedef ConcreteFactory< AbstractEnemyFactory, OpNewFactoryUnit, TYPELIST_3(SillySoldier, SillyMonster, SillySuperMonster) > EasyLevelEnemyFactory; typedef ConcreteFactory< AbstractFactory, PrototypeFactoryUnit > EnemyFactory;
Pominite
Odwiedzajcy wariant cykliczny i acykliczny Wielometody implementacja statyczna liniowa, oraz dwie dynamiczne: logarytmiczna nieintruzyjna, staa intruzyjna
rda
Nowoczesne projektowanie w C++ A.Alexandrescu Strona A.Alexandrescu: http://erdani.org Strona biblioteki Loki: http://loki-lib.sourceforge.net Wikipedia :P