2010-05-21 5 views
3

vptr이 vtable 기본 주소를 얻는 방법을 알고 싶었습니다. vptr에서가의 일환으로 컴파일러가 생성 한 코드에 의해 초기화됩니다Vptr의 의심 - Vtable 주소를 얻는 방법을 알고 싶습니다.

+0

huh? 컴파일러가 vtable 주소를 아는 방법을 묻고 있습니까? –

+0

컴파일러는 vtable을 사용하지 않을 수도 있습니다. vtable을 사용해야하는 C++ 표준은 없습니다. –

답변

1

사전에 내가이 비밀을 알고 싶어

A obj; /// here vptr getting vtable's base address. 

예를 지금

class A 
{ 
virtual getdata(); 
int a; 
} 

에 대한

.. 감사합니다 obj의 초기화 마술은 그냥과 같이 할당합니다, 여기에 없습니다 :

struct __A_vtbl_def { 
    void (*getdata)(__A*); 
}; 

__A_vtbl_def __A_vtbl = { 
    &A__getdata 
}; 

struct __A { 
    __A_vtbl_def* vptr; 
    int a; 
}; 

__A obj; 
obj.vptr = &__A_vtbl; 

참고 :이 모든 컴파일러가 vptr에서을 구현하는 방법을 보여주는 코드를 척이다. 요즘 실제 코드 컴파일러가 뱉어내는 것이 무엇인지 전혀 알지 못합니다.

1

이것은 C++ 질문이 아니며 C++에 vtable 또는 vptr이 없으며 일부 벤더는 vtable을 사용하여 가상 함수를 구현하지만 완전히 구현에 따라 다릅니다.

+1

실제 "모든"컴파일러는 vtable을 사용하지만 질문은 완벽하게 합법적이라고 생각합니다. –

+1

음, vtable에 대한 가정이 있습니다. 가능한 한 대부분의 컴파일러는 모든 가상 함수를 단일 테이블에 넣을 수는 없습니다. 많은 사람들이 복잡한 유형의 여러 vtable을 생성합니다. 이 시점에서 실제 질문이 발생합니다 : 런타임이 올바른 것을 선택하는 방법? – MSalters

+0

@MSalters 실제로이 작업을 수행하는 단일 컴파일러를 알고 있습니까? 그렇다면 런타임시 어떻게 해결할 수 있습니까? –

1

A의 생성자는 vtable 포인터가 올바른 vtable을 가리 키도록 자동으로 초기화합니다. 여기에 특정 예를 들어 내 컴파일러에 의해 생성 된 어셈블리 코드의 조각은 (이 A::A에서입니다)입니다 :

004114A3 mov   eax,dword ptr [this] 
004114A6 mov   dword ptr [eax],offset A::`vftable' (415740h) 

컴파일러가 코드를 생성 볼 수 있듯이 그의 시작 부분에 복사 클래스 A에 대한 vftable 포인터를 인스턴스.

+0

+1은 일반적으로 ctor에 코드가 추가되었음을 나타냅니다. 실제로 표시되는 것은 vtable_pointer_가 오브젝트에 복사되는 방법입니다. ("offset A :: vftable"= 메모리 오프셋 = 포인터) – MSalters

+0

@MSalters 캐치를 주셔서 감사합니다, 내 대답을 편집했습니다 –

0

컴파일러는 하나의 클래스의 vtable을 생성하고 컴파일 할 때 vtable의 주소가 결정됩니다. 런타임에 객체를 인스턴스화하면 vptr은 Vtable의 주소를 가져옵니다.

관련 문제