2011-09-26 5 views
2

이 질문은 this one과 관련됩니다.POD 구조체에서 상속받은 클래스의 기본 생성자의 이상한 동작

이전 질문에서 언급 한 것처럼 Win 구조 BITMAP에서 내 클래스를 상속하여 확장 된 기능을 제공하기로 결정했습니다.

나는 컴파일 된 프로그램 동작에 관심을 기울였다. 우선 아래처럼 내 클래스에 대한 기본 생성자를 정의 : 아이디어 컴파일러에서

CPreviewFrame::CPreviewFrame(): 
    m_bufferSize(0) 
{ 
    bmBits = NULL; //ensure that compiler in debug won't init it with 0xccccc... and delete[] will do the job 
} 

는이 초기화 목록에서 수동으로 호출되지 않은 경우에도 기본 유형에 대한 기본 생성자를 호출하는 코드를 생성했다. 그러나 디버깅하는 동안 BITMAP의 데이터 멤버가 초기화되지 않은 것으로 나타났습니다! BITMAP에 대한 수동 초기화를 추가하면 모든 데이터 멤버가 0으로 초기화됩니다.

CPreviewFrame::CPreviewFrame(): 
    BITMAP(), 
    m_bufferSize(0) 
{ 
    //bmBits = NULL; //it's not needed anymore probably 
} 

왜 그런가? 컴파일러가 기본 생성자를 호출 할 의무가 없거나 클래스에만 적용됩니까? (그것은 그렇게 생각할 수 없습니다 - 유일한 차이점은 회원과 상속에 대한 기본 액세스 한정자입니다)

답변

4

POD 구조체에 명시적인 이니셜 라이저를 제공하지 않으면 객체의 불확정 초기 값이 C++ 표준의 8.5/9 절 에 대한 이니셜 라이저 (즉, CPreviewFrame 생성자 값의 초기화 자 목록에 괄호가 있음)를 추가하면 섹션 8.5/7에 따라 BITMAP 객체가 초기화됩니다. 8.5/5 절에 따르면 BITMAP의 모든 비 정적 멤버는 배열, 공용체 또는 클래스 유형이 아니므로 0으로 초기화된다는 것을 의미합니다. 최초의 예에서

하지만, 당신은 단지 CPreviewFrame 생성자 ... 아니 초기화 이후 확정 된 값으로 BITMAP의 데이터 멤버의 나머지 부분을 잎의 실제 본문에 BITMAP 구조의 bmBits 멤버를 초기화 BITMAP 구조 자체에 대해 지정되었습니다. 클래스의 각 비 정적 데이터 멤버가 생성자의 실제 본문이 호출되기 전에 초기화되므로 CPreviewFrame 클래스의 비 정적 POD 구조체 데이터 멤버 인 BITMAP에 대한 명시 적 이니셜 라이저의 부재는 다음을 의미합니다. 값이 불명확 한 초기 값으로 설정되는 8.5/9에 기술 된 행동이 효력을 발생한다는 것.