2012-03-31 1 views
0

_declspec(novtable)은 어떤 경우에 액세스 위반이 있습니까?_declspec (novtable)이 안전하지 않은시기는 언제입니까?

예를 들어,이 코드는하지 않습니다

int main(int argc, char* argv[]) 
{ 
    Base* a = new Base(); 
    delete a; // access violation 
} 

왜 코드를 수행 :이 코드는 것,

class __declspec(novtable) Base 
{ 
public: 
    virtual ~Base() { }; 
}; 

int main(int argc, char* argv[]) 
{ 
    Base a; 
} 

을하지만 :

class __declspec(novtable) Base 
{ 
public: 
    virtual ~Base() { }; 
    virtual int Foo() const = 0; 
    virtual int Bar() const { return 2; }; 
}; 

class A : public Base 
{ 
public: 
    int Foo() const { return 1; }; 
}; 

int main(int argc, char* argv[]) 
{ 
    A a; 
    volatile int a1 = a.Foo(); 
    volatile int a2 = a.Bar(); 

    Base* c = new A(); 
    volatile int c1 = c->Foo(); 
    volatile int c2 = c->Bar(); 
    delete c; 

    return 0; 
} 

이 코드는하지 않습니다 처음 두 예제에서는 소멸자를 던지지 않습니까? 당신이 novtable로 표시된 클래스 다음 액세스 클래스 멤버를 인스턴스화하려고하면

+1

구현 된 가상 멤버가 안전하지 않습니다. 클래스 대신'__interface'를 사용하여 컴파일러에서이를 강제 할 수 있습니다. –

+0

@ 한자 Passant - 멋진! 나는 그것에 대해 몰랐다! – PaulH

답변

2

http://msdn.microsoft.com/en-us/library/k13k85ky%28v=vs.71%29.aspx

, 당신은 액세스 위반 (AV)를 받게됩니다.

액세스 위반이있는 코드는 novtable 클래스에서 명시 적으로 "delete"를 호출하는 코드입니다.

+0

두 번째 예제에서 'Base a;'가 범위를 벗어나면 왜 이해하지 못합니까? – PaulH

+5

동작은 정의되지 않습니다. "일하는 것"은 정의되지 않은 유효한 동작입니다. (기술적 인 이유는 객체 유형이 완전히 알려져 있기 때문에 vtable 조회가 최적화 될 수 있기 때문입니다.) 최적화는 버그를 가렸다. –

+0

가상 기능이없는 클래스에서이 novtable을 사용하면 문제가 발생할 수 있습니까? –

관련 문제