您可以使用CRTP和以接口作为参数的功能吗?

时间:2012-02-16 16:52:58

标签: c++ templates crtp

在C ++中,纯虚拟类通常用于运行时多态性。

所以你有:

class IInterfaceA
{
    virtual void DoFoo() = 0;
};

派生类如:

class CFancyObject : public IInterfaceA
{
...

然后可以在以下函数中使用:

void Foo(IInterfaceA &interface);

但这是运行时情况,如果在编译时已知对象,我们可以通过使用CRTP做得更好:

template<class T> class IInterfaceA
{
public:
    void DoFoo()
    {    
        static_cast<T*>(this)->CallDerivedFunction();
    }
}

class CFancyObject : public IInterfaceA<CFancyObject>
{
    ...
}

是否可以在以IInterface作为参数的函数中使用基于CRTP的派生类?

void Foo(IInterfaceA<?> &interface);

2 个答案:

答案 0 :(得分:2)

接口用于将类的API与其实现分离。通过引入模板参数,您将实现紧密地耦合到接口,从而破坏了整个目的。 CRTP旨在解决一系列不同的问题。

如果使界面模板化,则将其作为参数的函数也必须进行模板化。完成后,使用接口类和使用实现类没有区别。

template<class T>
void Foo(IInterfaceA<T> &interface) { interface.DoFoo(); }

相同并且没有任何优势
template<class T>
void Foo(T &object) { object.DoFoo(); }

答案 1 :(得分:0)

你不能这样做:

template<class T> class IInterfaceA 
{
public:
    template<class T2>
    void DoFoo(IInterfaceA<T2> &interface)
    {    
        static_cast<T*>(this)->CallDerivedFunction(interface);
    }
}

class CFancyObject : public IInterfaceA<CFancyObject>
{
    template<class T2>
    CallDerivedFunction(IInterfaceA<T2> &interface) {...}
}