Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using CRTP with an interface

I have a set of classes that implement the same business methods. I plan to use CRTP instead of virtual dispatch due to performance reasons. But I'd like to keep the convenience of coding to a single interface that comes with inheritance and virtual methods.

Is it ok to have my specialised classes inherit from both a templated abstract class that would use CRTP to hold common code, and also inherit from a pure virtual class so I can then create instances of each type but have my client code depend only on the interface? Even better, how can I use CRTP to provide a single interface to client code while having multiple implementations?

like image 934
ruipacheco Avatar asked Dec 01 '16 11:12

ruipacheco


1 Answers

Sure. You can use an approach like this, which is perfectly valid:

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();
    }

    //...
}
like image 107
Smeeheey Avatar answered Sep 23 '22 19:09

Smeeheey