tl; dr - 構図は私の状況にとって正しいデザインの選択のようですが、一緒に作っている各オブジェクトのヒープ割り当てのオーバーヘッドを避けたいと思います。どんな良いテクニックですか?合成(過剰継承)による余分なヒープ割り当ての回避
私は次のようになり、セットアップがあります。
大体class Foo {
public:
Foo(unique_ptr<FooEvaluator> evaluator)
: evaluator_(std::move(evaluator)),
common_state_() {}
void FooMethod() {
// Perform some common processing.
evaluator.DoSomething();
}
private:
unique_ptr<FooEvaluator> evaluator_;
Bar common_state_;
}
class FooEvaluator {
public:
virtual void DoSomething() = 0;
}
class FooEvaluatorImpl : public FooEvaluator {
public:
FooEvaluatorImpl(type1 arg) {...}
void DoSomething() override {...}
}
class FooEvaluatorImplVariant : public FooEvaluator {
public:
FooEvaluatorImplVariant(type2 arg) {...}
void DoSomething() override {...}
}
を:私はいくつかの共通の処理を行うのFooを持っているし、その後FooEvaluatorを使用しています。私はいくつかの異なるロジックを持つFooEvaluatorの実装をいくつか持っています。一般的なFoo処理は、それを複製しないようにするのには意味がありますが、それほど重要ではありません。
共有ロジックと評価ロジックの両方を含むモノリシックなFooを使用していた場合は、2つのオブジェクトを割り当てる必要があります。
FooからFooEvaluatorを継承し、Fooのプライベート仮想メソッドとしてDoSomething()
を追加することは、ぼんやりとした妥当な中間地です。これは継承の濫用のビットです(あなたはFooEvaluatorが "Foo"だとは言えませんが)、私の共有コードを取得し、倍精度メモリの割り当てを回避します。
どのような考えですか?まあ
はFooの評価者のほぼ同じ大きさのすべてはありますか?もしそうなら、私はそれらをstd :: variantまたはboost:variantにして、通常は仮想関数インタフェースであるものを実装するvisitor関数を持っています。 – RyanP
仮想継承をcrtpに置き換えることはできますか?つまり、コンパイル時にコンポジションを実行できますか?これは、タイプ消去を失うのと引き換えにunique_ptr、ヒープ割り当て、およびvtableを削除します(またはレベルを上げる)。 –
「構成」の意味が分かりません。あなたは例を挙げることができますか?私は構成がどのように複数の割り当てをもたらすか理解していません。 (おそらく私の無知だろうが) –