2011-08-03 4 views
5

헤더 파일에 다른 헤더 파일이 포함되지 않고 해당 * .cpp 파일에 모든 종속성이 포함되어 있어야하며 올바른 순서로 포함되는 스타일을 포함하는 헤더를 보았습니다. 좋은 옛날에 이것으로 빌드 의존성 추적을 더 쉽게 만들 수있는 것 같습니다 (그러나 나는 단지 추측하고 있습니다). 요즘 좋은 이유가 있을까요?C 헤더 파일에 다른 헤더 파일을 포함하지 않는 이유는 무엇입니까?

파일 "BH"

#ifndef _B_h_ 
#define _B_h_ 

// Note we do not #include "A.h" that contains class A declaration. 

class B 
{ 
public: 
    A a; // An A object. 
}; 
#endif // _B_h_ 

파일 "B.cpp"

#include "A.h" // Must include this before B.h, otherwise class A not defined in B.h 
#include "B.h" 

... 
+1

당신이 그것을 원하는 경우 자신의 질문 제목을 편집 할 수 있습니다. –

+0

실생활에서 그 예를 보지 못했다고 생각합니다. 컴파일하지 않았기 때문입니다. 모든 멤버 객체의 전체 유형에 액세스 할 수 있어야합니다. –

+2

소원을 부여했습니다. :) –

답변

4

코드를 작성한 사람은 포함 된 헤더의 수를 줄이는 일반적인 권장 사항을 잘못 이해 한 것으로 보입니다.일반적으로 컴파일 속도를 높이기 위해 불필요한#include <> 지시문을 제거하는 것이 좋습니다. 실제로 대형 프로젝트에, 그것은에 의해 크게 컴파일을 가속화 할 수 있습니다 : 헤더의 수를 줄일 수

  1. 컴파일러가 주어진 소스 파일을 컴파일 열 필요가있는 파일;
  2. 헤더가 변경된 후 다시 컴파일해야하는 소스 파일의 수를 줄입니다. 일반적으로

, 사람들이 추천합니다 (그 난에 작업 한 모든 프로젝트에 대한 표준 코딩에 있었다) 당해 헤더에 정의 된 클래스가 아닌 클래스에 대한 기대 선언을 사용하여 :

  1. 으로 사용 기본 클래스.
  2. 은 데이터 멤버로 사용됩니다.
  3. 에는 공식 서식이 불완전합니다 (예 : 표준 라이브러리 컨테이너는 기본값이있는 한 추가 템플릿 인수가 허용되므로이를 선언하기 위해 비표준입니다).
  4. 가지 경우 1과 2에서

#include <> 지시 해야모든 따라 소스 파일과 헤더의 클래스 정의 앞에 나타납니다. 기본적으로 헤더의 #include <> 지시어를 각각의 종속성으로 이동합니다. 결과적으로 더 많은 코드가 생성되고 이점이 없습니다 (예 : 컴파일 시간 등은 동일합니다). 이러한 이유 때문에이 권장 사항은 코딩 표준에서 또 다른 항목을 동반합니다. 각 헤더 파일은 "독립 실행 형"으로 컴파일해야합니다 (예 : 소스 파일의 첫 번째 줄에 포함).

8

그래, 즉 누군가가 순서 잘못 얻는 경우에 때문에 오류를 얻을 것이다, 나쁜 관행 것 그들이 알아 내지 못할 수도 있습니다. 모든 헤더 파일에 가드가 포함되어 있으면 필요로하는 다른 모든 헤더를 포함하는 하나의 헤더가 문제가되지 않습니다. 이것이 어떻게되어야하는지입니다.

+1

+1. Window의 헤더 파일 중 하나를 포함 할 때 어떤 점에서 이런 문제가 발생했다고 생각합니다. 설명서에는 "X를 포함하면 Y도 포함해야합니다."와 같은 내용이 있습니다. 제 생각은 "X가 Y를 필요로한다면, 왜 X가 Y 자체를 포함하지 않는 걸까요?"라고 생각했습니다. – MRAB

+0

@MRAB 나는 그와 비슷한 것을 기억하지만, 그것이 어떤 헤더인지 기억할 수 없다. –

+1

''이 (가) ''앞에 포함되어야합니다. 그렇지 않으면 ''에' '이 포함되어 있습니다 (호환되지 않으며 더 이상 사용되지 않음). –

2

요즘에는 그럴만한 이유가 있습니까?

아니요. 사람들은 더 잘 알지 못하거나 신경 쓰지 않거나 더 중요한 것들을 걱정할 것이기 때문에 "일할"모든 종류의 일을합니다. 언어가 실제 모듈 가져 오기 시스템이있는 대신 전처리기에 의존 할 때 발생합니다.

귀하의 물건을 포함하는 사람이 포함 또는 숨겨진 사전 요구 사항의 순서에 대해 걱정할 필요가 없도록하는 것이 좋습니다. 물론 제 3 자의 어리석은 매크로 속임수로 인해 손이 강제되지 않는다면 어쨌든.

4

정말 나쁜 습관입니다. 컴파일러가 오류가 발생하기 쉬운 올바른 순서를 파악하도록하십시오. 헤더는 자체적으로 포함 된 것처럼 컴파일해야합니다 (예 : #include "B.h"으로 구성된 TU가있는 경우).

+0

컴파일러는 올바른 순서를 알아낼 수 없습니다. 거기도 옳은 주문일까요? –

+1

모레 소, * A.h를 포함하지 않고'B.h' *를 사용할 수있는 * 방법이 없으므로 'B.h'안에'A.h '가 포함되어야한다는 것은 논리적 일뿐입니다. "나는 B 급을 원한다."라고 말할 수 있어야하며, 어떤 상황에서도 B. h를 포함 시켜서이 목표를 달성 할 수 있어야합니다. –

2

예, 헤더에 INTERFACE의 모든 종속성을 # 포함하는 것이 좋습니다.

이 경우 예 : #가 "A"를 포함합니다 (B의 인터페이스는 A에 의존하기 때문에).

그렇지 않으면 구현에서 "A"(헤더가 사용되지 않음)를 사용하는 경우 인터페이스의 일부가 아니기 때문에 .cpp에서 A 만 # 포함합니다.

아무래도 피할 수없는 경우 어떠한 경우에도 헤더 순서가 중요합니다. 일반적으로 헤더 순서는 중요하지 않아야합니다 (SHOULD NOT).

이럴 ...

PS : 비얀 스트로브 스트 룹 그렇지 않으면 원하는대로 전처리 및 전처리 매크로는 여전히 우리와 아주 많이 있습니다만큼. 확실하게 C-land에서, 그리고 확실히 어떤 Microsoft API에서도. 사실을 존중하는 것은 좋은 형태입니다.

2

나는이 나쁜 스타일을 고려할 것입니다. 오류를 이해하는 것은 어려울 것입니다.

단일 헤더 파일을 변경할 때마다 많은 코드를 다시 컴파일하지 않는 것이 좋습니다. 그래도이 상황에 처하면 디자인 문제가있을 것입니다.

관련 문제