2016-12-01 66 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