2011-12-30 2 views
2

age()라는 가상 함수가 포함 된 Person 클래스가 있다고 가정 해 보겠습니다. 언어 의미론에 따라 vtable은 객체별로가 아니라 클래스 단위입니다. VPTR은 오브젝트마다 있고 vtable을 가리 킵니다.vtable의 가상 함수 주소

질문 :이 프로그램을 빌드하는 경우

()가 (주이 존재 말할 수) : VTABLE 수

  1. VTABLE가 생성됩니다 즉 승 존재로 제공 /도 하나의 객체를 생성 오 ?

  2. 컴파일러에서 age()에 대해 vtable에 두는 주소는 메모리에있는 일부 정적 주소의 일종입니까?

  3. 또는 컴파일러가 age()에 대한 주소를 얻기 위해 내부적으로 개체를 만듭니다 (age()는 개체가 생성 될 때만 존재할 수있는 일부 데이터 멤버에서 작동하기 때문에) 이것 뒤에 다른 마술? 다음과 같이 나의 이해 당으로

, 답변은 다음과 같습니다 확인

  1. 하지 내가 위의 프로그램에서 "나노"를 실행 시도

단지 내가 vtable을 알아낼 수 있는지 알기 위해, 그러나 운 없음. 그렇게 할 방법이 있습니까?

좋습니다.

+4

모두 구현에 따라 다르므로 실제 답변을 원하면 사용하는 컴파일러를 지정해야합니다. –

+0

* 언어별로 * 가상 테이블 * 또는 * 가상 테이블 포인터 *를 언급하지 않고 가상 테이블 (모든 현재 컴파일러에서와 같이) 또는 임의의 가상 테이블로 구현할 수있는 연산의 의미 다른 접근 –

+0

감사합니다 @EtiennedeMartel –

답변

0

"언어 별 의미에 따라"vtable 같은 것은 없습니다. C++ 사양은 가상 디스패치가 구현되는 방법을 정확하게 지정하지 않습니다. 컴파일러는 vtable을 사용할 수 있습니다. 또는 다른 것을 사용할 수도 있습니다. 그건 컴파일러에게 달렸어.

특정 컴파일러는 물론 vtable을 사용할 수 있습니다. 그러나 그것은 그들과 함께 무엇이든 할 수 있습니다. 이것이 구현 세부 사항입니다. 간단히 말해, 사용하고있는 특정 컴파일러를 조사하지 않고도 알 수있는 방법이 없습니다.

정말로, 그렇게 많이 중요합니까? 이 정의 된 모든 구현 이래로

+0

브루스 에켈 (Bruce Eckel)이 구현을 이해했으며 이것이 C++에서 정의한 방법이라고 생각했습니다. 그러나, 당신은 정확합니다. 이것은 컴파일러에 의존해야합니다. 내 이해를 고쳐 주셔서 감사합니다. –

1

이 모든 답변은 컴파일러에 따라 다릅니다. 물리적 인 vtbl이 존재할 필요는 없습니다. 이것은 언어를 구현하는 매우 일반적인 방법 일뿐입니다. 그러나 이것에 대한 보편적 인 ABI는 없으며 개발자로서 걱정해야 할 것이 아닙니다.

+0

감사, 감사합니다. –

3

, 내 대답은 약간의 '일반적인 구현'을 설명

  1. 는 V-테이블은 OS가 메모리에 바로 기계 코드 자체와 같은 실행 파일에 저장 및로드 짐을 싣는 사람. OS는 문자열 리터럴, 머신 코드, vtables, 상수 데이터 등 어떤 데이터를로드할지 신경 쓰지 않습니다.

  2. 당신이 가진 가정 :

    // pseudocode, not C++ 
    struct A { 
        void *vtable; 
        int x; 
    }; 
    
    void A_f(A* this) { cout << this->x; } 
    
    void* A_vtable[] = { &A_f }; 
    
    void g(A* a) { ((void(*)(A*))(((void**)a->vtable)[0]))(a); } 
    

    그래서 그래, 그것의 정적 데이터 :

    struct A { 
        int x; 
        virtual void f() { cout << x; } 
    }; 
    
    void g(A* a) { a->f(); } 
    

    생성 된 코드는에 (의미)와 유사합니다.

    물론 위의 코드는 매우 단순합니다. RTTI와 가상 상속을 지원하려면 더 복잡한 일을해야합니다.

  3. 난 당신이 무슨 뜻인지 이해하지만, 제

+0

당신은 아주 좋은 설명을 가지고 있습니다. 이것은 나에게 Q3도 분명히 해주었습니다 :) –

1

이 모든 컴파일러 의존, 당신은 그냥 할 수있는 방법으로 전체 답을해야하지 않습니다

vtable을 만들 수 있습니까? 즉, vtable은 단일 객체를 만들지 않고도 존재할 수 있습니까?

컴파일러와 프로그램에 따라 다릅니다. 예를 들어, GCC는 클래스 정의 내에 정의되지 않은 첫 번째 가상 함수가 정의 된 (객체가 생성되었는지 여부에 관계없이) 번역 단위에 vtable을 만들지 만 어떤 경우에는 vtable을 전혀 생성하지 않을 수도 있습니다 또는 객체가 생성되지 않아도 객체를 생성 할 수 있습니다.

컴파일러에서 age()에 대해 vtable에 두는 주소는 메모리에있는 일부 정적 주소의 일종입니까?

일반적으로 링커/로더가 확인합니다. 프로그램이 링크되면 링커는 일반적으로 함수의 (상대) 주소를 확인한 다음이를 첫 번째 단계로 vtable에 주입합니다. 프로그램이 메모리에로드되면 해당 주소는 함수가있는 메모리 주소로 고정됩니다 (로더에 따라 실행마다 다를 수 있음).

아니면 그 컴파일러가 내부적으로 (객체가 구성되어있는 경우에만 존재 올 수있는 데이터 멤버에 작업 할) (나이 때문에)) (나이에 주소를 얻기위한 몇 가지 객체를 생성하거나이있다 이것 뒤에 다른 마술?

저는 전체적인 질문을 따르지 않습니다. 컴파일러는 프로그램이 요청할 때만 멤버 age이 인위적으로있는 유형의 객체를 만들지 않습니다. 멤버는 잠재적으로 특정 형식의 개체에 대한 데이터 액세스/수정 기능을하지만 해당 멤버에 대한 액세스는 모든 비 정적 멤버에게 전달되는 암시적인 this 포인터를 사용하여 처리됩니다.

+0

Thanks @David .. –