非静的メンバー関数へのポインターを実現するために使用される基本的なメカニズムを理解しようとしています。コンパイラごとに異なる可能性のある詳細を気にせずに、全体像で vtbl (ポリモフィズムの仮想テーブル) がどのように機能するかに似た答えを探しています。
例:
#include <stdio.h>
class A {
public:
int i;
int j;
void foo(void) { };
};
int main ()
{
int A::*ptr_j = &A::j;
void (A::*ptr_f)(void) = &A::foo;
printf("Foo::j pointer to data member %p\r\n", ptr_j);
printf("Foo::foo pointer to function member %p\r\n", ptr_f);
}
結果は
Foo::j
データメンバーへのポインター0x4
Foo::foo
関数メンバーへのポインター0x804844c
「The C++ Programming Language By Stroustrup」より、
メンバーへのポインター...構造体へのオフセットまたは配列へのインデックスに似ています...
Foo::j
データ メンバーの場合、Pointer-To-Memberは多かれ少なかれ と同等であることを理解していoffsetOf(Foo, j)
ます。ホスト環境で gcc コンパイラを使用した場合の値は 4 で、4 と一致しoffsetOf(Foo, j)
ます。
関数メンバーの場合、戻り値は0x804844c
です。そして、これはグローバルデータ領域に属するアドレスです (クラスがロードされる場所は?)
だから私の質問は:
address である「オブジェクト」とは何ですか0x804844c
。
offsetOf()
これは大きなオフセットであるため、単純な にすることはできません。- vbtl はクラスではなく、インスタンス化されたオブジェクトに関連付けられたエンティティであると考えているため、vtbl のアドレス (または vtbl のエントリのアドレス) にすることはできません。
- 関数の実装コードがロードされるアドレスにすることはできません。派生オブジェクトを適用すると、同じポインターが多態的に動作する可能性があるためです。
次に、 address のオブジェクトは何ですか? また、演算子orが適用され0x804844c
たときにメンバー関数へのポインタを実際の関数アドレスに変換する際のその役割は何ですか?->*
.*