Относительно вашего конкретного вопроса,
как мы можем наблюдать за содержанием
указатели на функции-члены?
Ответ таков: кроме преобразования их в bool для выражения того, что оно указывает на что-то или нет, вы не можете «указывать» указатели на функции-члены. По крайней мере, не в соответствии с требованиями. Причина в том, что стандарт явно запрещает это:
4,12 сноска 57:
57) Правило конвертации
указатели на членов (от указателя на
член базы для указателя на член
производная) выглядит перевернутой по сравнению с
правило для указателей на объекты (от
указатель на производный указатель на базу)
(4.10, пункт 10). Эта инверсия
необходимо обеспечить безопасность типов. Заметка
что указатель на член не является
указатель на объект или указатель на
функция и правила конверсий
такие указатели не относятся к
указатели на участников. В частности,
указатель на член не может быть преобразован
в пустоту *.
Например, вот пример кода:
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
class Gizmo
{
public:
void DoTheThing()
{
return;
};
private:
int foo_;
};
int main()
{
void(Gizmo::*fn)(void) = &Gizmo::DoTheThing;
Gizmo g;
(g.*fn)(); // once you have the function pointer, you can call the function this way
bool b = fn;
// void* v = (void*)fn; // standard explicitly disallows this conversion
cout << hex << fn;
return 0;
}
Я отмечаю, что мой отладчик (MSVC9) может сообщить мне фактический физический адрес функции-члена во время выполнения, поэтому я знаю, что должен быть какой-то способ получить этот адрес. Но я уверен, что он не соответствует требованиям, не является переносимым и, вероятно, включает в себя машинный код. Если бы я пошел по этому пути, я бы начал с адреса адреса указателя функции (например, &fn
), приведя его к void *, и пошел бы оттуда. Это также потребует, чтобы вы знали размер указателей (разных на разных платформах).
Но я бы спросил, если вы можете преобразовать указатель на функцию-член в bool и оценить существование указателя, зачем в реальном коде вам нужен адрес?
Предположительно, ответ на последний вопрос таков: «Таким образом, я могу определить, указывает ли одна функция указатель на ту же функцию, что и другая». Справедливо. Вы можете сравнить функциональные указатели на равенство:
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
class Gizmo
{
public:
void DoTheThing()
{
return;
};
**void DoTheOtherThing()
{
return;
};**
private:
int foo_;
};
int main()
{
void(Gizmo::*fn)(void) = &Gizmo::DoTheThing;
Gizmo g;
(g.*fn)(); // once you have the function pointer, you can call the function this way
bool b = fn;
// void* v = (void*)fn; // standard explicitly disallows this conversion
cout << hex << fn;
**void(Gizmo::*fnOther)(void) = &Gizmo::DoTheOtherThing;
bool same = fnOther == fn;
bool sameIsSame = fn == fn;**
return 0;
}