2010-12-02 4 views
4
#include <iostream> 
struct Base1 
{ 
public: 
    virtual void show()=0; 
}; 
struct Base2 
{ 
public: 
    virtual void Display()=0; 
}; 
class Derived:virtual public Base1,virtual public Base2 
{ 
public: 
    virtual void show(){} 
    virtual void Display(){} 

}; 
void main() 
{ 
    using namespace std; 
    cout<<sizeof(Derived); 
} 

출력 12 를 도시하지만 Dervied 클래스 즉 소멸자를 삽입 할 때 그 때 출력으로 20 보이고 코드를다중 상속의 경우 파생 클래스의 크기가 증가하는 다형성의 경우 측면 파생 클래스의 소멸자에 대한 코드 작성. 왜?

#include <iostream> 
struct Base1 
{ 
public: 
    virtual void show()=0; 
}; 
struct Base2 
{ 
public: 
    virtual void Display()=0; 
}; 
class Derived:virtual public Base1,virtual public Base2 
{ 
public: 
    virtual void show(){} 
    virtual void Display(){} 
     ~Derived(){} 


}; 
void main() 
{ 
    using namespace std; 
    cout<<sizeof(Derived); 
} 

을 따르고있다. 왜?

+0

중요하지는 않지만 어떤 컴파일러에서 재현됩니까? – sharptooth

+0

@sharptooth : - 프로그램을 실행할 때마다 동일한 결과를 보여줍니다. – Suri

+0

Tried Visual C++ 9? – sharptooth

답변

1

1) 기본 클래스에는 가상 소멸자가 없습니다.
2) 메인 리턴 int, void가 아님

구현 정의가 무엇인지 묻습니다. g ++ 4.3.0을 사용하면 두 경우 모두 동일한 크기가됩니다 (8 비트는 32 비트 PC에서 좋은 결과를 얻어야합니다).

편집

정의 구현에서, 나는 그것이 가상 상속 구현 방법에 따라 달라집니다 의미했다. 일반적으로 파생 클래스는 기본 클래스에 대한 포인터를 포함하지만 필요는 없습니다.

g ++의 경우 모든 하위 객체 (기본 클래스에 대한 포인터)의 주소를 가져올 수 있으려면 Derived의 크기는 (32 비트 시스템에서) 12 바이트가되어야하지만 모든 클래스가 비어있는 경우 (즉, 멤버 변수가없는 경우) 컴파일러는 빈 기본 클래스의 크기를 자유롭게 최적화하고 두 기본 클래스의 다른 주소를 제공 할 수 있어야하기 때문에 크기를 8 바이트로 줄입니다 (4 바이트가 아님).).

+0

에서 작업 중입니다. 구현 정의 된 경우 gcc 설명서의 어딘가에 문서화되어야합니다. 너는 그것을 꺼낼 수 있니? – Chubsdad

+0

각 클래스에 가상 ~ Base1() 및 가상 ~ Base2()를 추가했습니다. 결과가 ~ Dervied()가 없을 때 12가 표시되고, 20.i가 표시되면 20.i가 Visual vC++ 9.0에서 작동합니다. – Suri

+0

@ Chubsdad gcc 설명서에서 문제를 발견했지만 g ++에서 상속이 어떻게 구현되는지 설명합니다. 구현은 vc9와 비슷해야합니다. –

0

음, 생성 된 코드를보고 첫 번째 예는이 메모리 레이아웃이 있습니다

| Derived::vtable | Base1::vtable | Base2::vtable | 

두 번째는이 레이아웃이 있습니다

| Derived::vtable | 00 00 00 00 | Base1::vtable | 00 00 00 00 | 
| Base2::vtable | 

내가 모르는 제로는 무엇인가. 패딩은 CCCCCCCC으로 초기화되지 않은 채로 남아 있기 때문에 이 아닌 패딩입니다. 어쩌면 가상 하위 객체를 삭제할 때 카운터 또는 플래그로 사용되며 소멸자를 추가하면 이러한 필드가 클래스에 추가됩니다. 나는 그것들을 00000000과 다른 것으로 만드는 데 실패했다.

어쨌든, 당신은 당신의 질문에이를 추가 할 수 있습니다 : 왜 소멸자 virtual 다음 레이아웃이

| Derived::vtable | 00 00 00 00 | Base1::vtable | 00 00 00 00 | 
| Base2::vtable |  padding  | 

(24 바이트)하게 할 때?

관련 문제