2013-06-14 4 views
7

C++의 모든 가상 함수는 V 테이블에 저장되어 있습니다. 오버 라이딩은 가상 기능의 경우에 발생합니다. 나는 테이블에서 직접 Virtual 함수를 호출 할 수있는 방법이 있는지 물어보고 싶고 V-table에 어떤 함수가 포함되어 있는지도 결정할 수 있습니다.V 테이블에서 가상 함수 호출

+0

왜 그렇게하고 싶습니까? 컴파일러 ABI의 inernals에 대해 아는 한 적어도 직접 메모리 어드레싱을 사용할 수 있습니다. –

+0

우리는 V-pointer를 가리키는 v-table.using g ++ 컴파일러 인 을 가리키며 Class에있는 V-pointer (클래스에 가상 함수가 포함되어있는 경우)를 사용할 수 있습니까? –

답변

16

글쎄, 실제로하실 수 있습니다. 나는 이식성에 신경 쓰지 않지만 대면 할 수는 있습니다. VS를 사용하여 32 비트 코드를 작성한다고 가정하면 객체 주소의 처음 4 바이트가 vtable 주소입니다. 헤더 파일을 보면 vtable에서 메서드의 순서를 알 수 있습니다.

예 :

class Base 
{ 
public: 

    virtual void printMessage() 
    { 
     std::cout << "Base::printMessage()" << std::endl; 
    } 
}; 

class Derived : public Base 
{ 
public: 

    void printMessage() 
    { 
     std::cout << "Derived::printMessage()" << std::endl; 
    } 
}; 

int main(int argc, char* argv[]) 
{ 
    Derived d; 

    unsigned int vtblAddress = *(unsigned int*)&d; 

    typedef void(*pFun)(void*); 

    pFun printFun = (pFun)(*(unsigned int*)(vtblAddress)); 

    printFun(&d); 

    return 0; 
} 

P.S. 왜 그런지 묻지는 않겠지 만, 여기에 하나의 옵션이 있습니다 :-)

+1

이것은 실제로 내가 원했던 것입니다. –

+8

믿을 수없는, Peter Wood, Eelke, toro2k, Stony와 quetzalcoatl은 무엇이 여기에 묻히고 있는지 말할 수 없습니다. 어떻게이 스레드의 모든 참가자가 무엇이 요청되었는지 이해할 수 있습니까? Mike Seymour와 ForEveR에 비해 꽤 낮은 평판을 가진 5 명의 "똑똑한"남자들은 다른 사람들을 괴롭 히고 있습니다. 내 말은, 네가 그 질문을 이해하지 못한다는거야. 괜찮아.하지만 다른 사람들이 그걸 신의 의논하라고하자. – user1764961

+1

@ user1764961- 예, 정말 믿을만한 사람 !! –

2

표준에 의한 가상 기능은 v-table을 사용하여 구현된다는 보장은 없습니다. 따라서 확실한 경우에만 해당 컴파일러에서 v-table을 사용합니다. 필요한 오프셋을 찾을 수 있습니다.

+1

C++에서는 컴파일러가 가상 함수를 구현하기 위해 V-table을 사용할 필요가 없습니까 ??? –

+0

@ user2484070 예, 필요하지 않습니다. 가상 함수의 구현은 컴파일러에 의존합니다. – ForEveR

+0

@ user2484070, 값은 어딘가에 저장되며 어떻게 든 표시됩니다. 그것은 잘 알려진 V-table이 될 것인가 아니면 다른 것이 될 것인가 ... 정말로 중요하지 않습니다. – user1764961

2

휴대 가능하게, 아니요. 언어는 가상 디스패치가 어떻게 구현되는지, 어떻게 동작 하는지를 지정하지 않습니다. 반드시 v 테이블을 사용하여 구현되는 것은 아니며 가상 함수를 호출하는 것 외에는 가상 함수에 액세스 할 수있는 방법이 없습니다.

하나의 특정 ABI 만 지원하면 가상 디스패치 메커니즘과 동일한 방식으로 개체를 함수 포인터에 매핑하기 위해 일부 세부적인 포인터 캐스트와 함께 구현 세부 정보를 사용할 수 있습니다. 그러나 정의 된 언어를 벗어나 지원되지 않는 비 휴대용 영역으로 넘어갈 것이므로 어떤 일을 하든지 다시 생각해 보는 것이 좋습니다.

+1

잡았습니다. 감사합니다 :) –

0

vtable의 정확한 구현이 특정 플랫폼/컴파일러이기 때문에 일반적으로 아니오라고 말하고 싶습니다. 플랫폼/컴파일러가 vtable 및 addresation을 구현하는 방법을 알고 있다면 특정 클래스에 대한 vtable의 주소를 확인한 다음 가상 메소드의 오프셋을 추가하여 계산할 수 있습니다.

vtable에는 클래스의 모든 가상 메소드가 포함되어 있습니다. 응용 프로그램을 분해하여 볼 수 있습니다.

관련 문제