2012-03-31 17 views
0

_declspec(novtable)はどんな状況の下でアクセス違反ですか?例えば_declspec(novtable)が安全でないのはいつですか?

、このコードがない:

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; 
} 

また、このコードはしません。

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

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

しかし、このコードは以下となります。

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

なぜコードはありません最初の2つの例では、デストラクタに投げない?

+1

実装されている仮想メンバーはすべて安全ではありません。クラスの代わりに '__interface'を使ってコンパイラにこれを強制することができます。 –

+0

@Hans Passant - ファンシー!私はそれについて知らなかった! – PaulH

答えて

2

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

あなたはnovtable、その後 アクセスクラスのメンバでマークされたクラスをインスタンス化しようとすると、アクセス違反(AV)を受け取ることになります。

アクセス違反が発生するコードは、明示的にnovtableクラスで「削除」を呼び出すコードです。

+0

それは理にかなっていますが、2番目の例で 'Base a; – PaulH

+5

動作は未定義です。 「動作している」とは、未定義の有効な動作です。 (技術的な理由は、オブジェクトタイプが完全にわかっているので、vtableのルックアップを最適化できます)。 –

+0

仮想関数を持たないクラスでこのnovtableを使用すると問題が発生する可能性がありますか? –

関連する問題