避免使用组合(超过继承)的额外堆分配?

时间:2017-01-12 16:53:55

标签: c++ inheritance

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。

我能想到的一个模糊合理的中间立场是让FooEvaluator从Foo继承,并在Foo上添加DoSomething()作为私有虚拟方法。它有点滥用继承imo(你不能说FooEvaluator&#34;是&#34; Foo),但它会获得我的共享代码并避免双内存分配。 / p>

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

您可以使用模板执行类似的操作:

template <typename Evaluator>
class Foo {
public:
    template <typename ... Ts>
    Foo(Ts&&... args) 
    : evaluator_(std::forward<Ts>(args)...),
      common_state_()
    {}

    void FooMethod() {
      // Perform some common processing.
      evaluator.DoSomething();
    }
private:
    Evaluator evaluator_;
    Bar common_state_;
};

答案 1 :(得分:-1)

好吧,因为我不知道Foo的复杂性/细节,我建议将其设为内联函数,然后你可以从几个FooEvaluator实例中调用它,按顺序在完成细节之前完成共同处理。