2012-06-05 4 views
0

하위 객체에 vptr에서의 존재, 및 이로부터 파생 된 클래스 :I 그것에 VTPR 해당 가상 소멸자 가지는 클래스 '기부'과 이에 VTABLE하고있다

class base { 
public: 
    virtual ~base() {} 
}; 

class der : base {}; 

main() 
{ 

    int a = sizeof(base); // = 4 , fine ! 

    int b = sizeof(der); // = 4 too ? 
} 

지금 파생 된 클래스가 너무 가상 그대로 그것 자체의 VPTR을 가지지 만 VPTR을 가진 기본 클래스의 하위 객체를 가지고 있기 때문에 'der'클래스의 크기가 8 바이트가되어서는 안됩니다. 즉, VPTR의 크기는 class 'der'+ 'base'클래스의 하위 객체의 VPTR 크기? (sizeof (void *) = 4 바이트 일 때).

기본적으로 내 질문은 : '기본'클래스의 하위 개체가 'der'에서 만들어지면 별도의 새 VPTR이 생성됩니까? 그리고 그것이 그렇다면 왜 'der'의 크기를 계산하는 동안 그 크기가 추가되지 않는 이유는 무엇입니까?

누군가가이를 분명히 할 수 있습니까?

+0

vptr을 파생 클래스에 복제하면 vptrs의 목적을 완전히 상실하게됩니다. 즉,'base' 포인터로'der' 인스턴스를 조작 할 때 구현의 파생 된 부분에서 vptr을 가져 오는 것으로 가정됩니다. 그 물체? 그러나 객체가 여러 다형성 기본 클래스에서 상속 받으면 객체는 여러 개의 vptr을 가질 수 있습니다. struct A {virtual ~ A() {}}; struct B {가상 ~ B() {}}; struct C : A, B {};'. 일부 (대부분?) 구현에서 C는 두 개의 vptrs를 가지며, 하나는'A' 하위 객체에 있고 다른 하나는'B' 하위 객체에 있습니다. –

+1

위의 구조체 C는 분명히 두 개의 VPTR을 가지지 만 하위 객체 (예 : U)에있는 대신이 VPTR이 클래스 C 자체에 있으면 안됩니다. 그렇지 않았기 때문에 구현이 가정된다고 어떻게 알 수 있습니까? 객체의 파생 부분에서 vptr을 가져 오려면? – cirronimbo

답변

4

이것은 모두 구현에 따라 다릅니다. 그러나 실제로는 파생 된 클래스에 vptr이 하나만 있습니다. 두 가지 필요는 없습니다. vptr의 핵심은 가상 함수의 올바른 재정의를 동적으로 호출하는 데 사용되는 것입니다. der 개체는 단순히 base 개체와 다른 포인터 값을 갖습니다.

는 [참고 : 예는 아마 당신이 있다는 사실에 의해 혼란 오히려 전형적인 대중 상속보다, 개인 상속을 사용하여 ... (실수?)]

+0

공개 상속을 사용하지 않았습니다. 내가 아는 한 내가 묻는 것은 아무런 차이가 없었기 때문입니다. 죄송합니다. 답변을 얻을 수 없습니다. 내가 물어 본 것은 '기본'의 하위 오브젝트에서 VPTR에 관한 것입니다. – cirronimbo

+0

cirronimmplo : 그는 파생 클래스가 기본 클래스에 대한 가상 ptr을 필요로하지 않으므로 파생 클래스의 vptr이이를 덮어 씁니다. –

+0

@cirronimbo :'base' 객체가 있다면 vptr은 vtable에서'base'를 가리 킵니다. 'der' 객체를 가지고 있다면, vptr은 vtable에서'der'를 가리킨다. –

2

난 당신이 vtable을 혼란 것 같아요 및 vptrs. 각 클래스에는 vtable이 있고 각 객체에는 해당 vtable에 대한 포인터가 vptr로 저장됩니다. vtable은 정적 전역과 비슷하며 클래스의 모든 인스턴스간에 공유되므로 개체에 공간을 차지하지 않습니다.