작업중 인 C ++ 프로젝트에서 포함을 정리하고 있으며 특정 파일에 직접 사용되는 모든 헤더를 명시 적으로 포함 해야하는지 또는 최소값 만 포함 해야하는지 궁금합니다.
예를 들면 다음과 같습니다 Entity.hpp
.
#include "RenderObject.hpp"
#include "Texture.hpp"
struct Entity {
Texture texture;
RenderObject render();
}
(forward 선언 RenderObject
은 옵션이 아니라고 가정합니다 .)
지금, 나는 그 아는 RenderObject.hpp
포함 Texture.hpp
– 나는 각이 때문에 알고 RenderObject
이 Texture
멤버. 여전히에 포함 Texture.hpp
되어 Entity.hpp
있는지에 대한 확신이 있는지 확실하지 않기 때문에에 명시 적 으로 포함하고 RenderObject.hpp
있습니다.
그래서 : 좋은 습관입니까?
답변
해당 파일의 내용에 대해 알고있는 것과 상관없이 해당 파일의 .cpp 파일에 사용 된 개체를 정의하는 모든 헤더를 항상 포함해야합니다. 헤더를 여러 번 포함하는 것이 중요하지 않도록 모든 헤더 파일에 가드를 포함해야합니다.
그 원인:
- 이를 통해 해당 소스 파일이 요구하는 것과 정확하게 소스를 읽는 개발자에게 명확 해집니다. 여기에서 파일의 처음 몇 줄을보고있는 누군가
Texture
가이 파일의 객체를 다루고 있음을 알 수 있습니다 . - 따라서 리팩터링 된 헤더가 더 이상 특정 헤더 자체가 필요하지 않을 때 컴파일 문제를 일으키는 문제를 피할 수 있습니다. 예를 들어
RenderObject.hpp
실제로 필요하지 않다는 것을 알고 있다고 가정하십시오Texture.hpp
.
결과적으로 해당 파일에 명시 적으로 필요한 경우가 아니면 다른 헤더에 헤더를 포함해서는 안됩니다.
답변
일반적으로 사용하는 내용을 포함하십시오. 객체를 직접 사용하는 경우 헤더 파일을 직접 포함하십시오. B를 사용하지만 B를 직접 사용하지 않는 객체 A를 사용하는 경우 Ah 만 포함하십시오.
또한 주제에 관한 동안 실제로 헤더에 필요한 경우 헤더 파일에 다른 헤더 파일 만 포함해야합니다. .cpp에만 필요하면 여기에만 포함하십시오. 이것은 공개 및 개인 종속성의 차이점이며 클래스 사용자가 실제로 필요하지 않은 헤더를 드래그하지 못하게합니다.
답변
특정 파일에 직접 사용 된 모든 헤더를 명시 적으로 포함 해야하는지 궁금합니다.
예.
다른 헤더가 언제 변경 될지는 알 수 없습니다. 각 번역 단위에 번역 단위에 필요한 헤더를 포함시키는 것이 전 세계적으로 의미가 있습니다.
이중 포함이 유해하지 않도록 헤더 보호대가 있습니다.
답변
이것에 대한 의견은 다르지만 모든 파일 (c / cpp 소스 파일 또는 h / hpp 헤더 파일)은 자체적으로 컴파일하거나 분석 할 수 있어야한다는 견해입니다.
따라서 모든 파일은 필요한 모든 헤더 파일을 #include해야합니다. 하나의 헤더 파일이 이미 포함되어 있다고 가정해서는 안됩니다.
헤더 파일을 추가하고 직접 포함하지 않고 다른 곳에 정의 된 항목을 사용하는 것을 발견하면 정말 고통 스럽습니다. 그래서 찾아야합니다 (아마도 잘못된 것으로 끝납니다!)
반대로, 필요하지 않은 파일을 #include하면 (일반적으로) 문제가되지 않습니다 …
개인 스타일의 포인트로, #include 파일을 알파벳 순서로 정렬하고 시스템과 응용 프로그램으로 나눕니다. 이는 “자체가 포함되고 완전히 일관된”메시지를 강화하는 데 도움이됩니다.
답변
전 이적 포함이 필요한지 (예 : 기본 클래스) 또는 구현 세부 사항 (개인 멤버)에 의한 것인지에 따라 다릅니다.
명확히하기 위해 전 이적 포함은 제거 할 때 필요합니다. 중간 헤더에 선언 된 인터페이스를 먼저 변경 한 후에 만 수행 할 수 있습니다. 그것은 이미 중대한 변화이므로, 그것을 사용하는 .cpp 파일은 어쨌든 검사해야합니다.
예 : Ah는 C.cpp에서 사용되는 Bh에 포함됩니다. Bh가 구현 세부 사항으로 Ah를 사용한 경우 C.cpp는 Bh가 계속 그렇게 할 것이라고 가정해서는 안됩니다. 그러나 Bh가 기본 클래스에 Ah를 사용하는 경우 C.cpp는 Bh가 기본 클래스에 대한 관련 헤더를 계속 포함한다고 가정 할 수 있습니다.
여기에 헤더 포함을 복제하지 않는 장점이 있습니다. Bh가 사용하는 기본 클래스가 실제로 Ah에 속하지 않고 Bh 자체로 리팩토링되었다고 가정하십시오. Bh는 이제 독립형 헤더입니다. C.cpp에 Ah가 중복 포함 된 경우 이제 불필요한 헤더가 포함됩니다.
답변
또 다른 경우가있을 수 있습니다. Ah, Bh 및 C.cpp가 있으며 Bh에는 Ah가 포함됩니다
C.cpp에서는
#include "B.h"
#include "A.h" // < this can be optional as B.h already has all the stuff in A.h
여기에 #include “Ah”를 쓰지 않으면 어떻게 될까요? C.cpp에서는 A와 B (예 : 클래스)가 모두 사용됩니다. 나중에 C.cpp 코드를 변경하고 B 관련 항목을 제거했지만 Bh는 포함시키지 않았습니다.
Ah와 Bh를 모두 포함하고 지금이 시점에서 불필요한 포함을 감지하는 도구를 사용하면 Bh 포함이 더 이상 필요하지 않음을 알 수 있습니다. 위와 같이 Bh 만 포함하면 도구 / 사람이 코드 변경 후 불필요한 포함을 감지하기 어렵습니다.
답변
제안 된 답변과 약간 다른 접근 방식을 취하고 있습니다.
헤더에는 항상 최소값 만 포함하고 컴파일 패스를 만드는 데 필요한 것만 포함하십시오. 가능하면 앞으로 선언을 사용하십시오.
소스 파일에서 얼마나 많이 포함하는지는 중요하지 않습니다. 내 환경 설정에는 여전히 최소값이 포함되어야합니다.
여기에 헤더를 포함하여 작은 프로젝트의 경우 차이가 없습니다. 그러나 중대형 프로젝트의 경우 문제가 될 수 있습니다. 최신 하드웨어를 사용하여 컴파일하더라도 차이점이 눈에.니다. 그 이유는 컴파일러가 여전히 포함 된 헤더를 열고 구문 분석해야하기 때문입니다. 따라서 빌드를 최적화하려면 위의 기술을 적용하십시오 (최소한 포함 및 forward 선언 사용).
조금 오래되었지만 대규모 C ++ 소프트웨어 디자인 (John Lakos)은이 모든 것을 자세히 설명합니다.