Ответ 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()) { };