库设计:隐藏依赖项 [英] Library design: Hiding dependencies

查看:113
本文介绍了库设计:隐藏依赖项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构建一个内部使用第三方库的库,但是我不想将此库和第三方库公开给我的库用户.这样,在构建静态库时,用户将只需要我的标头和已编译的库.

I'm attempting to build a library that uses a third-party library internally, but I do not want to expose and of this third-party library to the user of my library. This way, when the static library is built, the user will only need my header and the compiled library.

如何处理在第3方库中定义的班级定义中的私人成员?

How do I deal with private members in my class definitions that are defined in the 3rd party library?

例如. .

#include "ThirdPartyLib.h"
class DummyClass
{
    TypeFromThirdParty tftp;

public:
    bool checkStuff(const float) const;
};

实现:

#include "ThirdPartyLib.h"
#include "dummy.h"    
bool DummyClass::checkStuff(const float t)
{
    return tftp.isOk(t);
}

有问题的部分是标题中的#include "ThirdPartyLib.h",因为我的图书馆的用户将比我的图书馆需要更多的东西.

The offending portion is the #include "ThirdPartyLib.h" in the header, as then the user of my library will need more than my library.

解决此问题的一种方法可能是预先声明标头中使用的所有第三方类型,然后将值类型替换为引用,但是我想知道是否还有另一种方法或设计被我完全忽略了? /p>

One way of getting around this might be to forward declare all third party types used in the header and then replace the value types with references, but I'm wondering if there is another method or design that I am completely overlooking?

推荐答案

私有实现类"或"pimpl"成语是一种方法.这样一来,所有对第三方库的提及(以及其他实现细节)都不会包含在标头中,这是以额外的间接级别为代价的:

The "private implementation class" or "pimpl" idiom is one approach. This keeps all mention of the third-party library (and other implementation details) out of the header, at the cost of an extra level of indirection:

// header
#include <memory>

class DummyClass {
public:
    DummyClass();
    ~DummyClass();
    bool checkStuff(float t);

private:
    struct Impl;
    std::unique_ptr<Impl> impl;
};

// source
#include "DummyClass.h"
#include "ThirdPartyLib.h"

struct DummyClass::Impl {
    TypeFromThirdParty tftp;
};

DummyClass::DummyClass() : impl(new Impl) {}

// This must be defined here, since ~unique_ptr requires Impl to be complete
DummyClass::~DummyClass() {}

bool DummyClass::checkStuff(float t) {return impl->tftp.isOk(t);}

另一种方法是定义抽象接口,并通过工厂创建具体的实现类.同样,这会从标头中删除所有实现细节,但要付出额外的间接费用:

Another approach is to define an abstract interface, and a factory to create the concrete implementation class. Again, this removes all implementation details from the header, at the cost of an extra indirection:

// header
#include <memory>

struct DummyInterface {
    virtual ~DummyInterface() {}
    virtual bool checkStuff(float t) = 0;

    static std::unique_ptr<DummyInterface> create();
};

// source
#include "DummyClass.h"
#include "ThirdPartyLib.h"

struct DummyClass : DummyInterface {
    TypeFromThirdParty tftp;
    bool checkStuff(float t) {return tftp.isOk(t);}
};

std::unique_ptr<DummyInterface> DummyInterface::create() {
    return std::unique_ptr<DummyInterface>(new DummyClass);
}

这篇关于库设计:隐藏依赖项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆