这里的一些答案使得通过C+类听起来真的很可怕,但我想分享另一个观点。其他一些响应中提到的纯虚拟C+方法实际上比您想象的要干净。我已经围绕这个概念建立了一个完整的插件系统,它已经运行了很多年了。我有一个“PluginManager”类,它使用LoadLib()和GetProcAddress()动态地从指定的目录加载dll(以及Linux等效文件,以便跨平台执行)。
信不信由你,即使您做了一些奇怪的事情,比如在纯虚拟界面的末尾添加一个新函数,并尝试在没有新函数的情况下加载针对接口编译的dll,这种方法也是可以原谅的-它们会加载得很好。当然.。您必须检查版本号,以确保您的可执行文件只对实现该函数的较新的dll调用新函数。但好消息是:它有效!因此,在某种程度上,你有一个粗糙的方法来逐步发展你的界面。
关于纯虚拟接口的另一件很酷的事情-你可以继承你想要的多少接口,你永远不会遇到钻石问题!
我想说,这种方法最大的缺点是,您必须非常小心您作为参数传递的类型。不首先用纯虚拟接口包装类或STL对象。没有结构(没有经过实用主义包装巫毒)。只是原始类型和指向其他接口的指针。此外,您不能超载函数,这是一个不便,但不是一个显示停止。
好消息是,使用少量代码行,您可以创建可重用的泛型类和接口来包装STL字符串、向量和其他容器类。或者,您可以将函数添加到您的接口中,如GetCount()和GetVal(N),以便让用户遍历列表。
人们为我们构建插件很容易。他们不必是ABI边界方面的专家-他们只是继承他们感兴趣的接口,对他们支持的函数进行编码,并为不支持的函数返回false。
据我所知,制造所有这些工作的技术并不是基于任何标准。据我所知,微软决定这样做他们的虚拟表,这样他们就可以制作COM,而其他编译器编写人员也决定效仿。这包括GCC、Intel、Borland和其他大多数主要的C+编译器。如果您计划使用一个晦涩的嵌入式编译器,那么这种方法可能不会适用于您。理论上说,任何一家编译器公司都可以随时改变他们的虚拟表并打破它们,但是考虑到多年来编写的大量代码依赖于这种技术,如果任何主要的参与者决定打破排名,我会感到非常惊讶。
所以这个故事的寓意是.。除了一些极端的情况外,您需要一个负责接口的人,他可以确保ABI边界与原始类型保持干净,并避免重载。如果您同意这一规定,那么我就不怕在编译器之间共享DLL/SOS中类的接口。直接共享类=麻烦,但共享纯虚拟接口并不那么糟糕。