如何避免#crude依赖外部库

How to avoid #include dependency to external library

本文关键字:外部 依赖 #crude 何避免      更新时间:2023-10-16

如果我使用以下标题文件创建静态库:

// Myfile.h
#include "SomeHeaderFile.h" // External library
Class MyClass
{
// My code
};

在我自己的项目中,我可以告诉编译器(在我的情况下,Visual Studio)在哪里寻找SomeheaderFile.H。但是,我不希望我的用户关心这一点 - 他们应该能够包含我的标题,而不必通知他们的编译器有关Someheaderfile.H。H。

的位置。

这种情况通常如何处理?

这是经典的"编译防火墙"方案。有两个简单的解决方案要做:

  1. 向前销售您需要从外部库中需要的任何类或功能。然后仅在CPP文件中包含外部库的标头文件(当您实际需要使用您在标题中转发的类或功能时)。

  2. 使用PIMPL IDIOM(或Cheshire Cat),您可以将您声明并仅私下定义(在CPP文件中)转发为"实现"类。您使用该私有类将所有与外图的代码放置在公共类中避免具有任何痕迹(在标题文件中声明的痕迹)。

这是使用第一个选项的示例:

#ifndef MY_LIB_MY_HEADER_H
#define MY_LIB_MY_HEADER_H
class some_external_class;  // forward-declare external dependency.
class my_class {
  public:
    // ...
    void someFunction(some_external_class& aRef);  // declare members using the forward-declared incomplete type.
};
#endif
// in the cpp file:
#include "my_header.h"
#include "some_external_header.h"
void my_class::someFunction(some_external_class& aRef) {
  // here, you can use all that you want from some_external_class.
};

这是选项2的示例:

#ifndef MY_LIB_MY_HEADER_H
#define MY_LIB_MY_HEADER_H
class my_class_impl;  // forward-declare private "implementation" class.
class my_class {
  private:
    std::unique_ptr<my_class_impl> pimpl; // a vanishing facade...
  public:
    // ...
};
#endif
// in the cpp file:
#include "my_header.h"
#include "some_external_header.h"
class my_class_impl {
  private:
    some_external_class obj;
    // ...
  public:
    // some functions ... 
};
my_class::my_class() : pimpl(new my_class_impl()) { };

说外部标头文件包含以下内容:

外部.h

class foo
{
public:
   foo();
};

在您的库中,您使用foo:

myheader.h:

#include "external.h"
class bar
{
...
private:
   foo* _x;
};

要使您的代码编译,您所要做的就是转发声明foo类(之后您可以删除包含):

class foo;
class bar
{
...
private:
   foo* _x;
};

您必须在源文件中包含external.h。