クラス インスタンスとフィールドへのポインターが与えられると、このクラス インスタンスのフィールド変数を指す通常のポインターを取得できます。これは、次のコードの最後の代入と同様です。
class A
{
public:
int i, j;
};
int main(){
A a;
int A::*p = &A::i;
int* r = &(a.*p); // r now points to a.i;
}
この変換を逆にすることは可能ですか: コードのように、指定されたクラス インスタンスA a;
をint* r
取得int A::* p
(または、指定されたポインターが指定されたインスタンスにない場合は NULL ptr):
class A
{
public:
int i, j;
};
int main(){
A a;
int A::*p = &A::i;
int* r = &(a.*p); // r now points to a.i;
int A::*s = // a--->r -how to extract r back to member pointer?
}
私が考えられる唯一の方法は、Aの既知のすべてのフィールドを取得し、特定のインスタンスのアドレスを計算し、特定のアドレスと比較する関数を作成することです。ただし、これにはクラスごとにカスタム コードを記述する必要があり、管理が難しくなる可能性があります。また、次善のパフォーマンスもあります。
このような変換は、私が知っているすべての実装の下でいくつかの操作でコンパイラーによって実行できると想像できます-そのようなポインターは通常、構造内のオフセットにすぎないため、特定のポインターが実際にこのクラスストレージにあるかどうかを確認するための減算と範囲チェックにすぎません. 仮想基本クラスは少し複雑になりますが、コンパイラが処理できないものは何もないと思います。ただし、標準で必要とされていないため(そうですか?)、コンパイラベンダーは気にしていないようです。
それとも私は間違っていますか?そのような変換には根本的な問題がありますか?
編集:
私が尋ねていることについて少し誤解があることがわかります。要するに、私は次のいずれかを尋ねています:
- すでにいくつかの実装がありますが (つまり、コンパイラ レベルで)、ほとんど誰も使用していないため、ほとんど誰もそれについて知りません。
- 標準では言及されておらず、コンパイラベンダーもそれについて考えていませんが、原則として実装することは可能です(繰り返しますが、コンパイルされたコードではなく、コンパイラによって)。
- このような操作には、私が見逃した深刻な問題がいくつかあります。
私の質問は - それらのどれが本当ですか? そして最後の場合 - 根本的な問題は何ですか?
回避策を求めているわけではありません。