隐藏库用户的库依赖关系
Hiding library dependencies from library users
考虑我正在写一个静态库。让它有一个Foo
// mylib.h
#include <dependency_header_from_other_static_library.h>
class Foo {
// ...
private:
type_from_dependent_library x;
}
您可以看到此库(让它称为mylib
)取决于另一个库。它的编译很好。但是,当用户编译它的代码(使用Foo
并包含mylib.h
)并与我的lib链接时,汇编失败了,因为用户还需要将dependency_header_from_other_static_library.h
标头文件还编译代码。
我想对用户隐藏此依赖关系。如何完成?想到的一件事是PIMPL
成语。喜欢:
// mylib.h
#include <dependency_header_from_other_static_library.h>
class Foo {
// ...
private:
class FooImpl;
boost::shared_ptr<FooImpl> impl_;
}
// mylib_priv.h
class FooImpl {
// ...
private:
type_from_dependent_library x;
}
,但它要求我在FooImpl
中复制Foo
类的接口。而且,在我的情况下使用PIMPL
是过度的吗?
谢谢。
将标头与其他标头解耦时,您可能可以使用一些方法:
-
如果二手库对其声明其类型的方式有所保证,则您可能能够转发标题中所需的类型。当然,这仍然意味着您只能将这些类型称为标题中的指针或功能签名中,但这可能足够好。例如,如果二手库有望使用您需要使用的
class LibraryType
,则可以做类似的事情:// Foo.h class LibraryType; class Foo { // ... LibraryType* data; };
这可能会削减您的必要松弛,以便在不包括标头的情况下使用该类型,而无需跳过Pimpl方法。
-
如果图书馆没有向其声明它的声明方式提出承诺,则可以使用
void*
参考相应类型。当然,这意味着,每当您访问实施中的数据时,都需要将void*
投放到适当的类型。由于该类型在静态上是已知的,因此使用static_cast<LibraryType*>
非常好,即,由于演员阵容而没有开销,但仍然相对痛苦。 -
另一种选择当然是使用pimpl习惯。如果您键入任何合理的服务,它可能会大大更改接口,并且复制类本身和私人声明类型之间的接口不应大。另外,请注意,私有类型只是一个数据容器,即合理地将其作为
struct
,并且对其访问没有保护。唯一真正的问题是,您需要确保在调用破坏者的点上可见类型的定义。使用std::shared_ptr<T>(new T(/*...*))
为此安排。
有效地,所有三种方法都采用相同的操作,尽管技术略有不同:它们为您提供了一个不透明的手柄,该手柄可在标题文件中使用,其定义仅是实现的。这样,库的客户端就不需要包括相应的标头文件。但是,除非在构建库时解决符号,否则客户仍然需要访问二手库。
- C++GTKMM gui循环依赖关系
- 如何在头文件中声明类模板(由于循环依赖关系)
- 对在不同二进制文件中创建的对象文件的依赖关系
- 使用Bazel构建具有不同编译器/链接器选项的C/C++依赖关系
- OpenVINO - 推理库插件 libMKLDNNPlugin.so 无法解析依赖关系
- 模拟测试中类的依赖关系
- C++模板方法中的循环依赖关系
- 解析正交模块的依赖关系
- 如何在 Mac OS 上安装 boost-mpi 及其对 clang 的依赖关系?
- Wt::D bo 中的循环依赖关系
- 在包含窗口标头时难以解决循环依赖关系问题
- 当依赖关系和依赖关系都是多态时,在哪个继承级别存储依赖关系指针?
- 解决循环依赖关系 c++ 的想法
- C++循环依赖关系,未声明的标识符
- C++ 中的循环依赖关系问题
- 为什么包含需要进一步的依赖关系?
- 使用 cmake 获取外部依赖关系
- CMake 外部和内部静态库的循环依赖关系
- 在没有Xcode的macOS中开发具有依赖关系的应用程序
- "std::shared_ptr"循环依赖关系是如何导致问题的