0

仮想テーブルは関数ポインタの配列です。すべての関数が異なる署名を持っているので、どうすればそれを実装できますか?

4

3 に答える 3

4

あなたはそれを実装しません。

コンパイラはそれ(または同等の機能を持つもの)を生成し、型システムによって制約されないため、関数アドレスを単純に保存し、それらを正しく呼び出すために必要なコードを生成できます。

struct配列ではなく、異なるタイプの関数ポインタを含むものを使用して、漠然と似たものを実装できます。これは、C で動的ポリモーフィズムを実装する非常に一般的な方法です。たとえば、Linux カーネルは、次の行に沿ってインターフェイスを定義することにより、ファイルのようなオブジェクトにポリモーフィックな動作を提供します。

struct fileops {
    int (*fo_read)  (struct file *fp, ...);
    int (*fo_write) (struct file *fp, ...);
    // and so on
};
于 2012-08-21T10:12:21.153 に答える
0

コンパイル時にすべての関数がわかっている場合は、異なる型の関数ポインターの構造体を使用できます (ただし、コンパイル時にすべての関数がわかっている場合は、仮想メソッドを持つクラスを使用しないでください)。

実行時にこれを行いたい場合は、void*おそらく の配列で十分です。ポインターを格納するときにポインターをキャストし、呼び出す前に (正しい型に) 再度キャストする必要があります。もちろん、関数の型 (呼び出し規約を含む) を別の場所で追跡する必要があります。

これで何をしようとしているのかを知らなければ、より有用な答えを出すことは非常に困難です.


コードで vtables を実装する正当な理由があります。ただし、これらは実装の詳細であるため、「C++」だけでなく、既知の ABI をターゲットにする必要があります。私がこれを行ったのは、実行時に新しい COM クラスを動的に作成する実験だけでした (COM オブジェクトに期待される ABI は、最初の 3 つの関数がインターフェイスを__stdcall実装する呼び出し規則に従う関数を含む vtable へのポインターです)。IUnknown

于 2012-08-21T10:37:01.240 に答える
0

仮想テーブル内の関数のシグネチャが異なる場合は、異種の型を持つメンバーを含む構造型として実装する必要があります。

または、シグネチャが何であるかを示す他の情報がある場合は、関数ポインターを別の関数ポインター型にキャストできますが、呼び出す前に正しい型にキャストし直す必要があります。

于 2012-08-21T10:12:11.293 に答える