我有一組實現相同的業務方法的類。由於性能原因,我計劃使用CRTP而不是虛擬調度。但是我想把編碼的便利性保留在一個帶有繼承和虛擬方法的接口上。使用CRTP與接口
可以讓我的專用類同時從模板化的抽象類繼承,它將使用CRTP來保存公共代碼,並且還可以從純虛擬類繼承,以便我可以創建每種類型的實例,但具有我的客戶端代碼僅取決於接口?更好的是,如何在使用CRTP的同時爲客戶端代碼提供單一接口,同時又有多個實現?
我有一組實現相同的業務方法的類。由於性能原因,我計劃使用CRTP而不是虛擬調度。但是我想把編碼的便利性保留在一個帶有繼承和虛擬方法的接口上。使用CRTP與接口
可以讓我的專用類同時從模板化的抽象類繼承,它將使用CRTP來保存公共代碼,並且還可以從純虛擬類繼承,以便我可以創建每種類型的實例,但具有我的客戶端代碼僅取決於接口?更好的是,如何在使用CRTP的同時爲客戶端代碼提供單一接口,同時又有多個實現?
肯定。您可以使用這樣的方法,這是完全正確的:
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();
}
//...
}
運行時成本是否與僅使用純虛函數相同? – ruipacheco
是的,因爲模板根本沒有運行時間開銷。 – Smeeheey
所以看看這個代碼與僅使用純虛函數相比,CRTP不會給我太多什麼?我有同樣的表現懲罰? – ruipacheco
那麼,如果你打算重構你的代碼由於性能原因,抽象方法是不是一個好主意......你使用CRTP以避免虛擬調度是爲什麼它的常見的替代名稱是靜態的多態性..但從語法點。當然沒有人能夠從這樣阻止你,但恕我直言,你需要想清楚... –
的公共方法不會在接口方面,只在專業化。 – ruipacheco