首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >设计C++库

设计C++库
EN

Stack Overflow用户
提问于 2009-07-18 13:54:48
回答 5查看 840关注 0票数 2

我正在设计一个C++静态库。我想让这些类成为泛型/可配置类,这样它们就可以支持许多数据类型(并且我不想在我的库中编写任何特定于数据类型的代码)。所以我已经模板化了这些类。

但是由于我目前使用的编译器不支持C++“导出”模板特性,所以我不得不在头文件中提供类的实现。我不想将我的类的实现细节暴露给将要使用我的库的客户端代码。

您能为我提供一些解决上述问题的设计方案吗?

EN

回答 5

Stack Overflow用户

发布于 2009-07-18 15:11:07

在模板出现之前,必须使用运行时多态性编写与类型无关的C++代码。但是对于模板,您也可以将这两种技术结合起来。

例如,假设您想要存储任何类型的值,以便以后检索。如果没有模板,您将不得不这样做:

代码语言:javascript
运行
复制
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函数。

但您可以在这样的系统周围包装一个基于模板的层:

代码语言:javascript
运行
复制
template <T>
struct PrintableType : PrintableThing
{
    T instance;

    virtual void print(std::ostream &os)
        { os << instance; }

    PrintableType(const T &i)
        : instance(i) {}
};

并在库的头部、PrintableContainer类的声明中添加一个方法:

代码语言:javascript
运行
复制
template <class T>
void store(const T &p)
{
    store(new PrintableType(p));
}

这充当了模板和运行时多态性之间的桥梁,编译时绑定到实现print<<操作符,也绑定到复制构造函数(当然也转发到嵌套实例的析构函数)。

通过这种方式,您可以完全基于运行时多态性编写一个库,其实现能够隐藏在库的源代码中,但需要添加一点模板“糖”以方便使用。

这是否值得麻烦,将取决于您的需求。它有一个纯粹的技术优势,即运行时多态性本身就是您所需要的。不利的一面是,你无疑会降低编译器有效内联的能力。从好的方面来说,你的编译时间和二进制代码膨胀可能会下降。

例如std::tr1::functionboost::any,它们有一个非常干净、现代的基于C++模板的前端,但在后台作为运行时多态容器工作。

票数 3
EN

Stack Overflow用户

发布于 2009-07-18 16:35:25

我有个消息要告诉你,伙计。即使使用export,您仍然必须发布所有模板代码-- export使您不必将定义放在头文件中。你完全被卡住了。您可以使用的唯一技术是将一些非模板函数拆分出来,并将它们放入不同的类中。但这很难看,而且通常涉及void*、placement newdelete。这就是野兽的本性。

票数 1
EN

Stack Overflow用户

发布于 2009-07-18 14:00:29

你可以尝试混淆你的代码--但是除了在头文件中包含模板代码之外,你在C++03中几乎别无选择。

Vandevoorde在他的书中描述了另一种技术:显式实例化-但这需要显式实例化所有可能的有用组合。

但要对此主题进行最全面的回顾,请阅读C++模板:完整指南中的第6章。

编辑(回应您的评论):在不使用模板的情况下编写泛型代码有两种选择:

1)预处理器-仍需要头文件

2)使用void* - yuk -非常不安全

所以不,我不建议不使用模板来解决专门设计的问题(尽管有一些缺陷)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1147588

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档