2011-04-11 5 views
3

나는이 같은 매우 간단한 클래스 작성하는 경우 :가상 메소드가있는 경우 vtable이 생성됩니까?

class A 
{ 
    public : 
    virtual void foo() 
    { 
    } 
}; 

(NO 가상 소멸자) 컴파일러의 vtable을 만들 것입니다을? 아니면 현대적인 컴파일러가이 케이스 (잘못된 복사 및 붙여 넣기 일 수 있음)를 인식하고 그러한 클래스에 대한 가상 테이블을 추가하지 않을만큼 똑똑합니까?

+0

일반적인 기술은 첫 번째 가상 비선형 구성원으로 vtable을 방출하는 것입니다. 가상 인라인이 아닌 멤버가있는 곳에서는 대체 기능이 무엇인지 모르겠지만 인라인 함수 나 템플릿 인스턴스화에서 정적 인 것보다 해결하기가 더 어려운 문제는 아닙니다. – AProgrammer

+2

가상 소멸자는 다른 가상 함수가없는 경우 클래스가 다형성이되도록하는 한 가지 방법 일뿐입니다. (A에 대한 포인터를 통해 파생 클래스를 삭제하려는 경우에도 필요합니다. –

+2

@AProgrammer - 컴파일러는 vtable의 복사본을 많이 생성하고 링커에서 정렬해야 할 것입니다. –

답변

5

v 테이블은 구현 세부 사항입니다. 가상 함수에 대해 v 테이블을 사용하는 컴파일러는이 클래스에 대한 테이블을 작성합니다. 그렇지 않은 사람들은 그렇지 않습니다.

+1

몇 가지 대안이 있습니까? –

+0

@ 제이슨 : [이 질문에] (http://stackoverflow.com/questions/4352032/a-question-about-virtual-mechanism-in-c) 및 [this one] (http://stackoverflow.com/ 질문/5417829/how-can-c-virtual-functions-be-implemented-vtable 제외) –

+0

당신은 구현 세부 사항이 맞지만 실제로 그렇게하지 않는 컴파일러가 있습니까? –

2

컴파일러는 클래스가 다른 컴파일 단위에서 파생되지 않았 음을 확신 할 수 없으므로 호출이 인스턴스의 런타임 유형에 올바르게 종속되도록해야합니다.

가상 전화를 해결하기 위해 vtable을 사용하는 경우 vtable이 생성됩니다. 다른 구현이 사용되면 (자), 그기구가 사용됩니다.


올드 버전 : 컴파일러는 클래스가 다른 컴파일 단위에서 파생되지 않는다는 것을 확신 할 수 없기 때문에 vtable에 생성됩니다.

+0

컴파일러는 표준에 따라 가상 호출이 작동하도록 기계를 설정합니다. 그 기계는 vtable이 아닐 수도 있습니다. –

1

대답은 컴파일러가 v 테이블을 생성해야한다는 것입니다. 고려 이유를 이해하려면 다른 곳

class B : public A 
{ 
    void foo() { do something interesting } 
} 

과 :

void bar (A& obj) 
{ 
obj.foo() 
} 

반드시 bar()에 B 형의 개체를 전달할 수 있으며, B::foo()가 호출됩니다. B

void bar2 (A& obj) 
{ 
delete obj; 
} 

아마 소멸자에 대한 때문에 예상 동작하지 않을 것 같다 obj이 유형입니다 하나 polymorfically 우리의 경우 A를 제거 할 수 있기 때문에 항상 모든 다형성 클래스에 대한 가상 소멸자를 가지고 좋은 프로그래밍 연습 B는 절대로 호출되지 않습니다.

관련 문제