2009-03-03 4 views
9

.C 또는 .cpp 파일마다 헤더 파일 (.h)이 있어야합니까?모든 C 또는 C++ 파일에 헤더 파일이 있어야합니까?

은 C 파일이 다음과 같다고 가정 해 보겠습니다

  1. MAIN.C

  2. Func1.C

  3. Func2.C

  4. Func3.C

여기서 main()은 Main.C 파일에 있습니다.

또는 존재해야 Main.h

  • Func1.h

  • Func2.h

  • Func3.h

    네 개의 헤더 파일

    1. 이 있어야한다 모든 .C 파일에 대해 하나의 헤더 파일 일 수 있습니까?

      더 나은 방법은 무엇입니까?

  • 답변

    3

    일반적으로 .c/.cpp 파일마다 .h 파일이 하나씩 있습니다.

    4

    는 일반적으로 당신이 노출 할 .c 파일 함수 등의 선언을 포함, 각이 .c 파일에 대한 헤더 파일을 가지고하는 것이 좋습니다. 이렇게하면 다른 .c 파일에 필요한 기능을위한 .h 파일을 포함 할 수 있으며 포함하지 않은 헤더 파일이 변경된 경우 다시 컴파일 할 필요가 없습니다.

    2

    에 따라 다릅니다. 대개 별도의 .c 파일이 필요한 이유는 별도의 .h 파일이 필요한지 여부를 결정합니다.

    28

    보통 컴파일시에 다른 컴파일 단위에 노출 될 필요가 전혀 없다 이후 main.h을 가지고 특이한입니다. main() 자체는 링커/시작 코드에 대해 공개해야하지만 헤더 파일은 사용하지 않습니다.

    당신은 C 파일 당 하나 개의 헤더 파일 중 하나를 가질 수있다거나, 대부분, C 파일의 관련 그룹에 대한 헤더 파일. 당신이 BTREE 구현을 가지고 당신이 때 코드 변경 재 컴파일을 최소화하기 위해 자신의 C 파일에 등등, 추가, 삭제, 검색 넣고 한 경우 그

    한 예입니다.

    이 헤더는 API, 사용자에게 라이브러리의보기와 같이 각 C 파일에 대한 별도의 헤더 파일을 가지고이 경우 이해가되지 않습니다. 사용자가 함수를 사용할 수 있도록 6 개의 헤더 파일을 포함하기를 원할 것입니다. 하나의 btree.h 파일과 하나의 btree.lib 파일이 개별 C 파일에서 빌드 된 모든 BTree 오브젝트를 포함합니다.

    또 다른 예

    은 표준 C 헤더에서 찾을 수 있습니다.우리는 stdio.h 함수에 대해 여러 개의 C 파일이 있는지 여부를 확실하게 알지 못합니다. (그렇게하는 방법은 있지만 유일한 방법은 아닙니다.) 그렇다고해도, 그것들은 API. stdio_printf.h, stdio_fgets.h 등을 포함 할 필요가 없습니다. C 런타임 라이브러리의 표준 I/O 부분에 대해 하나의 stdio.h이 있습니다.

    +1

    템플릿을 언급하지 않았으므로 +1이 없습니다. ( – Marcin

    +0

    나는 C면에 더 집중하고 있었지만 왜 언급하겠습니까? 템플릿, 심지어 C++? 헤더 파일에 어떤 응용 프로그램이 사용되는지 (헤더 파일에 들어갈 수는 있지만 typedef는 사용할 수 있으며 명시 적으로 언급하지는 않습니다.) – paxdiablo

    1

    일반적인 방법과 일반적인 경우 만 더 나은 방법은 없습니다.

    더 일반적인 경우는 선언/정의 할 클래스/함수 인터페이스가있는 경우입니다. 정의가있는 .cpp/.c와 선언을위한 헤더가 하나만있는 것이 좋습니다. 동일한 이름을 지정하면 해당 이름이 직접 관련되어 있음을 쉽게 알 수 있습니다.

    그러나 "규칙"이 아니기 때문에 일반적인 방법이며 거의 모든 경우에서 가장 효율적입니다.

    일부 경우 (템플릿 클래스 또는 일부 작은 구조체 정의와 같은 경우) 헤더에는 .c/.cpp 파일이 필요하지 않습니다. 우리는 가상 순수 함수 또는 사소한 함수만을 사용하여 예를 들어 헤더 파일에만 가상 클래스 인터페이스 정의를 사용합니다.

    다른 드문 경우 (외부의 main.c/.cpp 파일과 같이) 외부 컴파일 장치의 코드가 주어진 컴파일 단위의 기능을 호출하도록 허용 할 필요가없는 경우가 있습니다. main 함수는 예제 (헤더/선언 필요 없음)이지만 다른 것들도 있습니다. 대부분 "다른 모든 파트를 모두 연결하는"코드이며 응용 프로그램의 다른 부분에서 호출하지 않습니다. 매우 드물 긴하지만이 경우 헤더가 이해가되지 않습니다.

    0

    이미 언급했듯이 일반적으로 각 원본 (.c 또는 .cpp) 파일마다 하나의 헤더 파일 (.h)이 있습니다.

    그러나 파일의 응집력을 살펴 봐야합니다. 다양한 소스 파일이 개별적으로 재사용 할 수있는 기능 집합 (이상적인 조직)을 제공하는 경우 파일 당 하나의 헤더가 있어야합니다. 그러나 3 개의 소스 파일이 하나의 파일에 들어 맞지 않는 복합 함수 세트를 제공하면보다 복잡한 조직을 사용하게됩니다. 주 프로그램에서 사용하는 외부 서비스에 대해 하나의 헤더가 있으며 이는 동일한 서비스가 필요한 다른 프로그램에서 사용됩니다. 또한 협력 소스 파일에서 사용되는 두 번째 헤더가있어 해당 파일이 공유하는 '내부'정의를 제공합니다.

    (주 : Pax 참고) : 메인 프로그램에는 일반적으로 자체 헤더가 필요하지 않습니다. 다른 소스 코드가 제공하는 서비스를 사용해야합니다. 다른 파일에서 제공하는 서비스를 사용합니다.

    0

    다른 컴파일 유닛에서 컴파일 된 코드를 사용하려면 헤더 파일이 필요합니다. 헤더가 필요하거나 필요로하는 상황이 있습니다.

    첫 번째 경우는 main.c/cpp 파일입니다. 이 클래스는 포함되지 않으므로 헤더 파일이 필요 없습니다.

    경우에 따라 런타임에로드되는 dll을 통해로드되는 다양한 구현 집합의 동작을 정의하는 헤더 파일을 가질 수 있습니다. 동일한 헤더 변형을 구현하는 .c/.cpp 파일 집합이 있습니다. 이것은 플러그인 시스템에서 일반적 일 수 있습니다.

    10
    1. 헤더 파일은 필수 항목이 아닙니다.

    2. #include 포함 된 파일 (예 :.C 소스 파일)

    3. constants.h과 같은 글로벌 헤더 파일에는 컴파일 타임 플래그 및 프로젝트 광역 상수와 같이 일반적으로 사용되는 정보가 들어 있습니다.

    4. 라이브러리 API의 좋은 디자인은 공식 인터페이스를 한 세트의 헤더 파일로 노출시키고 모든 세부 사항을 구현하기 위해 내부 헤더 파일 세트를 사용하는 것입니다. 이렇게하면 불필요한 확장을 추가하지 않고도 C 라이브러리에 멋진 추상화 레이어를 추가 할 수 있습니다.

    5. 상식을 사용하십시오. C/C++은 실제로없는 것입니다.

    0

    일반적으로 CPP/C 파일은 헤더 파일 (프로토 타입과 선언에만 해당) 용입니다 (HPP는 자주 사용되지 않음) 파일 구현 및 H/HPP를위한 것입니다. Cpp 파일은 헤더 파일을 항상 가질 필요는 없지만 헤더 파일은 cpp 파일 사이의 다리 역할을하므로 각 cpp 파일은 다른 cpp 파일의 코드를 사용할 수 있습니다.

    강력하게 적용되어야하는 한 가지는 헤더 파일 내에 코드를 사용하지 않는 것입니다! 재정의로 인해 헤더 파일이 크기 프로젝트에서 컴파일을 중단하는 경우가 너무 많습니다. 그리고 그것은 단순히 헤더 파일을 두 개의 다른 cpp 파일에 포함시키는 것입니다. 헤더 파일은 항상 여러 번 포함되도록 디자인되어야합니다. Cpp 파일을 절대로 포함해서는 안됩니다.

    0

    일반적으로 .h와 .c 파일간에 명시적인 관계가 있다고는 생각하지 않습니다. 많은 경우 (아마 대부분) 코드 단위는 공용 인터페이스 (.h)와 불투명 한 구현 (.c)이있는 기능 라이브러리입니다. 열거 형이나 매크로처럼 많은 기호가 필요할 때도 있고 .c가없는 .h를 얻는 경우도 있고 어떤 경우에는 공용 인터페이스가없고 대응이없는 코드가 있습니다 .h

    특히 가독성을 위해 머리말이나 구현체 (드물게 둘다)가 너무 크고 털이 많아서 프로그래머의 온전함을 위해 많은 작은 파일들로 나뉘는 경우가 많습니다.

    2

    헤더 파일에 인터페이스를 넣고 cpp 파일로 구현하는 것을 좋아합니다. C++에서 멤버 변수와 프로토 타입을 헤더에 추가 한 다음 C++에서 다시 메서드를 추가해야하는 C++을 작성하는 것을 좋아하지 않습니다.

    module.h에

    struct IModuleInterface : public IUnknown 
    { 
        virtual void SomeMethod() = 0; 
    } 
    

    module.cpp 나는이 구현과 인터페이스를 오토넷의 정말 깨끗한 방법 찾을

    class ModuleImpl : public IModuleInterface, 
            public CObject // a common object to do the reference 
                   // counting stuff for IUnknown (so we 
                   // can stick this object in a smart 
                   // pointer). 
    { 
        ModuleImpl() : m_MemberVariable (0) 
        { 
        } 
    
        int m_MemberVariable; 
    
        void SomeInternalMethod() 
        { 
         // some internal code that doesn't need to be in the interface 
        } 
    
        void SometMethod() 
        { 
         // implementation for the method in the interface 
        } 
    
        // whatever else we need 
    }; 
    

    : 내가 좋아하는 뭔가를 선호합니다.

    +0

    Java의 C++ 프로그래밍 인터페이스 . 상속 클래스에 SomeMethod()를 구현하지 않으면 오류가 발생합니다. – deworde

    +0

    네, 그건 철학입니다.이 접근법에 대한 찬사를받을 수는 없지만, 작업자가 패러다임을 생각해 내고 그 이후로 사용했습니다. 네가 외부 인터페이스를 올바르게 구현하지 못하면 컴파일 오류가 발생합니다. – RedBlueThing

    +0

    이것은 Adobe InDesign SDK 전체에서 사용되었습니다. 나는 이것이 마이크로 소프트 COM에서 온 것이라고 믿는다. – Kugel

    1

    다른 코드가 무엇인지 알아야하는 코드가 무엇인지 알아야합니다. 다른 파일이 인식하고있는 양을 최소로 줄여서 작업을 수행하고자합니다.

    이들은 함수가 있는지, 전달해야 할 형식이 무엇인지, 그리고 반환 할 형식이 무엇인지 알아야합니다. 내부적으로 무엇을하는지는 알 필요가 없습니다. 프로그래머 관점에서 보면 이러한 유형이 실제로 의미하는 바를 알고 있어야합니다. (예 : int는 행이고 어느 열이) 코드 자체는 상관하지 않습니다. 이것이 기능과 매개 변수를 현명하게 명명하는 것이 가치가있는 이유입니다.

    다른 사람들처럼 말하자면, main.c의 경우처럼 코드의 다른 부분에 노출 될만한 가치가없는 cpp 파일이 없다면 헤더 파일이 필요 없습니다.

    가끔은 Func1에 대해 알고있는 모든 것이 Func2에 대해서도 알 수 있도록 단일 헤더 파일 (예 : Func1and2and3.h)에 넣고 싶은 모든 것을 넣을 가치가 있습니다. 그러나 저는 개인적으로 이것을 좋아하지 않습니다. 그것은 당신이 실제로 원하는 물건과 함께 많은 쓰레기를 버리는 경향이 있다는 것을 의미합니다.

    요약 : 누군가가 코드를 작성하고 알고리즘, 디자인 등이 모두 훌륭하다고 생각한다고 상상해보십시오. 그들이 작성한 코드를 사용하려고합니다. 당신이 알아야 할 것은 일어날 일, 무엇을 주어야하는지, 그리고 무엇을 얻을 것인지를주기 위해 무엇을 제공해야하는지입니다. 그게 헤더 파일에 있어야합니다.

    1

    파일이 인터페이스를 노출하는 경우 (즉, 다른 파일에서 호출 할 기능이있는 경우) 헤더 파일이 있어야합니다. 그렇지 않으면, 그렇게해서는 안됩니다.

    6

    일관성, 균일 성 및 단순성이 파일을 만드는 노력을 저장하는 것보다 중요하다는 것과 "표준이 좋지 않을 때에도 좋습니다"라는 것을 깨닫기 전까지 나는 "의존적 인"추세를 따라야했습니다.

    내 말은 다음과 같습니다. .cpp/.h 파일 쌍은 모든 "모듈"이 어쨌든 끝나는 것입니다. 두 가지 요구 사항을 동시에 적용하면 많은 혼란과 나쁜 엔지니어링을 줄일 수 있습니다.

    예를 들어, 헤더 파일에서 뭔가의 인터페이스를 볼 때, 정확히 어디에서 해당 구현을 검색/배치할지 알 수 있습니다. 반대로 .cpp 파일에 이전에 숨겨져 있던 인터페이스 (예 : 정적 함수가 전역이되는)의 인터페이스를 노출해야하는 경우 정확히 어디에 넣어야할지 압니다.

    의 나쁜 결과가이 간단한 규칙에 따라이 아닌 것으로 나타났습니다. 불필요한 인라인 함수. 적절한 형제 헤더 또는 cpp 파일이 추가되지 않았기 때문에 인 캡슐 레이션, 인터페이스 및 구현의 분리 (잘못된) 코드, 몇 가지 예를 들자면 모든 종류의 규칙을 위반합니다.

    그래서 항상 .h와 .c 파일을 모두 정의하십시오. 그것을 표준으로 만들고 따르고 안전하게 에 의존하십시오. 인생은이 방법으로 훨씬 더 간단하고 간결함 은 소프트웨어에서 가장 중요한 것인입니다.

    +0

    이것은 바보입니다. 어떤 것들은 구현이 필요하지 않습니다 (예 : 설정 헤더 등). 코드 표준은 훌륭합니다. 그렇지만, 분명히 여러분이 무언가 어리석은 짓을하고 있다고하더라도 (빈'.c' 파일과 같은) 그렇게하지는 않습니다. 예를 들어, 현재 제 라이브러리에는 52 개의 헤더와 47 개의 구현 파일 만 있습니다. – Thomas

    2

    비얀 스트로브 스트 룹은 .... 아름답게 자신의 저서는 "C++ 프로그래밍 언어"에 대해 설명

    프로그램이 작고 그 부분은 별도의 사용하도록하지 않을 때 물리적 파티션의 단일 헤더 스타일에 가장 유용 . 네임 스페이스가 사용될 때, 프로그램의 논리적 구조는 여전히 하나의 헤더 파일에서 설명 될 수 있습니다.

    큰 프로그램의 경우 단일 헤더 파일 접근 방식은 일반적인 파일 기반 개발 환경에서 작동하지 않습니다. 공통 헤더를 변경하면 전체 프로그램이 다시 컴파일되고 여러 프로그래머가 단일 헤더를 업데이트하면 오류가 발생하기 쉽습니다. 네임 스페이스와 클래스에 크게 의존하는 프로그래밍 스타일을 강조하지 않는 한 논리적 구조는 프로그램이 커짐에 따라 저하됩니다.

    대체 물리적 조직을 사용하면 각 논리 모듈이 제공하는 기능을 정의하는 자체 헤더를 가질 수 있습니다. 각 .c 파일에는 해당 h가 있습니다. 그것이 제공하는 것을 지정하는 파일 (인터페이스). 각각.c 모듈에는 자체 .h 파일과 일반적으로 인터페이스에 공고 된 서비스를 구현하기 위해 다른 모듈에서 필요한 것을 지정하는 .h 파일도 포함됩니다. 이 물리적 조직은 모듈의 논리적 조직에 해당합니다. 다중 헤더 방식을 사용하면 종속성을 쉽게 판별 할 수 있습니다. 단일 헤더 방식을 사용하면 모든 모듈에서 사용되는 모든 선언을 살펴보고 해당 모듈의 관련 여부를 결정해야합니다. 간단한 사실은 코드의 유지 관리가 불완전한 정보와 로컬 관점에서 항상 수행된다는 것입니다. 더 나은 현지화로 인해 모듈을 컴파일하는 데 필요한 정보가 줄어들고 따라서 컴파일 속도가 빨라집니다.

    관련 문제