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>
有什么想法吗?
答案 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实例中调用它,按顺序在完成细节之前完成共同处理。