C++派生类阵列

问题描述 投票:0回答:1

我目前正在做一个问题,需要把几个概念绑在一起。我首先定义了一个类 "Base",它使用CRTP(见 https:/www.modernescpp.comindex.phpc-is-still-lazy)来实现运行时的多态性。然后,我定义了两个Base的派生类,称为 "Derived1 "和 "Derived2",作为如何使用这种多态性的例子。在引入另一个概念 "Agent "之前,这一切都能如期进行。Agent将有各种状态变量以及指向其对应的派生类的指针。我们的目标是拥有许多这样的Agent,它们可能有不同的派生类。我想把所有这些对象都存储在 "Agent "中。一样 数组。然而,这似乎定义得不清楚,因为每个Agent不一定是相同的类型。

我曾考虑过用一个枚举来替换Agent定义中的Base指针,然后通过映射来检索相应的Derived类。这感觉不是特别优雅。我也怀疑有一种方法可以用虚拟基类来实现,但出于性能考虑,我试图避免使用vtables。

任何关于我第一次提出的实现的潜在解决方案的意见或建议,或为实现预期目标而进行的结构调整,都将非常感激。谢谢您

#include <iostream>

template <typename T>
class Base {
public:
    void func() {
        static_cast<T*>(this)->implementation();
    }
};

struct Derived1: Base<Derived1> {
    void implementation() {
        std::cout << "calling derived1 implementation of func" << std::endl;
    }
};

struct Derived2: Base<Derived2> {
    void implementation() {
        std::cout << "calling derived2 implementation of func" << std::endl;
    }
};

class Agent {
    public:
        // various member variables to keep state
        Base *base;    // NOTE: this is where I am unsure
}

int main() {
    Agent agent_array[2];    // NOTE: this is ill-defined since I don't pass template args
    Derived1 d1;
    Derived2 d2;

}

c++ templates derived-class
1个回答
3
投票

CRTP用于静态多态。

如果你需要运行时多态性,有很多方法可以实现。具有经典OOP继承的虚拟成员函数只是一种方式。

从优秀的"拥抱无范式编程!",我们可以看到其他的方法,以及它们之间的比较。

Performance between multiple ways of C++ runtime polymorphism

如果你只使用了已知数量的派生类,我建议你使用一个... variant-样的数据结构。它有静态存储,所以没有不必要的堆分配,所有的存储都是从你这里抽象出来的。

如果你需要导出 func() 明确地实现,那么你就需要使用多态值(幻灯片上的 "类型擦除")。参见Sean Parent的经典演讲"更好的代码。运行时多态性". 注意它也使用了vtables。要抽象vtables,你需要使用一个更复杂的struture,就像Sy Brand在他们的"动态多态与元类和代码注入。"的说法。

另外,注意到 "OO "的性能并没有那么差。在现代计算机中,虚拟成员函数并不那么昂贵,通常只有高性能的低延迟代码才会对这种类型的优化深表关心。

© www.soinside.com 2019 - 2024. All rights reserved.