我正在设计一个 C++ 静态库。 我想让这些类通用/可配置,以便它们可以支持多种数据类型(并且我不想在我的库中编写任何数据类型特定的代码)。 所以我对类(class)进行了模板化。
但是由于我当前使用的编译器不支持 C++“导出”模板功能,因此我被迫在头文件中提供类的实现。 我不想向将使用我的库的客户端代码公开我的类的实现细节。
您能为我提供一些解决上述问题的设计方案吗?
最佳答案
在模板出现之前,必须使用运行时多态性来编写与类型无关的 C++ 代码。但也可以使用模板,将这两种技术结合起来。
例如,假设您想要存储任何类型的值以供以后检索。如果没有模板,您必须这样做:
struct PrintableThing
{
// declare abstract operations needed on the type
virtual void print(std::ostream &os) = 0;
// polymorphic base class needs virtual destructor
virtual ~PrintableThing() {}
};
class PrintableContainer
{
PrintableThing *printableThing;
public:
// various other secret stuff
void store(PrintableThing *p);
};
该库的用户必须编写自己的 PrintableThing
的派生版本手动包装自己的数据并实现 print
其上的功能。
但是您可以在这样的系统周围包装基于模板的层:
template <T>
struct PrintableType : PrintableThing
{
T instance;
virtual void print(std::ostream &os)
{ os << instance; }
PrintableType(const T &i)
: instance(i) {}
};
并且还在库的 header 中添加一个方法,在 PrintableContainer
的声明中类:
template <class T>
void store(const T &p)
{
store(new PrintableType(p));
}
这充当模板和运行时多态性之间的桥梁,编译时绑定(bind)到 <<
实现 print
的运算符(operator),以及复制构造函数(当然也转发到嵌套实例的析构函数)。
这样,你就可以编写一个完全基于运行时多态性的库,其实现可以隐藏在库的源代码中,但添加一点模板“糖”以方便使用.
这是否值得麻烦取决于您的需求。它具有纯粹的技术优势,因为运行时多态性有时正是您所需要的。不利的一面是,您无疑会降低编译器有效内联的能力。从好的方面来说,您的编译时间和二进制代码膨胀可能会减少。
示例为std::tr1::function
和boost::any
,它有一个非常干净、现代的基于 C++ 模板的前端,但在幕后作为运行时多态容器工作。
关于c++ - 设计 C++ 库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1147588/