我有一组实现相同的业务方法的类。由于性能原因,我计划使用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