2017-10-31 8 views
2

간단한 템플릿 기반 모듈 기반 헤더 라이브러리를 작성했습니다. 모듈 기반의 경우, string.h 또는 dynarray.h 만 포함 할 수 있으며 헤더는 모든 종속성을 끌어 당깁니다.모듈 기반 라이브러리에 자체 고정 블로킹 포함

이제이 시스템의 작동 방식 때문에 누락 된 유형의 문제가 있습니다. 모듈을 수행합니다

  • #include 모든 종속성
  • 인터페이스 class Foo
  • #include에게

불행하게도, 어떤 상황에서, 두 개의 인터페이스를 사용할 수 있어야 구현 파일을 정의 어떤 구현을 포함하여 전 . 여기 문제가 무산 :

string.h를

#pragma once 

// A string depends on a DynArray. 
#include "dynarray.h" 

template<typename E> 
class String { 
public: 
    DynArray<E> arr; 
    /* ... */ 
}; 

// Include the implementation of all the different functions (irrelevant here) 
#include "string_impl.h" 

dynarray.h

#pragma once 

// The dynarray header has no direct dependencies 

template<typename E> 
class DynArray { 
public: 
    /* ... */ 
    E& Get(int index); 
}; 

// Include the implementation of all the different functions 
#include "dynarray_impl.h" 

dynarray_impl.h

#pragma once 

// The dynarray implementation needs the OutOfRangeException class 
#include "out_of_range_exception.h" 

template<typename E> 
E& DynArray<E>::Get(int index) { 
    if (index >= size) { 
     throw OutOfRangeException("Some error message"); 
    } 
} 

class OutOfRangeException { 
public: 
    String message; 
    OutOfRangeException(String message) { 
     /* ... */ 
    } 
}; 
out_of_range_exception.h

string.h을 어딘가에 포함하면 모듈 구현이 포함되므로 dynarray_impl.hout_of_range_exception.h의 내용이 문자열 클래스 인터페이스 앞에옵니다. 따라서 StringOutOfRangeException에 정의되어 있지 않습니다.

분명히 해결 방법은 문자열 인터페이스의 정의 이후에 dynarray (dynarr_impl.h)의 구현 부분 만 지연시키는 것입니다. 문제는 모듈 기반 접근 방식과 호환되지 않는 일종의 공통 헤더 파일을 만들지 않고 어떻게해야하는지 잘 모르는 것입니다.

답변

2

문제는 인터페이스와 구현 모두에 대해 하나의 파일이 있다는 것입니다. 해당 파일을 보내고

#include은 모두 X의 인터페이스와

때때로 당신은 그냥 X의 인터페이스에 의존 할 X의 구현에 따라 나타내는

X 인터페이스 :

  • #include 인터페이스의 모든 종속성
  • class X 인터페이스를 정의하십시오.

X 구현 :

  • #include 인터페이스
  • #include 구현
  • 의 모든 종속성은 class X의 구현을 정의합니다.

어떤 의미에서 이들은 하나의 모듈이 다른 모듈에 의존하는 두 개의 개별 모듈입니다. 이를 통해 클라이언트는 다른 유형의 인터페이스에만 의존하거나 구현 유형에만 의존하거나 인터페이스에서 먼저, 그리고 구현에서 나중에 의존 할 수 있습니다.

일반적으로 구현의 순환 종속성이있는 경우를 제외하고는 #include "X.h" 일 수 있습니다. 당신이 정말로 하나의 헤더 파일을 사용하려면 다음 어딘가에 당신이 #include "X_interface.h"


와 체인을 깰 필요가, 당신은 멀리 #pragma once로 할 수 있으며, "두 가지 모드"에 포함 할 수있는 헤더 파일했다. 이러한 메커니즘을 사용하면 컴파일러가 파일을 열어 코드가 있는지를 확인해야하기 때문에 빌드 시간이 많이 느려질 수 있습니다. 대부분의 컴파일러는 #ifdef 헤더 가드와 #pragma once을 감지하고 관심이없는 파일을 다시 열지 않도록 할 수 있습니다. 그러나 멋진 "여러 모드로 여러 번 포함될 수 있습니다"헤더 파일은이 기술로 처리 할 수 ​​없습니다.