Ответ 1
Дэнни Калев объясняет это довольно хорошо:
Базовое представление указателей на члены
Хотя указатели на элементы ведут себя как обычные указатели, за кулисами их представление совершенно иное. Фактически, указатель на член обычно состоит из структуры, содержащей до четырех полей в определенных случаях. Это связано с тем, что указатели на члены должны поддерживать не только обычные функции-члены, но также функции виртуальных членов, функции-члены объектов, которые имеют несколько базовых классов, и функции-члены виртуальных базовых классов. Таким образом, простейшая функция-член может быть представлена как набор из двух указателей: один, содержащий физический адрес памяти функции-члена, и второй указатель, который содержит указатель
this
. Однако в таких случаях, как виртуальная функция-член, множественное наследование и виртуальное наследование, указатель на член должен хранить дополнительную информацию. Таким образом, вы не можете накладывать указатели на участников на обычные указатели и не можете безопасно использовать между указателями для членов разных типов.Чтобы понять, как ваш компилятор представляет указатели на члены, используйте оператор
sizeof
. В следующем примере берутся размеры указателя на элемент данных и указатель на функцию-член. Как вы можете видеть, они имеют разные размеры, следовательно, разные представления:
struct A
{
int x;
void f();
};
int A::*pmi = &A::x;
void (A::*pmf)() = &A::f;
int n = sizeof (pmi); // 8 byte with my compiler
int m = sizeof (pmf); // 12 bytes with my compiler
Обратите внимание, что каждый из этих указателей может иметь другое представление в зависимости от рассматриваемого класса и является ли функция-член виртуальной.