Использование CRTP с интерфейсом


У меня есть набор классов, реализующих одни и те же бизнес-методы. Я планирую использовать CRTP вместо виртуальной диспетчеризации из соображений производительности. Но я хотел бы сохранить удобство кодирования для единого интерфейса, который поставляется с наследованием и виртуальными методами.

Нормально ли, чтобы мои специализированные классы наследовались как от шаблонного абстрактного класса, который будет использовать CRTP для хранения общего кода, так и от чистого виртуального класса, чтобы я мог создавать экземпляры каждого типа, но зависит ли мой клиентский код только от интерфейса? Еще лучше, как я могу использовать CRTP для предоставления одного интерфейса клиентскому коду, имея несколько реализаций?

1 5

1 ответ:

Конечно. Вы можете использовать такой подход, который совершенно справедлив:

class Interface 
{
public:
    virtual void doSomething() = 0;
    //...
};

template<typename T>
class GeneralImpl : public Interface
{
public:

    void doSomething() override
    {
        auto someDetail = T::somethingStatic();
        //...
        static_cast<T*>(this)->someMember();
        //...
    }
}

class SpecificImpl : public GeneralImpl<SpecificImpl>
{
public:
    static int somethingStatic()
    {
        //...
    }

    void someMember()
    {
        //...
    }
};

int main()
{
    std::vector<Interface*> vec;
    SpecificImpl instance;

    //...

    vec.push_back(&instance);

    //...

    for(auto* inst : vec) {
        inst->doSomething();
    }

    //...
}