1

最初:仮想関数のメカニズムが未定義であることをどこかで読みました。つまり、すべてのコンパイラが異なる方法で実装できることを意味します。しかし、仮想機能メカニズムについて私が見つけたすべてのテキストは、VTBL と VPTR について語っています。

別の仮想機能メカニズムの実装はありますか? いくつか例を挙げていただけますか?

2 番目: 異なる言語での VTBL 実装の違いは何ですか?

4

3 に答える 3

1

人気のある代替手段の 1 つは、インライン キャッシングです。これは、Smalltalk システムに由来すると思います。

もう 1 つの方法は、型ごとにポリモーフィック メソッド テーブル (VMT) を用意する代わりに、ポリモーフィック メソッドごとに型テーブルを用意することです。プログラム全体の分析が必要ですが、効率的な多重継承が可能になります。一部の Eiffel コンパイラは、このような方法を使用します (詳細については、「多重継承を効率的に実装するにはどうすればよいですか?」を参照してください)。

最後の 1 つは、switch ステートメント ベースのアプローチ (Eiffel での検査 ~ C での switch) という別の方法についても言及しています。SmartEiffel はその変形を使用し、クラス ID に基づいてバイナリ検索を行います。また、プログラム全体の分析も必要ですが、命令キャッシュの動作が改善されているため、現在のシステムでは VMT よりも効率的な場合があります。(詳細は、「仮想関数テーブルを使用しない効率的な動的ディスパッチ」を参照してください)。

于 2014-04-04T10:32:34.487 に答える
0

例を示します。

class B
{
private:
    int m_i;
public:
    void foo() { puts("B::foo"); }
    virtual void bar() { puts("B::bar"); }
};
class D : public B
{
private:
    int m_j;
public:
    virtual void bar() { puts("D::bar"); }
    virtual void asdf() { puts("D::asdf"); }
};

int main()
{
    D d;
    B *pb = &d;
    pb->bar();
}

ほとんどのコンパイラは、そのコードを次のように実装します。

struct B;
struct __vtbl_B_t
{
    void (*bar)(B * const this);
};
struct B
{
    const __vtbl_B_t *__vptr;
    int m_i;
};
void B__foo(B * const this) { puts("B::foo"); }
void B__bar(B * const this) { puts("B::bar"); }

const __vtbl_B_t __vtbl_B = { B__bar };
void B__ctor(B * const this)
{
    this->__vptr = &__vtbl_B;
}

struct D;
struct __vtbl_D_t
{
    __vtbl_B_t __base;
    void (*asdf)(D * const this);
};
struct D
{
    B __base;
    int m_j;
};
void D__bar(D * const this) { puts("D::bar"); }
void D__asdf(D * const this) { puts("D::asdf"); }

__vtbl_D_t __vtbl_D = { { (void (*)(B * const))D__bar }, D__asdf };
void D__ctor(D * const this)
{
    B__ctor((B * const)this);
    this->__base.__vptr = (const __vtbl_B_t *)&__vtbl_D;
}

int main()
{
    D d;
    D__ctor(&d);

    B *pb = (B *)&d;

    (*pb->__vptr->bar)(pb);
}

出力:

D::bar

言語が C++ でなくても、コンパイラの動作は似ています。

于 2014-04-04T10:30:27.593 に答える
0

これはあなたを助けるかもしれません:

仮想法表:代替法との比較

異なるコンパイラ ベンダーは異なる方法を選択する可能性があります... しかし、最終的な実装は標準に準拠する必要があります。これは何ですか...

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf (セクション 10.3)

于 2014-04-04T10:26:14.130 に答える