2

私はModernC++ Designの本を読んでいませんが、テンプレートを介した動作インジェクションのアイデアが興味深いと感じました。私は今それを自分で適用しようとしています。

ポリシーとして注入できると思ったロガーを持ったクラスがあります。ロガーには、ポリシーに応じてstd::stringまたはstd::wstringを受け取るlog()メソッドがあります。

// basic_logger.hpp
template<class String>
class basic_logger
{
public:
    typedef String string_type;

    void log(const string_type & s) { ... }
};
typedef basic_logger<std::string> logger;
typedef basic_logger<std::wstring> wlogger;

// reader.hpp
template<class Logger = logger>
class reader
{
public:
    typedef Logger logger_type;

    void read()
    {
        _logger.log("Reading...");
    }

private:
    logger_type _logger;
};

ここでの質問は、読者が上記のようにロガーを引数として取る必要があるのか​​、それとも文字列を取り、次にbasic_loggerをインスタンス変数としてインスタンス化するのかということです。そのようです:

template<class String>
class reader
{
public:
    typedef String string_type;
    typedef basic_logger<string_type> logger_type;

    // ...

private:
    logger_type _logger;
};

行く正しい方法は何ですか?

4

3 に答える 3

2

実際にポリシークラスを使用するには、ポリシーがテンプレートパラメータである必要があります。1つの例は、basic_stringへのchar_traitsパラメーターです。これは、継承を使用して空の基本クラスの最適化を利用し、クラスのパブリックインターフェイスに簡単に追加できるようにするMC ++ Dのポリシーとは異なる方法で実装されます(よりもはるかに優れた方法で)可能な各メソッドをラップします。ここでも、MC ++ Dを読んでください)。デフォルトを指定することもできます。

template<class String, class Logger=basic_logger<String> >
struct reader : Logger {
  void read() {
    this->log("Reading...");
  }
};
于 2010-04-04T20:32:52.700 に答える
1

質問は、そのロガーのタイプ、またはそれが読み取るもののタイプに基づいてパラメーター化する必要がありますか?これが質問であるならば、私は答えが明白であると思ったでしょう-後者。

この質問IMHOの問題は、StringもLoggerも実際にはポリシーではないということです。ポリシーでは、コンパイル時に、ロガーのようなものがロギングをどのように実行する必要があるかを示しています。コードは、継承を使用して実行時に同様に実行できるタイプのロガーをリーダーに提供するだけです。

于 2010-04-04T20:21:07.227 に答える
1

ポリシーは通常、クラスの動作に影響を与えるパラメータです。

クラスからポリシーを抽出することは事実上非常に困難です。さらに難しいのは、他の概念に影響を与えずに1つを変更できるように、ポリシーが直交する概念をカバーする必要があることです...これは想像できるように非常に困難です。

ポリシーの使用の良い例を見たい場合Loki::Singletonは、本で完全に示されているものを調べてください。

template
<
  typename T,
  template <class> class CreationPolicy = CreateUsingNew,
  template <class> class LifetimePolicy = DefaultLifetime,
  template <class, class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL,
  class MutexPolicy = LOKI_DEFAULT_MUTEX
>
class SingletonHolder;

印象的ですね。

ポリシーベースの設計の原則は、クラスのさまざまなアクションを分解して、それらについて独立して推論できるようにすることです。

さて、今私は、設定された数のテンプレートパラメータを持つクラスを要求するという考えにあまり慣れていないことを認めなければなりません。私は個人的に何かを好んだでしょう:

template
<
  class T,
  class CreationPolicy = CreateUsingNew<T>,
  class LifetimePolicy = DefaultLifeTime<T>,
  class MutexPolicy = LOKI_DEFAULT_MUTEX,
  template <class, class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL
>
class SingletonHolder;

最後のものは本当に仕方がない、あなたはそれにSingletonHolderクラス自体を渡すことになっている。

ただし、ここでポリシーを交換する方が簡単だと思います。次のようなポリシーを定義できます。

template <class T, size_t Param> MyCreationPolicy;

そして、それが署名と一致するように、paramの特定の値に対してそれをラップする必要なしに直接使用します。

于 2010-04-05T11:59:25.230 に答える