代码之家  ›  专栏  ›  技术社区  ›  ssube

隐藏标题中的类类型

  •  2
  • ssube  · 技术社区  · 15 年前

    我不确定这是否可能,但下面是:

    我有一个图书馆,它的界面至多是复杂的。不幸的是,它不仅是第三方库(而且太大了,无法重写),我还使用了一些其他依赖它的库。所以这个接口必须保持原样。

    为了解决这个问题,我尝试从本质上包装接口,并将所有依赖项的接口捆绑到更少、更逻辑的类中。这部分进展顺利,效果很好。大多数包装器类都包含指向原始类之一的对象的指针。像这样:

    class Node
    {
    public:
        String GetName()
        {
            return this->llNode->getNodeName();
        }
    
    private:
        OverlyComplicatedNodeClass * llNode; // low-level node
    };
    

    我唯一的问题是第二点。除了简化接口,我还想删除针对原始头/库的链接需求。

    这是第一个困难。如何包装类,使其不需要包含原始头?包装器将被构建为一个共享库(dll/so),如果这样做更简单的话。

    原始类是指针,不用于任何导出函数(尽管它们在一些构造函数中使用)。

    我有一些想法,包括预处理器之类的:

    #ifdef ACCESSLOWLEVEL
    #    define LLPtr(n) n *
    #else
    #    define LLPtr(n) void *
    #endif
    

    这是丑陋的,充其量。它基本上满足了我的需要,但我更愿意一个真正的解决方案,那种混乱。

    某种指针类型的魔力会起作用,直到我遇到一些使用共享指针的函数(某种自定义的 SharedPtr<> 类提供引用计数),更糟的是,一些特定于类的共享指针派生自 SharedPtr 类( NodePtr 例如。

    是否有可能以这样一种方式包装原始库,即只需要包含我的头,以便链接到我的动态库? 不需要链接到原始库或从中调用函数,只需要我的。我遇到的唯一问题是使用的类型/类。

    这个问题可能不太清楚。如果有帮助的话,我可以尝试清理它并添加更多的代码示例。我并不担心任何性能开销或这种方法的任何内容,只是想让它首先工作(过早的优化等等)。

    2 回复  |  直到 15 年前
        1
  •  4
  •   John Dibling    15 年前

    使用 Pimpl (指向实现的指针)习惯用法。如上所述, OverlyComplicatedNodeClass 对于您的库的用户来说是一个实现细节。他们不必知道这个类的结构,甚至它的名称。

    当您使用pimpl习惯用法时,您将替换 过度复杂的节点类 类中的指针,指针指向 void . 只有你图书馆的作者需要知道 void* 实际上是 OverlyComplicatedNodeClass* . 所以你的类声明变成:

    class Node
    {
    public:
        String GetName();
    
    private:
        void * impl; 
    };
    

    在库的实现中,初始化 impl 使用指向实际工作类的指针:

    MyoLIIB CPP

    Node::Node()
    : impl(new OverlyComplicatedNodeClass)
    {
    // ...
    };
    

    …你图书馆的用户永远不需要知道 过度复杂的节点类 存在。

    这种方法有一个潜在的缺点。所有使用 IMPL 类必须在库中实现。如果可以内联,则无。这是否是一个缺点在很大程度上取决于你的申请,所以你自己来判断。

    就你的班级而言,你确实 GetName() 的实现。必须将其移动到库中,就像使用 IMPL 指针。

        2
  •  0
  •   Karl Bielefeldt    15 年前

    本质上,每次使用都需要一组单独的头文件。一个用于构建DLL,另一个只使用导出的接口,而不提及所有封装的对象。您的示例如下:

    class Node
    {
    public:
        String GetName();
    };
    

    如果您不介意混乱,可以使用预处理器语句在同一物理文件中获取两个版本。