提问者:小点点

如何避免#include对外部库的依赖


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

// Myfile.h

#include "SomeHeaderFile.h" // External library

Class MyClass
{

// My code

};

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

这类情况通常如何处理?


共2个答案

匿名用户

这是一个经典的“编译防火墙”场景。有两个简单的解决方案可以做:

>

  • forward-从外部库声明任何需要的类或函数。然后仅在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()) { };
    

  • 匿名用户

    假设外部头文件包含以下内容:

    外部.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。