Я пытаюсь понять базовый механизм, используемый для реализации указателя на нестационарную функцию-член. Я ищу ответ, похожий на то, как 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
От «Язык программирования C++ По Страуструпом»,
Указатель на член ... больше похоже на смещение в структуре или индекс в массиве ...
Для данных член, я понимаю, что Pointer-To-Member Foo::j
более или менее эквивалентен offsetOf(Foo, j)
. Значение при использовании gcc-компилятора в моей среде-хосте составляет 4, и оно соответствует тому, что offsetOf(Foo, j)
равно 4.
Для члена функции возвращаемое значение равно 0x804844c
. И это некоторый адрес, который принадлежит к глобальной области данных
Так что мой вопрос (где загружается класс?):
Что такое «объект», который является адресом 0x804844c
.
- Это не может быть простой
offsetOf()
, так как это большое смещение. - Это не может быть адрес vtbl (или адрес записи в vtbl), потому что я верю, что vbtl - это объект, связанный с экземпляром объекта, а не с классом.
- Это не может быть адрес, в котором загружен код реализации функции. Поскольку один и тот же указатель может вести себя полиморфно при применении с производным объектом.
Тогда что объект по адресу 0x804844c
, и какова ее роль в переводе члена-функции указатель на в фактический адрес функции, когда оператор ->*
или .*
применяется?
Функции не являются «объектами» в смысле языка С ++, который использует этот термин. Обратите внимание, что функции-члены обычно реализуются как обычные функции с дополнительным параметром (объект становится «этим»). В этих реализациях они не находятся внутри самого экземпляра класса, но наряду с другими (свободными) функциями в сегменте кода. – dyp
* «Это не может быть адрес, где загружается код реализации функции. Поскольку один и тот же указатель может вести себя полиморфно при применении с производным объектом». * См. [этот ответ] (http://stackoverflow.com/a/1087671/420683) – dyp