データメンバーへのポインタの単一の宣言は、そのクラスのすべてのオブジェクトへのポインタを作成します。
いいえ。メンバーへのポインターを作成します(これは、オブジェクトのベースからのオフセットと見なす
ことができます)。次に、オブジェクトへのポインターと一緒に使用して、そのメンバーを取得できます。
struct S
{
int x;
int y;
};
int S::* ptrToMember = &S::x; // Pointer to a member.
S obj;
int* ptrToData = &obj.x; // Pointer to object
// that happens to be a member
メンバーへのポインターを作成する際には、オブジェクトを使用しないことに注意してください(タイプ情報のみを使用します)。したがって、このポインターは、特定のメンバーを取得するためのクラスへのオフセットです。
ポインタまたはオブジェクトを介してデータメンバーにアクセスできます。
(obj.*ptrToMember) = 5; // Assign via pointer to member (requires an object)
*ptrToData = 6; // Assign via pointer already points at object.
クラスの特定のインスタンスを1つだけ指すように単一のポインターが作成されるのとは対照的に、これが発生するのはなぜですか?
それはポインタと呼ばれます。
類似しているが並列の概念(上記を参照)。
アイデアをサポートするロジックは何ですか?
愚かな例:
void addOneToMember(S& obj, int S::* member) { (obj.*member) += 1; }
void addOneToX(S& obj) { addOneToMember(obj, &Obj::x);}
void addOneToY(S& obj) { addOneToMember(obj, &Obj::y);}
また、これを正しく理解している場合、これは、ポインターの初期化時に割り当てられるメモリの量が不定/可変であることを意味します。これは、その時点で任意の数のオブジェクトが存在する可能性があるためです。
いいえ。メンバーへのポインタは、オブジェクトへの単なるオフセットであるためです。値を取得するには、実際のオブジェクトが必要です。
最後に、これらのポインタにメモリはどのように割り当てられますか?
他のオブジェクトと同じように。レイアウトに関しては特別なことは何もありません。
ただし、実際のレイアウトは実装によって定義されます。したがって、コンパイラを参照せずにこの質問に答える方法はありません。しかし、それは本当にあなたには役に立たない。
これらのポインタの物理メモリアドレスを確認することは可能ですか?
もちろん。それらは他のオブジェクトと同じです。
// Not that this will provide anything meaningful.
std::cout.write(reinterpret_cast<char*>(&ptrToMember), sizeof(ptrToMember));
// 1) take the address of the pointer to member.
// 2) cast to char* as required by write.
// 3) pass the size of the pointer to member
// and you should write the values printed out.
// Note the values may be non printable but I am sure you can work with that
// Also note the meaning is not useful to you as it is compiler dependent.