왜 C ++에서 클래스의 크기가 데이터 멤버의 공개 / 개인 상태에 의존합니까?


23

내가 아는 것에서 C ++의 클래스 크기는 아래 요인에 따라 다릅니다.

  1. 모든 비 정적 데이터 멤버의 크기
  2. 데이터 멤버의 순서.
  3. 바이트 패딩이 사용 가능한지 여부
  4. 바로 기본 클래스의 크기입니다.
  5. 가상 기능의 존재.
  6. 상속 모드 (가상 상속).

이제 아래와 같이 2 개의 클래스를 만들었습니다.

class A{
    int a;
    short s;
    int b;
    char d;
};// kept a char at last on purpose to leave a "hole"

class B : public A{
    char c;  
};

이제 A와 BI의 크기를 확인하십시오.

  • A의 크기 : 16
  • B 사이즈 : 16

내 가정은 클래스 B의 문자 c가 클래스 A의 "구멍"에 수용된다는 것입니다.

그러나 나를 혼란스럽게하는 것은 회원을 공개하는 아래 시나리오입니다.

class A{
    public:
    int a;
    short d;
    int b;
    char s;
};

class B : public A{
    public:
    char c;
};

이제 크기는

  • A의 크기 : 16
  • B의 크기 : 20

이 차이의 이유를 이해할 수없는 것 같습니다.


1
왜 C ++에서 클래스의 크기가 데이터 멤버의 공개 / 개인 상태에 의존합니까? -그렇지 않습니다. 이것들은 컴파일러에 따라 구현되는 세부 사항입니다.
PaulMcKenzie

1
그래서 어떤 컴파일러를 사용하고 있습니까?
Romen

2
@PaulMcKenzie 사실 그렇습니다. 표준은 동일한 액세스 권한을 가진 멤버를 그룹화하여 컴파일러의 패딩 전략을 변경하도록 변경합니다.
NathanOliver

@ NathanOliver-ReinstateMonica, 나는 그것을 몰랐다. 관련 섹션을 참조 할 수 있습니까?
R Sahu

@RSahu 내 대답을 꽉 채울 때까지 찾고 있습니다.
NathanOliver

답변:


8

Itanium ABI 는 POD의 C ++ 03 정의를 사용하여 "레이아웃을위한 POP"인 클래스를 정의합니다. 개인 데이터 멤버가 있으면 클래스가 C ++ 03의 집계 및 POD가 될 수 없습니다.

POD-구조체 형 비 POD-구조체 비 POD-조합 (또는 유형의 배열) 또는 기준의 어떠한 비 정적 데이터 멤버가없는 집합 클래스 없으며 사용자 정의 복사 할당 연산자가없고 아무런 사용자 정의 소멸자.

POD 클래스이므로 테일 패딩 재사용이 비활성화됩니다 .

이러한 유형의 dsize, nvsize 및 nvalign은 일반적인 크기 및 정렬로 정의됩니다. 이러한 속성은 기본 클래스로 사용되는 비어 있지 않은 클래스 유형에만 중요합니다. 우리는 표준의 초기 버전이 다른 어떤 용도로도 그것을 사용할 수 없었고 때로는 더 빠른 유형의 복사를 허용하기 때문에 POD에 대한 테일 패딩을 무시합니다.

따라서 첫 번째 예에서는 A레이아웃 목적으로 POD가 아니고 테일 패딩을 사용할 수 B::c있지만 두 번째 예에서는 POD이며 테일 패딩을 재사용 할 수 없습니다.

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