如果我正在创建一个带有头文件的静态库,例如:
// Myfile.h
#include "SomeHeaderFile.h" // External library
Class MyClass
{
// My code
};
在我自己的项目中,我可以告诉编译器(在我的例子中,Visual Studio)在哪里查找SomeHeaderFile.h。但是,我不希望我的用户关注这一点 - 他们应该能够包含我的标题,而不必通知他们的编译器有关SomeHeaderFile.h的位置。
这种情况通常如何处理?
答案 0 :(得分:14)
这是一款经典的#34;编译防火墙"场景。有两个简单的解决方案:
从外部库转发声明您需要的任何类或函数。然后仅在您的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()) { };
答案 1 :(得分:4)
假设外部头文件包含以下内容:
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。