【问题标题】:Forward declaration of third party library第三方库的前向声明
【发布时间】:2021-12-05 06:49:30
【问题描述】:

我正在对第三方库的结构进行前向声明,因此我只能在我的 .cpp 文件中包含第三方标头。

我需要在 .hpp 中转发声明它们,然后在 .cpp 文件中,我需要让第三方标头在它们的实现中定义它们。

// X.hpp
namespace Y {
typedef struct A A;
typedef struct B B;
void (*f1)(A*);
void (*f2)(B*);

...
...

private: 
std::unique_ptr<A, decltype(f1)> a;
std::unique_ptr<B, decltype(f2)> b;

}
// X.cpp
#include <third_party> // contains definitons and declarations of real A, B

// this is not correct, but I need to say something like this.
struct Y::A: public A {};
struct Y::B: public B {};

namespace Y {
// using A, B in the implementation
}

【问题讨论】:

  • 我看到两个类型别名和两个神秘的派生类,但没有前向声明。为什么你认为你需要“这样的东西”?您希望“这样的事情”完成什么?
  • 为了避免 X.hpp 中的#include &lt;third_part&gt; 行。我只想将其包含在 .cpp 文件中。
  • 我认为您需要阅读更多关于前向声明的内容。您从未见过涉及typedef 和继承的示例。
  • 为什么不直接把第三方包起来?

标签: c++ struct forward-declaration


【解决方案1】:

您提供的信息有点有限,但假设您有一些第三方库在命名空间Y 中定义了一个结构A,您可以将其与std::unique_ptr 一起使用,如下所示,用于标题文件:

#include <memory>

namespace Y
{
  struct A; // the forward declaration
}

class MyClass
{
public:
  MyClass();
  ~MyClass();

private:
  std::unique_ptr<Y::A> a_;
};

还有.cpp 文件:

#include <third_party>

MyClass::MyClass() : a_{...}
{
}

MyClass::~MyClass() = default;

这可确保析构函数的代码在已知Y::A 的完整定义的上下文中编译。

【讨论】:

  • 替代方案:PIMPL 您自己的类,避免对您不拥有的代码进行(可能脆弱的)前向声明。
  • 但我它不是一个类,因为它是 C API,它是一个struct,它有一个自己的免费功能。因此,我需要为unique_ptr 提供一个删除器。这就是为什么我还想定义原始函数签名。
  • @quasimodo,C API 结构怎么能在命名空间中?您应该在命名空间Y 之外转发声明结构。
【解决方案2】:

您可以通过这种方式转发声明结构:

struct A;

这对您不起作用的原因是您使用的是unique_ptr,这需要一个定义(声明是不够的)。你可以改用shared_ptr

或者,您可以将私有变量封装到一个类中(在 cpp 文件中定义,在头文件中前向声明)并使用指向该类的指针而不是指向第三方结构的指针。

【讨论】:

猜你喜欢
  • 2013-04-12
  • 1970-01-01
  • 1970-01-01
  • 2017-10-18
  • 2018-03-11
  • 2023-04-01
  • 1970-01-01
  • 2015-10-20
相关资源
最近更新 更多