接口的一个常见用途是从DLL或共享库导出接口。这使得可以通过选择在运行时加载哪个共享库来编写在多个版本的接口之间进行选择的程序。一个非常有用的用途是编写一个可以与多个语音引擎一起工作的程序。语音引擎库由应用程序根据用户首选项加载。
例如,假设您有以下界面。
struct ITTS
{
virtual bool Init() = 0;
virtual bool Shutdown() = 0;
virtual bool ReadyToSpeak() = 0;
virtual bool Speak(const char* str) = 0;
};
然后在每个DLL或共享库中都有一个导出函数GetTTS,它返回一个指向ITTS对象的指针。此函数通过返回指向从ITTS接口派生的对象的指针来工作。
我一直在研究CRTP及其作为此类接口的替代方案。例如,上述传统接口将使用CRTP实现如下。
template<class T>
struct ITTS
{
bool Init()
{
return static_cast<T*>(this)->Init_();
}
bool Shutdown()
{
return static_cast<T*>(this)->Shutdown_();
}
bool ReadyToSpeak()
{
return static_cast<T*>(this)->ReadyToSpeak_();
}
bool Speak(const char* str)
{
return static_cast<T*>(this)->Speak_(str);
}
};
问题在于,无法定义一个返回指向此类对象的指针的函数,以便应用程序可以在运行时选择接口的实现。