Search code examples
c++c++11inheritancecrtppure-virtual

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?


Solution

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