문제

헤더 파일에서만 클래스를 선언하고 구현하는 것의 차이점이 있는지 궁금했습니다. 헤더에서 클래스를 제작하고 효과적인 .CPP 파일로 구현하는 일반적인 접근 방식과 비교할 때.

내가 말하는 내용을 더 잘 설명하기 위해 나는 정상적인 접근 방식의 차이를 의미합니다.

// File class.h
class MyClass 
{
private:
  //attributes
  public:
  void method1(...);
  void method2(...);
  ...
};

//file class.cpp
#include "class.h"

void MyClass::method1(...) 
{
  //implementation
}

void MyClass::method2(...) 
{
  //implementation
}

그리고 a 그냥 헤더 접근하다:

// File class.h
class MyClass 
{
private:
  //attributes
public:
  void method1(...) 
  {
      //implementation
  }

  void method2(...) 
  {
    //implementation
  }

  ...
};

주요 차이점을 얻을 수 있습니다. 두 번째 경우 코드는 동일한 구현의 더 많은 인스턴스를 생성 해야하는 다른 모든 파일에 포함되어있어 암시 적 중복성이 포함됩니다. 첫 번째 사례에서 코드는 자체적으로 컴파일되며 모든 호출은 MyClass 구현에 연결됩니다 class.cpp.

그러나 다른 차이점이 있습니까? 상황에 따라 다른 접근 방식을 사용하는 것이 더 편리합니까? 또한 메소드의 본문을 헤더 파일로 직접 정의하는 것은 컴파일러가 해당 메소드를 인화하도록 암시적인 요청임을 읽었습니다.

도움이 되었습니까?

해결책

주요 차이점은 멤버 기능 정의가 헤더 본문에있는 경우 해당 헤더를 포함하는 각 번역 장치에 대해 한 번 컴파일된다는 것입니다. 프로젝트에 수백 ~ 천명의 소스 파일이 포함되어 있고 해당 클래스가 상당히 널리 사용되는 경우, 이는 많은 반복을 의미 할 수 있습니다. 각 클래스가 2 개 또는 3 개의 다른 클래스에 의해서만 사용 되더라도 헤더에 코드가 많을수록 더 많은 작업을 수행 할 수 있습니다.

멤버 기능 정의가 자체의 번역 장치 (.CPP 파일)에 있으면 한 번 컴파일되며 함수 선언 만 여러 번 컴파일됩니다.

클래스 정의에서 정의 된 (선언 된 것이 아니라) 멤버 기능이 암시 적으로 의미가 있다는 것은 사실입니다. inline. 하지만 inline 사람들이 합리적으로 의미하는 바를 의미하지는 않습니다. inline 함수의 여러 정의가 다른 번역 단위로 나타나고 나중에 함께 연결되는 것이 합법적이라고 말합니다. 클래스가 다른 소스 파일을 사용할 헤더 파일에있는 경우에 필요하므로 언어가 도움이되기 위해 노력합니다.

inline 또한 컴파일러에 대한 힌트는 함수가 유용하게 상환 될 수 있지만 이름에도 불구하고 선택 사항입니다. 컴파일러가 더 정교할수록 인라인에 대한 자체 결정을 내릴 수 있고 힌트에 대한 필요성이 줄어 듭니다. 실제 인라인 태그보다 더 중요한 것은 컴파일러가 기능을 사용할 수 있는지 여부입니다. 함수가 다른 번역 장치에 정의되면 호출을 컴파일 할 때 사용할 수 없으므로 호출을 인화하려면 호출이 아닌 링커가되어야합니다.

세 번째 가능한 방법을 고려하여 차이점을 더 잘 볼 수 있습니다.

// File class.h
class MyClass
{
    private:
        //attributes
    public:
       void method1(...);
       void method2(...);
       ...
};

inline void MyClass::method1(...)
{
     //implementation
}

inline void MyClass::method2(...)
{
     //implementation
}

암시 적 인라인이 방해가되지 않았 으므로이 "모든 헤더"접근 방식과 "헤더 플러스 소스"접근 방식 사이에는 약간의 차이가 남아 있습니다. 번역 단위로 코드를 나누는 방법은 구축 된 상황에 영향을 미칩니다.

다른 팁

예, 컴파일러는 다음과 같은 헤더 파일에서 직접 선언 된 메소드를 인라인하려고합니다.

class A
{
 public:
   void method()
   {
   }
};

헤더 파일의 구현을 분리 할 때 다음과 같은 편의 시설을 생각할 수 있습니다.

  1. 동일한 코드가 여러 번역 장치에 포함되어 있기 때문에 코드 블로트가 없습니다.
  2. 편집 시간은 급격히 줄어 듭니다. 헤더 파일 컴파일러의 모든 수정에 대해서는 직간접 적으로 포함하는 다른 모든 파일을 빌드해야합니다. 헤더 파일에 공간을 추가하기 위해 전체 바이너리를 다시 빌드하는 것이 매우 실망 스러울 것 같아요.

구현이 포함 된 헤더로 변경하면 해당 헤더가 포함 된 다른 모든 클래스가 재고 컴파일 및 Relink를 강제합니다.

헤더는 구현보다 덜 자주 변경되므로 구현을 별도의 파일에 넣어 상당한 컴파일 시간을 절약 할 수 있습니다.

다른 답변이 이미 지적했듯이, 파일 내에서 메소드를 정의합니다. class 블록으로 인해 컴파일러가 인라인이 발생합니다.

예, 클래스 정의 내부에서 메소드를 정의하는 것은 그들을 선언하는 것과 같습니다. inline. 다른 차이는 없습니다. 헤더 파일의 모든 것을 정의하는 데 이점이 없습니다.

템플릿 멤버 정의는 헤더 파일에도 포함되어야하므로 템플릿 클래스가있는 C ++에서 일반적으로 표시됩니다 (대부분의 컴파일러가 지원하지 않기 때문에 템플릿 멤버 정의도 포함되어야합니다. export). 그러나 평범한 비 테인 플레이트 클래스에서는 방법을 inline.

저에게 주된 차이점은 헤더 파일이 클래스의 "인터페이스"와 같다는 것입니다. 클라이언트의 특정 구현에 대해 걱정하지 않고 해당 클래스의 클라이언트에게 공개 방법 (지원하는 운영)을 알려줍니다. 의미에서, CPP 파일 만 변경하므로 컴파일 시간이 훨씬 적기 때문에 클라이언트를 구현 변경으로부터 캡슐화하는 방법입니다.

과거에 나는 다양한 CORBA 분포의 차이점에서 모듈 차폐를 만들었으며 다양한 OS/컴파일러/CORBA LIB 조합에서 균일하게 작동 할 것으로 예상되었습니다. 헤더 파일로 구현하면 간단한 포함 된 프로젝트에 더 쉽게 추가 할 수있었습니다. 동일한 기술은 코드가 다른 라이브러리 또는 다른 OS로 컴파일 될 때 재 컴파일이 필요할 때 코드가 동시에 재 컴파일되었음을 보장했습니다.

따라서 내 요점은 여러 프로젝트에서 재사용 가능하고 고려할 수있는 작은 라이브러리가 있다면 헤더가 메인 프로젝트에 추가 파일을 추가하거나 외부 LIB를 다시 컴파일하는 것과는 달리 다른 프로젝트와의 통합에 이점을 제공한다는 것입니다. /obj 파일.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top