2012-06-03 7 views
0

어디서나 문서화되어 있는지 확신 할 수 없습니다. 가상 함수의 경우, 각 클래스는 가상 테이블이라는 함수 포인터 배열에 대한 포인터 인 vptr을 보유하고 있습니다. vptr의 프로토 타입이 무엇인지 알고 싶습니다. 예를 들어 다음과 같이 클래스가 선언 된 경우, C++ : 가상 포인터의 프로토 타입

class A 
{ 
    int a; 
    public: A(){} 
    virtual void display(); 
    virtual void setValue(int x); 
}; 

이제 우리는 하나의 vptr에서 다른 프로토 타입이 개 정의 할 것인가 클래스 A의 VTABLE 두 함수 포인터가있는

?

제 이해가 잘못되었는지 알려주세요.

Thx! Rahul.

+0

가능한 복제본 [C++의 가상 테이블 구조 란 무엇입니까?] (http://stackoverflow.com/questions/5868431/what-is-the-structure-of-virtual-tables-in-c) –

답변

3

vptr은 구현 세부 사항이므로 프로토 타입이 없습니다.

1

Oli Charlesworth가 지적했듯이 가상 포인터는 구현 세부 사항이므로이 질문은 C++ 측면에서 실제로 이해가되지 않습니다. 즉 가상 함수의 다음과 같은 수동 구현 (일부 기능이) 이해에 도움이 될 수 말했다

물론
struct vtable { 
    void (*display)(void*); 
    void (*setValue)(void*, int); 
}; 

void A_display(void *this_) { /*Cast this_ to A* and do A stuff*/ } 
void A_setValue(void *this_, int x) { /*Cast this_ to A* and do A stuff*/ } 

vtable A_vtable = {A_display, A_setValue}; 

struct A { 
    vtable *vptr = &A_vtable; 
    int a; 
    public: A(){} 
}; 

void B_display(void *this_) { /*Cast this_ to B* and do B stuff*/ } 
void B_setValue(void *this_, int x) { /*Cast this_ to B* and do B stuff*/ } 

vtable B_vtable = {B_display, B_setValue}; 

struct B { 
    vtable *vptr = &B_vtable; 
    int a; 
    public: B(){} 
}; 

void display(void *obj) { 
    ((*static_cast<vtable**>(obj))->display)(obj); 
} 
void setValue(void *obj, int) { 
    ((*static_cast<vtable**>(obj))->setValue)(obj, int); 
} 

, 이것은 단지 가상 함수의 기능의 작은 부분 집합을 제공하지만, 그것은해야 vptrs은 고정 된 유형의 함수에 대한 포인터 모음을 가리 킵니다.

1

가상 테이블 (그러한 것을 사용하는 구현에서)은 "컴파일러 마술"의 산물입니다. C++ 코드가 직접 사용하지 않기 때문에 특정 프로토 타입이 필요하지 않습니다. 대신 컴파일러는 하나를 필요로하는 각 클래스를 준수하도록 사용자 정의 생성합니다. 또한 컴파일러는 각 요소에 액세스하는 코드를 생성하므로 형식이 안전한 방식으로 각 요소에 액세스 할 수 있습니다.

예를 들면, 컴파일러는 A::setValue 방법 슬롯 컴파일러가 제 위치에있을 넣어 하나이므로 setValue 서명과 일치 함수에 대한 포인터를 보유하고 있음을 알고있다. 또한 해당 슬롯에 직접 액세스하는 유일한 코드는 컴파일러에서 생성 한 컴퓨터 코드이며 해당 코드를 생성하기 전에 컴파일러는 원래 C++ 코드가 setValue 함수를 호출하고 있음을 확인했습니다. 따라서, setValue 슬롯이 setValue 호환 함수 포인터 이외의 다른 것을 저장할 수 있다는 걱정은 없습니다. 대신에 다른 슬롯이 액세스 될 수 있다는 우려는 없습니다. 그런 일이 생기면 컴파일러 버그 일 것이고 일반 사용자 코드의 결과로 일어날 일은 결코 없을 것입니다.

테이블의 요소는 그룹으로 처리되지 않으므로 모두 동일한 유형을 가질 필요는 없습니다. 기껏해야, 그들은 모두 "일반적인 포인터 또는 CPU가 점프하기에 적합한 오프셋"유형을 가지고 있습니다. 이 시점에서 C++이 아니기 때문에 "유형"은 특정 C++ 유형에 맞을 필요가 없습니다.