モダンC++設計の学習を始めることにし、OOPのバックグラウンドを持っているなら、 Loki ライブラリの内部を見ることから始めることができます。
Loki は、Andrei Alexandrescuが彼の著書『 Modern C++ Design』の一部として執筆したC++ソフトウェアライブラリの名前です。
このライブラリは、C++テンプレートメタプログラミングを広範に活用し、タイプリスト、ファンクタ、シングルトン、スマートポインタ、オブジェクトファクトリ、ビジター、マルチメソッドなど、一般的に使用されるいくつかのツールを実装しています。
このライブラリの設計の背後にある著者の動機は次のとおりです。
- Lokiのユーザーは、必要な機能に対してのみコストを支払えばよいのです。Lokiの各コンポーネントは、他のコンポーネントから独立して使用できます。
- 「小は美なり」— Lokiの内部依存関係は小さい。
- 「乗法的なものは素晴らしい」— Lokiの特別な焦点は、小さく抽象的な動作の断片(ポリシー)を組み合わせることで、乗法的な動作(つまり、きめ細かく特殊化された設計)を実現することです。
- Lokiは戦術ではなく戦略に、ビットではなく設計に、台所の流し台ではなくアーキテクチャコンポーネントに焦点を当てています。
- Lokiはライブラリの設計ではなく設計のライブラリであるため、その環境について最小限の前提しか置かず、デフォルトの決定が選択される場所には適切なフックを提供すべきです。
- Lokiは能力の低いコンパイラに迎合しません。Lokiは、標準C++の範囲内で読みやすいコードを書くことを目指しています。
- コンポーネントは理想的には、小さく、理解しやすく正しく使いやすく、単独でも組み合わせても有用で、プロジェクトへの影響が大きいものです。
しかし、そのモダンC++イディオムにさらに深く入る前に、テンプレートプログラミングの中心的な概念であるポリシーベース設計イディオムを習得するのが良いでしょう。
ポリシーベース設計の中心的なイディオムは、クラステンプレート(ホストクラスと呼ばれる)で、いくつかの型パラメータを入力として受け取ります。これらはユーザーが選択した型(ポリシークラスと呼ばれる)でインスタンス化され、それぞれが特定の暗黙的なインターフェース(ポリシーと呼ばれる)を実装し、インスタンス化されたホストクラスの動作の直交する(またはほぼ直交する)側面をカプセル化します。ホストクラスと各ポリシーの異なる既製の実装セットを組み合わせて提供することで、ライブラリやモジュールは、コンパイル時に解決される指数関数的な数の異なる動作の組み合わせをサポートでき、ホストクラステンプレートのインスタンス化でさまざまな提供ポリシークラスを組み合わせて選択できます。
これは、 Wikipedia からのこの便利なイディオムを示す小さな例です。
#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!"
}
ポリシーベース設計を発見したら、ライブラリで使用されている他のイディオムに進むことができます。
- マルチプルディスパッチャー
- Pimpl
- Printf(型安全なprintfの代替)
- 順序付き静的オブジェクト生成
- スコープガードポインタ
- スモールオブジェクトアロケーター
- スマートポインタ
- コンパイル時チェック
上記のイディオムの詳細な説明は、この興味深い リソースで入手できます。
要約すると、LokiライブラリはSTLやBoostほど人気はありませんが、基本的なモダンC++設計イディオムを学ぶための興味深い教育用ライブラリです。モダンC++設計を習得するための良い出発点です。
