development

왜 헤더 파일과 .cpp 파일이 있습니까?

big-blog 2020. 2. 15. 21:03
반응형

왜 헤더 파일과 .cpp 파일이 있습니까? [닫은]


C ++에 헤더 파일과 .cpp 파일이있는 이유는 무엇입니까?


글쎄, 주된 이유는 인터페이스를 구현에서 분리하기위한 것입니다. 헤더는 클래스 (또는 구현되는 모든 것)가 수행 할 "무엇"을 선언하지만 cpp 파일은 "어떻게"기능을 수행 할 것인지를 정의합니다.

이것은 의존성을 줄여서 헤더를 사용하는 코드가 구현의 모든 세부 사항과 그에 필요한 다른 클래스 / 헤더를 알아야 할 필요는 없습니다. 이렇게하면 구현 시간이 변경 될 때 컴파일 시간과 재 컴파일 양이 줄어 듭니다.

완벽하지는 않으며 일반적으로 인터페이스와 구현을 올바르게 분리하기 위해 Pimpl Idiom 과 같은 기술에 의존 하지만 좋은 시작입니다.


C ++ 컴파일

C ++ 컴파일은 다음 두 가지 주요 단계로 수행됩니다.

  1. 첫 번째는 "원본"텍스트 파일을 이진 "객체"파일로 컴파일하는 것입니다. CPP 파일은 컴파일 된 파일이며 원시 선언 또는 헤더 포함. CPP 파일은 일반적으로 .OBJ 또는 .O "object"파일로 컴파일됩니다.

  2. 두 번째는 모든 "객체"파일을 연결하여 최종 이진 파일 (라이브러리 또는 실행 파일)을 만드는 것입니다.

HPP는이 모든 과정에서 어디에 적합합니까?

열악한 외로운 CPP 파일 ...

각 CPP 파일의 컴파일은 다른 모든 CPP 파일과 독립적이므로 A.CPP에 다음과 같이 B.CPP에 정의 된 기호가 필요한 경우 :

// A.CPP
void doSomething()
{
   doSomethingElse(); // Defined in B.CPP
}

// B.CPP
void doSomethingElse()
{
   // Etc.
}

A.CPP에 "doSomethingElse"가 존재하는지 알 수있는 방법이 없기 때문에 컴파일되지 않습니다. A.CPP에 다음과 같은 선언이없는 한 :

// A.CPP
void doSomethingElse() ; // From B.CPP

void doSomething()
{
   doSomethingElse() ; // Defined in B.CPP
}

그런 다음 동일한 기호를 사용하는 C.CPP가 있으면 선언을 복사 / 붙여 넣습니다.

복사 / 페이스트 경고!

예, 문제가 있습니다. 복사 / 붙여 넣기는 위험하며 유지 관리가 어렵습니다. 복사 / 붙여 넣기를하지 않고 심볼을 선언 할 수있는 방법이 있다면 시원 할 것입니다. 어떻게해야합니까? 일반적으로 .h, .hxx, .h ++ 또는 C ++ 파일에 선호되는 .hpp 접미사로 일부 텍스트 파일을 포함하면 다음과 같습니다.

// B.HPP (here, we decided to declare every symbol defined in B.CPP)
void doSomethingElse() ;

// A.CPP
#include "B.HPP"

void doSomething()
{
   doSomethingElse() ; // Defined in B.CPP
}

// B.CPP
#include "B.HPP"

void doSomethingElse()
{
   // Etc.
}

// C.CPP
#include "B.HPP"

void doSomethingAgain()
{
   doSomethingElse() ; // Defined in B.CPP
}

어떻게 include작동합니까?

파일을 포함하면 본질적으로 CPP 파일의 내용을 구문 분석 한 후 복사하여 붙여 넣습니다.

예를 들어 A.HPP 헤더가있는 다음 코드에서

// A.HPP
void someFunction();
void someOtherFunction();

... 원본 B.CPP :

// B.CPP
#include "A.HPP"

void doSomething()
{
   // Etc.
}

... 포함 후 :

// B.CPP
void someFunction();
void someOtherFunction();

void doSomething()
{
   // Etc.
}

한 가지 작은 것-왜 B.CPP에 B.HPP를 포함 시키는가?

현재의 경우에는 이것이 필요하지 않으며 B.HPP에는 doSomethingElse함수 선언이 있고 B.CPP에는 doSomethingElse함수 정의 (자체적으로 선언)가 있습니다. 그러나 B.HPP가 선언 (및 인라인 코드)에 사용되는보다 일반적인 경우에는 해당 정의 (예 : 열거 형, 일반 구조체 등)가 없으므로 B.CPP 인 경우 포함이 필요할 수 있습니다 B.HPP의 선언을 사용합니다. 대체로 소스가 기본적으로 헤더를 포함하는 것이 "좋은 맛"입니다.

결론

C ++ 컴파일러는 기호 선언 만 검색 할 수 없으므로 헤더 파일이 필요하므로 이러한 선언을 포함 시켜서이를 지원해야합니다.

마지막으로 한마디 : HPP 파일의 내용 주위에 헤더 가드를 두어야 여러 포함이 아무 것도 깨지지 않도록해야합니다. 그러나 HPP 파일이 존재하는 주된 이유는 위에 설명되어 있습니다.

#ifndef B_HPP_
#define B_HPP_

// The declarations in the B.hpp file

#endif // B_HPP_

개념이 시작된 C는 30 년이 지난 지금, 여러 파일의 코드를 서로 연결할 수있는 유일한 방법이었습니다.

오늘날 C ++에서 컴파일 시간을 완전히 없애고 무수한 의존성을 유발하는 끔찍한 해킹입니다 (헤더 파일의 클래스 정의가 구현에 대한 정보를 너무 많이 노출하기 때문에).


C ++에서 최종 실행 코드는 기호 정보를 전달하지 않기 때문에 다소 순수한 기계 코드입니다.

따라서 코드 자체와는 별도의 코드 인터페이스를 설명 할 방법이 필요합니다. 이 설명은 헤더 파일에 있습니다.


라이브러리 형식을 디자인 한 사람들은 C 전 처리기 매크로 및 함수 선언과 같이 거의 사용되지 않는 정보를위한 공간을 "폐기"하고 싶지 않기 때문입니다.

컴파일러에게 "이 기능은 나중에 링커가 작업을 수행 할 때 사용할 수 있습니다"라고 알리기 위해 해당 정보가 필요하기 때문에이 공유 정보를 저장할 수있는 두 번째 파일이 필요했습니다.

C / C ++ 이후의 대부분의 언어는이 정보를 출력 (예 : Java 바이트 코드)에 저장하거나 사전 컴파일 된 형식을 전혀 사용하지 않고 항상 소스 형식으로 배포되고 즉시 컴파일됩니다 (Python, Perl).


C ++은 C에서 상속했기 때문에 불행히도.


인터페이스를 선언하는 전 처리기 방식입니다. 인터페이스 (메소드 선언)를 헤더 파일에, 구현을 cpp에 넣습니다. 라이브러리를 사용하는 응용 프로그램은 인터페이스 만 알아야하며 #include를 통해 액세스 할 수 있습니다.


종종 전체 코드를 제공하지 않고도 인터페이스 정의를 원할 것입니다. 예를 들어, 공유 라이브러리가있는 경우 공유 라이브러리에 사용 된 모든 기능과 기호를 정의하는 헤더 파일이 제공됩니다. 헤더 파일이 없으면 소스를 배송해야합니다.

단일 프로젝트 내에서 헤더 파일은 IMHO라는 최소한 두 가지 목적으로 사용됩니다.

  • 명확성, 즉 인터페이스를 구현과 분리하여 유지하면 코드를보다 쉽게 ​​읽을 수 있습니다.
  • 컴파일 시간 가능한 경우 전체 구현 대신 인터페이스 만 사용하면 컴파일러에서 실제 코드를 구문 분석하는 대신 인터페이스를 참조 할 수 있기 때문에 컴파일 시간을 단축 할 수 있습니다 (이상적으로는 수행해야 함). 한 번).

에 응답 MadKeithV의 대답은 ,

이것은 의존성을 줄여서 헤더를 사용하는 코드가 구현의 모든 세부 사항과 그에 필요한 다른 클래스 / 헤더를 알아야 할 필요는 없습니다. 이렇게하면 컴파일 시간이 줄어들고 구현의 내용이 변경 될 때 필요한 재 컴파일 양도 줄어 듭니다.

또 다른 이유는 헤더가 각 클래스에 고유 한 ID를 제공하기 때문입니다.

우리가 같은 것을 가지고 있다면

class A {..};
class B : public A {...};

class C {
    include A.cpp;
    include B.cpp;
    .....
};

A는 B의 일부이므로 헤더를 사용하면 이러한 종류의 두통을 피할 수 있기 때문에 프로젝트를 빌드하려고 할 때 오류가 발생합니다.

참고 URL : https://stackoverflow.com/questions/333889/why-have-header-files-and-cpp-files



반응형