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


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.