如何避免#include依赖于外部库

JBe*_*ley 15 c++ dependencies header-files static-libraries

如果我正在创建一个带有头文件的静态库,例如:

// Myfile.h

#include "SomeHeaderFile.h" // External library

Class MyClass
{

// My code

};
Run Code Online (Sandbox Code Playgroud)

在我自己的项目中,我可以告诉编译器(在我的情况下,Visual Studio)在哪里查找SomeHeaderFile.h.但是,我不希望我的用户关注这一点 - 他们应该能够包含我的头,而不必通知他们的编译器有关SomeHeaderFile.h的位置.

这种情况通常如何处理?

Mik*_*son 15

这是一个经典的"编译防火墙"场景.有两个简单的解决方案:

  1. 从外部库转发声明您需要的任何类或函数.然后只在您的cpp文件中包含外部库的头文件(当您实际需要使用在标头中转发声明的类或函数时).

  2. 使用PImpl惯用语(或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.
};
Run Code Online (Sandbox Code Playgroud)

以下是选项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()) { };
Run Code Online (Sandbox Code Playgroud)