Wenn Sie modernes C++-Design lernen möchten und aus der OOP-Welt kommen, lohnt sich als Einstieg ein Blick in die Loki library.
Loki ist der Name einer C++-Softwarebibliothek, die Andrei Alexandrescu im Rahmen seines Buches entwickelt hat Modern C++ Design.
Die Bibliothek nutzt intensiv die Template-Metaprogrammierung von C++ und implementiert mehrere häufig verwendete Werkzeuge: Typelisten, Funktoren, Singletons, Smart Pointer, Objektfabriken, Visitor und Multimethoden.
Der Autor nennt für den Entwurf dieser Bibliothek folgende Beweggründe:
- Loki-Nutzer zahlen nur für die Funktionen, die sie tatsächlich benötigen. Jede Loki-Komponente kann unabhängig von den anderen verwendet werden.
- „Small is beautiful“ – Lokis interne Abhängigkeiten sind gering.
- „Multiplicative is splendid.“ – Loki konzentriert sich besonders darauf, durch die Kombination kleiner, abstrakter Verhaltensbausteine (Policies) vielfältige, fein abgestimmte und spezialisierte Designs zu ermöglichen.
- Loki konzentriert sich auf Strategie statt Taktik, auf Design statt Details und auf Architekturkomponenten statt auf eine überladene Universallösung.
- Da Loki eine Bibliothek von Designs und nicht einfach das Design einer Bibliothek ist, sollte sie möglichst wenige Annahmen über ihre Umgebung treffen und überall dort geeignete Erweiterungspunkte bereitstellen, wo eine Standardentscheidung getroffen wird.
- Loki nimmt keine Rücksicht auf weniger leistungsfähige Compiler. Ziel ist lesbarer Code innerhalb des C++-Standards.
- Idealerweise sind die Komponenten klein, leicht zu verstehen und korrekt einzusetzen, sowohl einzeln als auch gemeinsam nützlich und haben einen großen Nutzen für Projekte.
Bevor Sie jedoch tiefer in die modernen C++-Idiome von Loki einsteigen, sollten Sie ein zentrales Konzept der Template-Programmierung beherrschen: Policy-based Design.
Das zentrale Idiom des Policy-based Design ist ein Klassen-Template (die sogenannte Host-Klasse), das mehrere Typparameter entgegennimmt. Diese werden mit vom Benutzer ausgewählten Typen (Policy-Klassen) instanziiert. Jede Policy-Klasse implementiert eine bestimmte implizite Schnittstelle (Policy) und kapselt einen orthogonalen oder weitgehend unabhängigen Aspekt des Verhaltens der instanziierten Host-Klasse. Durch die Kombination einer Host-Klasse mit verschiedenen vorgefertigten Implementierungen jeder Policy kann eine Bibliothek oder ein Modul eine exponentielle Anzahl unterschiedlicher Verhaltenskombinationen unterstützen. Diese werden zur Compile-Zeit aufgelöst und durch das passende Kombinieren der bereitgestellten Policy-Klassen bei der Instanziierung des Host-Templates ausgewählt.
Hier ist ein kleines Beispiel aus Wikipedia das dieses nützliche Idiom veranschaulicht:
#include
#include
template
class HelloWorld : private OutputPolicy, private LanguagePolicy
{
using OutputPolicy::print;
using LanguagePolicy::message;
public:
// Behaviour method
void run() const
{
// Two policy methods
print(message());
}
};
class OutputPolicyWriteToCout
{
protected:
template
void print(MessageType const &message) const
{
std::cout << message << std::endl;
}
};
class LanguagePolicyEnglish
{
protected:
std::string message() const
{
return "Hello, World!";
}
};
class LanguagePolicyGerman
{
protected:
std::string message() const
{
return "Hallo Welt!";
}
};
int main()
{
/* Example 1 */
typedef HelloWorld<OutputPolicyWriteToCout, LanguagePolicyEnglish> HelloWorldEnglish;
HelloWorldEnglish hello_world;
hello_world.run(); // prints "Hello, World!"
/* Example 2
* Does the same, but uses another language policy */
typedef HelloWorld<OutputPolicyWriteToCout, LanguagePolicyGerman> HelloWorldGerman;
HelloWorldGerman hello_world2;
hello_world2.run(); // prints "Hallo Welt!"
}
Nachdem Sie Policy-based Design kennengelernt haben, können Sie sich den weiteren von der Bibliothek verwendeten Idiomen widmen:
- Multiple Dispatcher
- Pimpl
- Printf (ein typsicherer Ersatz für printf)
- Geordnete Erzeugung statischer Objekte
- Scope-Guard-Pointer
- Small Object Allocator
- Smart Pointer
- Compile-Time-Prüfung
Eine ausführliche Erklärung der oben genannten Idiome finden Sie in dieser interessanten Ressource.
Zusammenfassend ist die Loki-Bibliothek zwar nicht so populär wie STL oder Boost, aber sie ist eine interessante Lernbibliothek, um die grundlegenden Idiome des modernen C++-Designs kennenzulernen. Sie bietet einen guten Einstieg, um modernes C++-Design zu beherrschen.
