왜 비공개 회원을 헤더에 넣어야합니까?


62

개인 변수는 클래스 사용자에게 복잡성과 구현 세부 사항을 숨기는 방법입니다. 이것은 다소 좋은 기능입니다. 그러나 C ++에서 왜 클래스 헤더에 그것들을 넣어야하는지 이해하지 못합니다. 나는 이것에 대한 두 가지 성가신 단점을 봅니다.

  • 사용자의 헤더를 어지럽게 만듭니다.
  • 내부를 수정할 때마다 모든 클라이언트 라이브러리를 강제로 다시 컴파일합니다.

이 요구 사항 뒤에 개념적 이유가 있습니까? 컴파일러에서 작업을 용이하게하는 것입니까?


당신은 헤더에 빈 구조체를 선언 할 수 있지만, 구조체를 사용할 때만 구조체에 대한 포인터를 사용할 수 있습니다 (그리고 할당 할 수 없습니다)
ratchet freak

3
@ratchetfreak : 아니요, 빈 ( struct foo{};)은 허용되지 않지만 정방향 선언 ( struct foo;)은 허용 됩니다.
MSalters

@MSalters 그게 내가 의미하는 것
ratchet freak

1
단점을 추가하겠습니다. * .h 파일에 개인 함수 헤더를 작성하는 것은 많은 시간 낭비입니다. (잠깐 친구 수업 잊어 버림)
Jonny

답변:


68

인스턴스화 할 때 적절한 양의 메모리를 할당하려면 C ++ 컴파일러가 클래스의 실제 크기를 알아야하기 때문입니다. 그리고 크기에는 모든 회원뿐만 아니라 개인 회원도 포함됩니다.

이를 피하는 한 가지 방법은 Herb Sutter가 그의 Week of the Week 시리즈 # 24# 28 에서 설명한 Pimpl 관용구를 사용하는 입니다.

최신 정보

실제로 이것은 (또는 일반적으로 헤더 / 소스 파일 구별 및 #includes) C에서 상속 된 C ++의 주요 장애물입니다. C ++ C가 만들어진 시절 에는 대규모 소프트웨어 개발에 대한 경험이 없었습니다. 실제 문제를 일으키기 시작합니다. 그 이후에 배운 교훈은 새로운 언어의 설계자들에 의해 이어졌지만 C ++은 이전 버전과의 호환성 요구 사항에 묶여있어 언어의 근본적인 문제를 해결하기가 정말로 어렵습니다.


이런 종류의 정보는 클래스 라이브러리에만 포함되어 있지 않습니까? 연결에 사용됩니까?
Simon Bergot

@Simon, "클래스 라이브러리"란 무엇을 의미합니까?
Péter Török

클래스 정의와 메소드를 포함하는 객체 파일 모음을 의미합니다
Simon Bergot

7
C ++가 만들어 졌을 때 AT & T / Bell Labs (당시 Stroustrups 고용주)은 대규모 C 개발 경험이있었습니다. 그들의 5ESS 전화 스위치 소프트웨어는 아마도 세계에서 가장 큰 단일 C 프로그램 일 것입니다. OO에 대한 초기 아이디어는 이미 해당 코드 기반에서 볼 수 있으며 Cfront는 이러한 기술을 모방했습니다. 그러나 개념 private은 더 현대적입니다.
MSalters

1
C에서는 할당자를 라이브러리 함수에두기 만하면됩니다. 클라이언트는 그러한 구조를 전혀 할당 할 수 없습니다. 이로 인해 오버 헤드가 약간 증가하지만 여러 버전에서 코드를 마이그레이션하는 것이 쉽지 않으므로 종종 가치가 있습니다. 그러나 C ++에서 볼 수있는 코드 스타일과는 매우 다른 코드 스타일을 만드는 경향이 있습니다.
Donal Fellows

15

클래스 정의는 클래스의 객체를 사용한 어디에서나 컴파일러가 메모리에서 동일한 레이아웃을 생성하기에 충분해야합니다. 예를 들어, 다음과 같은 것이 주어집니다 :

class X { 
    int a;
public:
    int b;
};

컴파일러는 일반적으로 한 것 a에서 0 오프셋 및 b오프셋 4. 컴파일러가 이것을 다음과 같이 본다면 :

class X { 
public:
    int b;
};

b오프셋 4 대신 오프셋 0에있는 것으로 "생각"합니다. 해당 정의를 할당 한 b코드가에 할당 되면 첫 번째 정의를 사용하는 코드 a가 수정 된 것 입니다.

클래스의 개인 부분에 대한 변경으로 인한 영향을 최소화하는 일반적인 방법을 일반적으로 pimpl 관용구라고합니다 (Google에서 많은 정보를 제공 할 수 있다고 확신합니다).


1
디자인 결정에 대해 묻고 있습니다. 물론 언어가 작동하려면 개인 회원 선언을 어딘가에 두어야합니다. 그러나 왜 더 개인적인 장소가 아닌 헤더에 있어야합니까?
Simon Bergot

7
@Simon : 헤더는 클래스 / 구조체의 모양을 알려주기 위해 컴파일러가 보는 모든 것입니다. C ++에 모듈과 같은 것을 추가하는 것에 대한 논의가 있었는데, 이러한 종류의 데이터를 조금 더 숨길 수는 있지만 지금까지는 승인되지 않았습니다 (완전히 삭제되지는 않았지만).
Jerry Coffin

3
그럼에도 불구하고 사소한 규칙은 이러한 ".cpp 정의"개인 구성원을 마지막에 할당하는 것입니다. 즉, 공개 및 "정상"개인 구성원의 상쇄는 그들에 의존하지 않을 것입니다. IMO의 진정한 이유는 파생 된 부분이 개인 구성원을 따라야하기 때문에 그러한 클래스에서 상속받을 수 없기 때문입니다.
MSalters

3

여러 가지 이유가있을 수 있습니다. 개인 회원은 대부분의 다른 수업에서 액세스 할 수 없지만 친구 수업에서는 계속 액세스 할 수 있습니다. 따라서 적어도이 경우 헤더에 필요할 수 있으므로 친구 클래스가 존재하는지 볼 수 있습니다.

종속 파일의 재 컴파일은 포함 구조에 따라 달라질 수 있습니다. 다른 헤더 대신 .cpp 파일에 .h 파일을 포함하면 경우에 따라 긴 재 컴파일 체인을 막을 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.