2013-10-10 3 views
0

오늘은 내가 .I이 책은 말한다 problem.as, G ++ 객체 모델

class Concrete1 { 
public: 
int val; 
char bit1; 
}; 

class Concrete2 : public Concrete1 { 
public: 
char bit2; 
}; 

class Concrete3 : public Concrete2 { 
public: 
char bit3; 
}; 

내가와 Mingw g ++에서 코드를 실행

발생>는 <을 읽고, 세 종류의 공간은 8, 12, 12.Bs2012에서 코드를 실행할 때 세 클래스의 공간은 8, 12, 16입니다. 소스 코드의 경우 vs2012의 코드는 문제가 없습니다. 그러나 g ++의 공간에 대해서는 몇 가지 질문이 있습니다. 문제가 있는지 확인하기 위해 샘플 코드를 작성하십시오. 샘플 코드는 다음과 같이
int main(void) 
{ 
    Concrete2 con2; 
    memset(&con2, 0, sizeof(con2)); 
    Concrete3 con3; 
    con3.val = 3; 
    con3.bit2 = 4; 
    con3.bit3 = 5; 
    Concrete2* con_ptr2 = &con2; 
    Concrete2* con_ptr3 = &con3; 
    *con_ptr3 = *con_ptr2; 
    cout << con3.bit3<< endl; 
    cout << sizeof(Concrete1) << endl; 
    cout << sizeof(Concrete2) << endl; 
    cout << sizeof(Concrete3) << endl; 
    return 0; 
} 

과 ++ g의 객체 모델

이 코드는 코드가 끝난하지만 문제 함께 "* con_ptr3 = * con_ptr2;"상기 con3.bit3 5 0이 아닌? 누구든지 나를 도울 수 있습니까?

+0

단계별로 단계별로 중단 점을 설정하십시오. – nhgrif

+0

내가 hava 중단 점을 설정하고 결과를 설명하는 방법을 모르겠 result.But을 봤어! – user2861706

+0

모든 행의 모든 ​​포인터와 변수의 값은 무엇입니까? – nhgrif

답변

0

결과가 맞으면 bit3은 5가되어야합니다. 할당은 con3의 Concrete1 및 Concrete2 부분에만 영향을주기 때문입니다.

할당은 바이트 단위가 아닌 구성원 단위입니다. 그래서 "* com_ptr3 = * con_ptr2"는 "memcpy (con_ptr3, con_ptr2, sizeof (Concrete2))"와 동일하지 않습니다. 기본 복사 생성자와 기본 할당 연산자는 구성원별로 데이터를 memberwise로 복사해야합니다 클래스에서 정의됩니다. 이것은 또한 특정 값을 갖는 패딩 바이트를 셀 수 없다는 것을 의미합니다.

크기 차이는 VS와 gcc가 약간 다른 패딩을 처리하기 때문입니다. gcc는 bit32와 bit3을 동일한 32 비트 단어로 팩할 수 있지만 VS는 그렇지 않습니다. gcc도 bit1을 pack 할 수 없기 때문에 size 8,8,8로 이어진다.

gcc는 Concrete1을 POD로 간주하지만 Concrete 2와 3은 그렇지 않기 때문일 수 있습니다. 이 표준에는 POD 유형이 아닌 데이터 유형에 비해 데이터 레이아웃 방식에 대한 엄격한 요구 사항이 있습니다. 컴파일러는 비 포드 (non-pod) 유형에 대한 클래스 데이터 레이아웃에서보다 유연합니다.