2010-02-09 3 views
4

C++로 작성한 정적 라이브러리가 있습니다. 필자는 이것을 여러 헤더와 소스 파일로 분리했다. 라이브러리의 클라이언트가 하나의 헤더 파일에 필요할 수있는 모든 헤더를 포함시키는 것이 더 좋은지 궁금합니다. 그 헤더 파일은 소스 코드에 포함 할 수 있거나 필요로하는 헤더 만 포함 할 수 있습니다. 코드가 불필요하게 비대해질 수 있습니까? 사용되지 않는 클래스 나 함수가 여전히 제품에 컴파일되는지는 확실하지 않았습니다.하나의 헤더를 사용하여 모든 정적 라이브러리 헤더를 포함해야합니까?

도움 주셔서 감사합니다.

답변

1

일반적으로 최종 실행 파일을 링크 할 때 실제로 프로그램에서 사용되는 기호와 함수 만 통합됩니다. 당신은 당신이 사용하는 것에 대해서만 지불합니다. 최소한 그것이 GCC 툴체인이 나를 위해 어떻게 작동하는지 보입니다. 나는 모든 툴체인을 말할 수 없다.

클라이언트가 항상 동일한 헤더 파일 세트를 포함해야한다면 편리함을 위해 다른 헤더 파일을 포함하는 "마스터"헤더 파일을 제공하는 것이 좋습니다. 그러나 클라이언트가 필요한 것만 포함하도록 선택할 수도 있습니다.

대규모 프로젝트에서 컴파일 시간을 줄이려면 가능한 한 적은 양의 헤더를 포함시켜 장치를 컴파일하는 것이 일반적입니다.

2

모두 선택 제공에 대해 무엇을 :

#include <library.hpp> // include everything 
#include <library/module.hpp> // only single module 

이런 식으로 당신은 거대한 하나의 파일을 포함하고 별도의 파일에 대해, 그들이 하나의 디렉토리에 깔끔하게 적층이없는

2

이 라이브러리에 따라 달라집니다 , 그리고 어떻게 구조화했는지. 라이브러리의 헤더 파일과 헤더 파일에 포함 된 부분은 본질적으로 라이브러리 API의 일부임을 기억하십시오. 따라서 고객이 고객이주의 깊게 선택하여 헤더 중에서 선택하도록 유도하면 오랜 시간 동안 해당 레이아웃을 지원해야합니다. API의 일부가 정말로 선택적이고 큰 경우 라이브러리가 전체 인터페이스를 하나의 파일 또는 단지 몇 개의 파일로 내보내는 것이 일반적입니다.

고려해야 할 사항 컴파일 시간 : 클라이언트에 라이브러리를 사용할 수있는 파일이 2 개 있고 내부 포함이 포함되어있는 경우 큰 프로젝트에서 자주 사용하는 경우 컴파일 시간이 크게 늘어날 수 있습니다. 이 경로를 사용하는 경우 모든 포함에 파일 내용뿐만 아니라 포함 행을 포함하는 적절한 포함 경비가 있는지 확인하십시오. 참고 : 현대 GCC는이 특별한 문제에 대해 매우 훌륭한 역할을 수행하며 헤더의 내용을 둘러싼 경비원 만 필요로합니다.

최종 컴파일 된 프로그램을 bloating하는 방법은 라이브러리의 클라이언트가 헤더 파일을 포함하는 방법이 아닌 라이브러리를 컴파일하는 방법과 도구 체인에 따라 다릅니다. (헤더에 정적 데이터 객체를 선언하면 일부 데이터는 클라이언트가 사용하지 않더라도 해당 데이터를 정의하는 객체에 연결됩니다.)

요약하면, 매우 큰 라이브러리 또는 아주 오래되고 괴상한 툴 체인이라면, 나는 단일 include를 사용하는 경향이 있습니다. 필자의 현재 구현 부분을 라이브러리 API에 헤더로 고정시키는 것은 다른 것들보다 더 큰 걱정이다.

2

컴파일하는 각 소스 파일에는 컴파일러가 독립적으로 호출된다는 점에 유의하십시오. 각 호출마다 컴파일러는 포함 된 모든 헤더 파일을 읽고 파싱하고 심볼 테이블을 작성해야합니다.

많은 소스 파일에서 이러한 "세계 포함"헤더 파일 중 하나를 사용하면 빌드 시간에 상당한 영향을 줄 수 있습니다.

이 문제를 완화 할 수있는 방법이 있습니다. 예를 들어 마이크로 소프트는 미리 컴파일 된 헤더 기능을 가지고 있습니다.이 헤더 기능은 후속 컴파일이 사용하기 위해 기본적으로 심볼 테이블을 저장합니다.

다른 고려 사항이 있습니다. WhizzoString 클래스를 사용하려면 SOAP, OpenGL 및 헤더가 있어야합니다. 사실 WhizzoString.h에는 공개 인터페이스의 일부인 유형 및 기호에 대한 헤더 만 포함됩니다. 즉, 입니다.이 클래스의 사용자로 필요합니다. 가능한 한 많은

, 당신은 WhizzoString.cpp에 WhizzoString.h에서 포함 이동을 시도한다 :

OK :

// Only include the stuff needed for this class 
#include "foo.h" // Foo class 
#include "bar.h" // Bar class 

public class WhizzoString 
{ 
    private Foo m_Foo; 
    private Bar * m_pBar; 
     . 
     . 
     . 
} 

더 나은 :

// Only include the stuff needed by the users of this class 
#include "foo.h" // Foo class 

class Bar; // Forward declaration 

public class WhizzoString 
{ 
    private Foo m_Foo; 
    private Bar * m_pBar; 
     . 
     . 
     . 
} 

클래스 사용자가 막대 유형을 만들거나 사용할 필요가없고 클래스에 아무 것도 포함하지 않은 경우 Bar의 인스턴스가 있으면 헤더 파일에 Bar의 전달 선언 만 제공하면 충분합니다 (WhizzoString.cpp는 #include "bar.h"이됩니다). 즉, WhizzoString.h를 포함한 모든 사람은 Bar.h 및 포함 된 모든 것을 포함하지 않을 수 있습니다.

+0

@ Scott Smith : 좋은 지적입니다! 감사! – csmithmaui

관련 문제