避免使用组合进行额外的堆分配(过度继承)
Avoiding extra heap allocations with composition (over inheritance)?
tl;dr-Composition似乎是适合我的情况的正确设计选择,但我希望避免为我一起组合的每个对象分配堆的开销。有什么好的技巧吗?
我有一个设置,看起来像:
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是Foo),但它会得到我的共享代码,并避免双重内存分配。
有什么想法吗?
您可以使用模板进行类似操作:
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_;
};
好吧,由于我不知道Foo的复杂性/细节,我建议将其作为内联函数,然后您可以从几个FooEvaluator实例中调用它,以便在执行细节之前完成常见的处理。
相关文章:
- 是否应该使用继承来减少内存消耗的实例的内存分配?
- 动态分配的属性和继承
- 创建一系列超类的指针,以分配继承的类
- 如何将从C 模板继承的类超载分配运算符
- 复制构造函数继承动态分配的数组
- 如何<base>从多个继承的类对象分配unique_ptr?
- 避免使用组合进行额外的堆分配(过度继承)
- 为什么GCC警告使用STD ::元组和虚拟继承来调用非平凡的动作分配运算符
- 超载分配运算符的继承
- 正确的语法,用于在C 中继承,并具有初始化列表和内存分配
- 自定义内存分配和多个继承类的解除分配
- 分配同一类时上层类和继承类之间的区别
- 继承下基类的OOPS内存分配
- 在堆栈上分配对象时发生C++继承错误
- 如何查找继承类的分配地址
- 尝试分配值时C++继承中断的代码
- 在实现中,继承是来自连续分配的多个层的数据成员
- C++ABC,继承和虚函数的分配,试图找出一个段错误等等
- 静态分配继承对象的数组
- 无法从继承的类分配指向方法的指针