2010-11-19 2 views
4

일부는 헤더 파일 가져 오기/포함을 헤더 파일에 추가하는 습관이 있습니다. 다른 한편으로 헤더 파일에 forward 선언을 작성하고 실제 #include 또는 #import 행을 구현 파일에 씁니다.헤더 파일 또는 구현 파일의 #import

표준 연습이 있습니까? 어느 쪽이 더 낫고 왜?

답변

9

X.h와 X.c가 있다고 가정하면 #include X.h의 모든 것입니다. #include <X.h>의 클라이언트는 X에서 필요한 경우도 있지만 모든 헤더를 포함합니다.

X.h는 X.h를 구문 분석하는 데 필요한 것만 포함해야합니다. 재정렬 흠도가 클라이언트를 해치지 않도록 번역 유닛이 다른 헤더를 포함하지 않을 것이라고 가정해야합니다. X.c는 구현에 필요한 모든 추가 항목을 포함해야합니다.

이렇게하면 재 컴파일 종속성이 최소화됩니다. 구현에만 변경 사항을 적용하여 헤더에 영향을주지 않으므로 클라이언트 재 컴파일이 트리거됩니다. Xc에서 직접 포함시켜야합니다.

1

클래스가 얕은 종속성을 가질 때 헤더 대신 전달 참조를 포함해야합니다. 예를 들어 :

A.h

#include "B.h" 
class A { 
    B* pointer; 
}; 

B.h

#include "A.h" 
class B { 
    A* pointer; 
}; 

컴파일에 휴식 것입니다.

class A; class B { A* pointer; }; 

각 클래스로 작동합니까 A.h

class B; 
class A { 
    B* pointer; 
}; 

B.h

는 다른 클래스가 선언에 존재하는 알 필요가있다.

+0

현실 세계에서 순환 의존성을 갖는 것이 좋은 설계/아키텍처입니까? – Mugunth

+1

아니요, 가능한 경우 항상 피해야합니다. 피할 수없는 경우 두 모듈이 상호 적으로 포함될 필요가있는 경우 99 %의 경우 의미 적으로 하나의 동일한 모듈이거나 둘 모두에 의존하는 결합 된 기본 모듈의 수퍼 모듈이 될 수 있습니다. – slezica

+1

A와 B에 대해 각각 "클래스 A"와 "클래스 B"만 포함하고, 각각 A.h와 B.h에 포함되어있는 순방향 선언 헤더를 제공하는 것이 더 좋습니다. 그런 식으로, A의 전방 선언, 선언 및 구현은 A (테스트 케이스 포함)에서 무엇인가를 작성할 때 자연스럽게 상호 참조되므로 클래스 A에서 일부 템플릿 및 typedef를 변경하면 B가 컴파일러에 대해 그렇소. –

0

헤더 파일에 가져 오기를 작성하므로 모든 구현 파일에는 하나의 포함 지시문 만 있습니다. 이것은 또한 모듈의 코드 사용자로부터 의존성을 숨기는 이점이 있습니다.

그러나 동일한 숨기기에는 단점이 있습니다. 모듈 사용자는 헤더에 포함 된 모든 종류의 다른 헤더를 가져올 수 있습니다. 이러한 관점에서 구현 파일에 포함 지시문을 사용하는 것이 종속성을 수동으로 해결하는 것을 의미하는 경우 라하더라도 코드가 더 가볍게 작성되므로 더 바람직합니다.

나는 하나의 대답이 있다고 생각하지 않습니다. 내가 준 이유를 고려할 때, 나는 첫 번째 접근법을 선호한다. 나는 더 깨끗한 코드 (더 무겁고 불필요한 임포트가있을지라도)를 이끌어 낼 것으로 생각한다.

내가 인용하고있는 사람이 기억이 나지 않아서 (즉 문구가 정확하지는 않지만) 항상 읽는 것을 기억합니다. "프로그램은 사람이 읽고 쓸 수 있도록 작성되며, 때로는 컴퓨터가 실행되도록 작성되었습니다." 나는 그가 깔끔하게 쉽게 가져올 수 있고 한 개의 지시어로 사용할 수있는 한 내 모듈의 사용자가 필요로하지 않는 몇 킬로 비트의 코드가 있는지 특별히 신경 쓰지 않는다.

다시 한번 생각해 보지 못한 것이 없다면, 그것은 맛의 문제라고 생각합니다. 이 경우에 주석이 환영받을 만합니다!

건배.

+4

미안하지만 - 당신의 논리가 엉망이되고 잘 정립 된 모범 사례와 반대되는 경향이 있습니다. 첫 번째 단락 : "이것은 또한 모듈의 코드 사용자로부터 의존성을 숨기는 장점이 있습니다."/"그가 깨끗하게 할 수있는 한, 그것을 쉽게 가져 와서 하나의 지시어로 사용하십시오". 헤더를 파싱하는 데 필요한 것을 포함시켜야합니다. 구현에만 필요한 다른 헤더는 클라이언트가 기능을 사용하기 위해 포함될 필요가 없습니다. (어느 쪽이든, 클라이언트는 여전히 객체/라이브러리에 링커 의존성을 추가해야합니다.) –

+0

솔직히 내 논리가 어수선하게 보이지 않습니다. 컴파일 라인에 파일을 추가하는 것은 다른 사람이 코드에서 여러 모듈을 가져 오도록 강요하는 것과 같지 않습니다. 내가보기에는 당신이 매우 비방하는 방법이기 때문에 더 이상 언급하지 않도록하십시오. 나는 이것에 대한 기사를 살펴보고 내 마음을 고쳐 볼 것이다. – slezica