c++ 库的公共头文件中应该包含哪些内容?

Posted

技术标签:

【中文标题】c++ 库的公共头文件中应该包含哪些内容?【英文标题】:What should be included in the public header files of a c++ library? 【发布时间】:2018-11-04 18:02:50 【问题描述】:

我正在构建一个小型 c++ 共享库,它有一个像这样的类(在头文件上)

class Foo 
  ...
  std::optional<some_type> _bar;
  ...
;

由于std::optional是C++17,任何包含上述文件的人都需要编译C++17。但是,_bar 不是库的公共接口的一部分。 _bar 仅在实现中使用。所以,我的问题是,我怎样才能公开一个只公开公共方法但维护我的实现 C++17 的头文件?我希望我不需要强迫图书馆的用户使用 C++17,对吧?

我也在使用 CMake 来生成构建文件,如果这很重要的话。

【问题讨论】:

由于 C++ 没有指定 ABI,您的客户可能需要使用完全相同的编译器。 PIMPL 是您正在寻找的习语 :) 但是您的库必须使用与用户代码相同的编译器进行编译,所以这有点争议——除非您从 C++ 接口转发所有内容通过稳定的 C ABI 到 C++ 中的底层静态链接 C++ 运行时实现,然后可以使用不同的编译器进行编译。唯一与 C++-ABI 兼容的编译器对,其中一个是 C++17,另一个不是,是 VC++2015 和 2017。对于任何其他编译器组合,您必须使用稳定的 C ABI .不过,您也可以拥有一个仅包含标头的库! 您也可以链接到 C++ API,但它必须是可靠的(即确保在一个库中分配的任何内容在 Windows 上的该库中被释放,而在 Linux 上,您需要发布最高如果您使用的是 libstdc++ 版本)。 【参考方案1】:

由于您正在构建共享库:

您可以定义一个基类BaseFoo 与所有接口(纯虚拟)。

然后从BaseFoo派生你的Foo,并添加一个工厂函数:getFoo

之后,将您的Foo 实现为动态库,并导出工厂函数(__attribute__ ((visibility ("default")))

现在,将 BaseFoo 标头与动态库一起发送(确保客户端使用相同版本的 libstdc++)。

【讨论】:

以上是关于c++ 库的公共头文件中应该包含哪些内容?的主要内容,如果未能解决你的问题,请参考以下文章

C++ STL 包含哪些头文件?

VS2019 C++动态链接库的创建使用

头文件带和不带.h的区别

C++库的头文件到底如何包含的?

c语言和c++头文件在哪些地方有所不同

linux下编写c++,include的那些头文件在啥地方