2011-11-02 3 views
10

C++과 Objective-C에서는 헤더에 정의 할 필요가없는 필요한 클래스를 전방 선언 한 다음 필요한 경우 소스 파일에 해당 클래스를 정의하는 헤더 파일을 가져 오는 습관을 들였습니다.전달 선언의 단점은 무엇입니까?

이것이 좋은 생각이 아닌 상황이 있습니까?

(전방 선언의 큰 단점은 불완전한 유형의 유용성이 제한된다는 것입니다.이 질문의 목적을 위해 헤더에서 불완전 유형으로 앞으로 선언 된 클래스 만 사용해야한다고 가정합니다.)

+17

전체 빌드 중에 커피를 마실 기회가 줄어 듭니? –

답변

6

때로는 미묘하게 위의 코드와 주석 코드가 헤더에 살고을 고려 오류

class Foo; 

template < typename T> 
struct Trait 
{ 
    static const int MY_TYPE = -1; 
}; 

// Lets say this is Foo.h 
//class Foo 
//{ 
//}; 
//template<> 
//struct Trait<Foo> 
//{ 
// static const int MY_TYPE = 1; 
//}; 

void TestFunction(Foo& f) 
{ 
    std::cout << Trait<Foo>::MY_TYPE << std::endl; 
} 

를 제기하지 않고 프로그램의 의미를 변경할 수 있습니다. 헤더가 포함 된 경우 TestFunction은 1을 인쇄합니다.

+0

+1 .. 아마도 OP의 생각 과정에 대해 내가 아는 것을 아는 내 의견보다 더 적합 할 것입니다. – Steve

+0

재미있는 것들. 그게 제가 궁금해했던 일입니다. – Luke

3

하나의 단점은 정보 숨기기/캡슐화의 부족 일 수 있습니다.

나는 가능한 최소한의 헤더 파일을 선호한다. 이는 내가 계속해서 많은 기능을 지원할 의무가 없다는 것을 의미합니다. 무언가를 변경하고 공개 머리글에 공개되지 않은 내용이 있으면 다른 사람에게 영향을주지 않고 클래스 내부에서 변경할 수있는 훨씬 더 좋은 기회가 있습니다.

는 편집 : 누가 복음은 예를 들어 요청

, 그래서 여기에 나중에 가서 :

Car라는 클래스가 있다고 가정하자. 그리고 당신이 그것을 위해 만든 유일한 것은 지점 A에서 B 지점으로 이동하는 것이 었습니다. 개인적으로 저는 헤더 파일을 Car이라는 클래스와 Drive이라는 메서드로 유지하려고합니다. 당신의 질문 ("내가 할 수있는 모든 수업")을 표현한 방식에서 나는 "DieselEngine", "PetrolEngine", "HybidEngine"등과 같은 클래스를 헤더 파일에서도 찾을 것으로 기대합니다. 이 문제는 프로젝트에서 일하는 다른 사람들 (또는 시간이 지남에 따라)이 노출 된 클래스를 사용하기 시작한다는 것입니다. 2 년 후, "당신은 PetrolEngine 클래스가 정말로 나를 위해 문제를 일으키고 있다고 생각합니다. 나는 그것을 제거하고 HybridEngine으로 완전히 대체 할 것입니다."- 이제는 PetrolEngine입니다. 당신이 이해하지 못하는 이유 때문에 100 개의 다른 파일에 둘러 쌓여 있습니다. 이제는 PetrolEngine을 사용하는 다른 모든 사람들에게 PetrolEngine을 사용하도록 강요 당합니다. 왜냐하면 당신이 그 수업을 처음부터 어떻게 사용했는지에 대한 견고한 "계약"을하지 않았기 때문입니다. 그것은 실제로 달성하고 싶었던 것의 구현 세부 사항이었습니다 - 자동차를 만드는 것.

EDIT 정보 은폐에 대한 의견 논의하기 : 당신이하고있는 모든 엄격 클래스/구조체 이름을 앞으로 선언하면

을 - 글쎄, 내가 "왜"다시 물어 것 같아요. 헤더 파일 및 클래스를 사용하는 소비자이고 해당 클래스에서 실제로 아무 것도 할 수 없으며 매개 변수 또는 주요 클래스 API의 반환 유형으로 표시되지 않는 이유는 무엇입니까? ?

불투명 한 데이터 구조에 대한 컴파일 타임 유형 안전 검사에이를 사용하는 경우 - 그게 한 가지입니다. 그러나 당신의 질문을 표현하는 방식으로 나는 의 모든 것을과 같은 것으로 만들었습니다. 물론 헤더 파일에 들어갔습니다.

+0

내가 무슨 뜻인지 잘 모르겠다. 예를 들어 주시겠습니까? – Luke

+4

이 기술로 정보 숨기기가 향상되지 않았습니까? 전방 선언에는 완전한 선언보다 훨씬 적은 정보가 있습니다. –

+2

전달 선언이 캡슐화를 중단시키는 방법을 설명해 주시겠습니까? 클래스 이름 만 제공하면 완전한 정의를 제공하는 것보다 훨씬 많은 정보가 숨겨지는 것 같습니다. –

0

아니요, 알고있는 한. 이미 다룬 유일한 단점은 불완전한 유형을 사용하는 것입니다. 완전히 정의 된 유형을 필요로하는 사용법은 없을 것이라고 말하기 때문에, 당신도 괜찮을 것입니다.

0

머리말에 클래스의 전체 정의가 필요하지 않은 경우 전방 선언이 전체 파일 포함보다 선호됩니다.내가 생각할 수있는 유일한 상 단점은 @Stephen Darlington이 이미 10 개의 상향 보를 줄 것이라는 의견으로 이미 게시 된 것입니다. :)

0

하나의 단점은 앞으로 선언 된 형식의 잠재적 인 메모리 누수입니다. 자세한 내용은 this question을 참조하십시오. 이 경우 Microsoft 컴파일러에서 warning C4150: deletion of pointer to incomplete type 'SomeType'; no destructor called을 실행합니다.

+2

실제 컴파일러에는 문제가 없습니다. –

2

전달 선언은 클래스, 함수, 전역 변수/상수 (extern 사용) 및 C++ 11의 열거 형에 적용될 수 있습니다.

중복성은 오류 범위를 더 많이 가져 오기 때문에 가장 큰 단점은 중복성입니다. 그러나 이는 앞으로 선언 할 내용에 따라 매우 다르게 적용됩니다.

클래스의 전방 선언, 전역 또는 열거 형에 오류가있는 경우 컴파일러에서 선택해야합니다 (예!).

함수 선언에 오류가있는 경우 C++에서 단순히 오버로드 (oups!)를 작성했습니다.

그러므로 클래스, 전역 또는 열거 형을 선언하는 것은 실제적인 단점이 없다고 말할 것입니다. 그러나 기능면에서 #include을 고수하면 더 많은 파일을 만들지 않도록 관련된 기능을 그룹화하는 헤더를 만들 수 있습니다.

0

아마도 대부분 코딩 작업을 계속해야하는 동료들에게는 쉽게 읽을 수있는 질문 일 것입니다.

관련 문제