Подтвердить что ты не робот

Как избежать зависимости #include от внешней библиотеки

Если я создаю статическую библиотеку с заголовочным файлом, например:

// Myfile.h

#include "SomeHeaderFile.h" // External library

Class MyClass
{

// My code

};

В моем собственном проекте я могу рассказать компилятору (в моем случае, Visual Studio), где искать SomeHeaderFile.h. Тем не менее, я не хочу, чтобы мои пользователи беспокоились об этом - они должны иметь возможность включать мой заголовок, не сообщая своему компилятору о местонахождении SomeHeaderFile.h.

Как обычно обрабатывается этот тип ситуации?

4b9b3361

Ответ 1

Это классический сценарий "компиляции брандмауэра". Существует два простых решения:

  • Переслать - объявить любые классы или функции, которые вам нужны из внешней библиотеки. А затем включите заголовочный файл внешней библиотеки только в вашем файле cpp (когда вам действительно нужно использовать классы или функции, которые вы переадресовываете в своем заголовке).

  • Используйте идиому 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.
};

Вот пример варианта 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()) { };

Ответ 2

Скажите, что внешний заголовочный файл содержит следующее:

external.h

class foo
{
public:
   foo();
};

И в вашей библиотеке вы используете foo:

myheader.h:

#include "external.h"

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

Чтобы получить код для компиляции, все, что вам нужно сделать, это переслать объявление класса foo (после этого вы можете удалить include):

class foo;

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

Затем вам нужно будет включить external.h в исходный файл.