【发布时间】:2012-12-11 14:40:42
【问题描述】:
我有一个类Foo,我不直接实现它,而是包装外部库(例如FooXternal1 或FooXternal2)
我见过的一种方法是使用预处理器指令作为
#include "config.h"
#include "foo.h"
#ifdef _FOOXTERNAL1_WRAPPER_
//implementation of class Foo using FooXternal1
#endif
#ifdef _FOOXTERNAL2_WRAPPER_
//implementation of class Foo using FooXternal2
#endif
config.h 用于定义这些预处理器标志(_FOOXTERNAL1_WRAPPER_ 和 _FOOEXTERNAL2_WRAPPER_)。
我的印象是 C++ 程序员社区不赞成这种做法,因为它使用预处理器指令,难以调试等。此外,它不允许两种实现并行存在。
我考虑过将Foo 设为基类并从它继承以允许两个实现并行存在。但是我遇到了两个问题:
- 纯虚函数:
cannot instatiate an object of type 'Foo',使用时需要用到。 - 虚拟函数存在运行没有(正确)实现的对象的风险。
我错过了什么吗?有没有更清洁的方法来做到这一点?
编辑: 总而言之,有 3(.5?!) 种包装方式 - 2(.5) 由 icepack 提供,最后一种由 Sergey 提供 1-使用工厂方法 2-使用预处理器指令 2.5- 使用 makefile 或 IDE 有效地完成预处理器指令的工作 3.5- 使用 Sergey 建议的模板
我正在开发一个资源有限的嵌入式系统,我决定使用template<enum = default_library>,具有模板专业化功能。便于后期用户理解;至少我是这么认为的
【问题讨论】:
-
只要您链接两个外部库,提供一个虚拟类和两个具体类就是一个很好的解决方案——尤其是在运行时您可以确定应该使用哪个库时。如果您没有在两个库中链接(或者如果它们有名称空间冲突禁止它),那么这将不起作用。 #define / #ifdef 并不总是友好的,但它有时是最好的解决方案。
-
要添加到 mah,如果您使用包装器 Foo,只需将任何必须被覆盖的函数声明为纯虚拟函数。一旦您尝试实例化具体子类,编译器将强制您在具体子类中提供实现。
-
正是我想要的,但是我不能实例化 Foo,因为它是抽象类。我错过了什么吗?
-
好吧,听起来您想为抽象基础提供一个工厂,以便在运行时动态选择 Foo 的哪个实现?
-
@mah,没有命名空间冲突,我可以链接两个库。我需要实例化 Foo 虽然
标签: c++ wrapper abstraction