2016-12-01 67 views
5

我有一组实现相同的业务方法的类。由于性能原因,我计划使用CRTP而不是虚拟调度。但是我想把编码的便利性保留在一个带有继承和虚拟方法的接口上。使用CRTP与接口

可以让我的专用类同时从模板化的抽象类继承,它将使用CRTP来保存公共代码,并且还可以从纯虚拟类继承,以便我可以创建每种类型的实例,但具有我的客户端代码仅取决于接口?更好的是,如何在使用CRTP的同时为客户端代码提供单一接口,同时又有多个实现?

+0

那么,如果你打算重构你的代码由于性能原因,抽象方法是不是一个好主意......你使用CRTP以避免虚拟调度是为什么它的常见的替代名称是静态的多态性..但从语法点。当然没有人能够从这样阻止你,但恕我直言,你需要想清楚... –

+0

的公共方法不会在接口方面,只在专业化。 – ruipacheco

回答

5

肯定。您可以使用这样的方法,这是完全正确的:

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

    //... 
} 
+0

运行时成本是否与仅使用纯虚函数相同? – ruipacheco

+0

是的,因为模板根本没有运行时间开销。 – Smeeheey

+0

所以看看这个代码与仅使用纯虚函数相比,CRTP不会给我太多什么?我有同样的表现惩罚? – ruipacheco