8

ライブラリは、クラスに仮想関数を提供します。ライブラリに動的にリンクされたバイナリを再コンパイルせずに、このクラスを新しい仮想関数で拡張できますか?

これは標準では不可能だと思います。これを可能にするプラットフォームはありますか?

新しい関数がクラス本体の最後にのみ追加された場合、それは簡単でしょうか?

4

1 に答える 1

5

この規格は、バイナリ互換性には関係していません。ただし、これはクラスに関係しており、クラスの定義をある変換単位から別の変換単位に「変更」することで、実際には未定義の動作を呼び出します。

ほとんどのコンパイラは、再コンパイルを必要とせずに多くの変更を許可しますが、リストは小さいです...そしてこれについては、派生クラスの事前知識によっては、それが不可能な場合があると思います。

私が予測する問題は、コンパイラーが通常仮想テーブルに対して実行する最適化にあります。

仮想関数を使用してクラスを作成すると、次のような仮想テーブルが作成されます。

// B virtual table
0 - Offset to complete object
1 - RTTI
2 - func0
3 - func1
...

ある程度のスペースを確保するために、派生クラス独自の仮想関数は通常「追加」されます。

// D virtual table
Same as B
N+3 - func(N+1)
N+4 - func(N+2)

このように、オブジェクトには1つの仮想ポインターしかありません。これは、型が(静的に) (ポインターまたは参照を介してD)である場合でもそのまま使用できます。B

ただし、B再コンパイルせずに拡張すると、関数を呼び出すときに、おそらく同じ引数を持たない関数を呼び出すため、単純にクラッシュします...おっとDN+1BN+1D

ただし、派生クラスがないことがわかっている場合は、独自の仮想関数を追加できます。

于 2011-04-19T08:52:36.590 に答える