Russian Qt Forum

Программирование => С/C++ => Тема начата: konstantin от Сентябрь 20, 2011, 13:51



Название: Указатель на функцию-член класса
Отправлено: konstantin от Сентябрь 20, 2011, 13:51
Здравствуйте!

При написании приложения в Borland столкнулся с необъяснимой особенностью то ли борландовского компилятора, то ли языка C++. Суть в следующем:

Есть класс формы, в котором есть функции-члены - обработчи различных событий.
В одной из таких функций мне необходимо получить адрес ее самой. Для этого
я испльзую указатель на данный тип функции. В итоге получаю не адрес функции, а адрес
объекта, в контексте которого вызывается данная функция.

Пример:

typedef void __fastcall (__closure *CallFunction)(System::TObject* Sender);// Тип указателя на функцию-член
CallFunction pFunc;

class TStatForm : public TForm
{
__published:
.........................................
.........................................
void __fastcall RequestButtonClick(TObject *Sender);
.........................................
}

void __fastcall TStatForm::RequestButtonClick(TObject *Sender)
{
...........................................
...........................................
pFunc = &RequestButtonClick;
...........................................
}

Через отладчик вижу, что функция RequestButtonClick лежит в памяти по адресу X,
а объект класса формы, для которого вызывается RequestButtonClick лежит по адресу Y.

В результате операции pFunc = &RequestButtonClick в pFunc получаем адрес Y.

Затем, в коде осуществляю вызов функции RequestButtonClick через pFunc
и он осуществляется нормально.

В общем-то, это то, что мне нужно, но очень хочтся понять, почему указателю
на функцию присваивается не адрес функции-члена, а адрес объекта и, как по такому
указателю вызывается функция???


Название: Re: Указатель на функцию-член класса
Отправлено: zenden от Сентябрь 20, 2011, 14:30
Потому что указатель на функцию-член класса в самом простом случае хранится в виде пары указатель на объект + указатель на код функции. Если же имеется наследование, то размер увеличивается (у борланда это  кажется 16 байт)

Кстати __closure - это не часть языка C++ и не поддерживается ни одним компилятором, кроме борланда.


Название: Re: Указатель на функцию-член класса
Отправлено: konstantin от Сентябрь 20, 2011, 15:14
Размерность моего указателя - 8 байт. Если указатель на функцию-член составной, то почему, при присвоении ему адреса функии, он принимает значение только адреса объекта?


Название: Re: Указатель на функцию-член класса
Отправлено: Akon от Сентябрь 20, 2011, 21:34
Ваш тип это TNotifyEvent:
Код:
TNotifyEvent pFunc = statForm->RequestButtonClick;
...
pFunc = 0;

Насколько я помню, там есть структура (реально, она на паскале):
Код:
struct TMethod {
  void* code;  // pointer to function  TStatForm::RequestButtonClick
  TObject* data;  // pointer to instance (statForm)
};

Вообщем, вы посмотрите дамп по адресу pFunc.


Название: Re: Указатель на функцию-член класса
Отправлено: konstantin от Сентябрь 21, 2011, 14:40
Залез в память. Как я уже говорил, под указатель отводится 8 байт. В четырех младших хранится адрес функции-члена, а в старших - адрес объекта. Из данных мне ответов напрашивается вывод о том, что структура указателя не регламентируется стандартом языка. Я правильно понял? Если кто знает хороший источник, где можно почитать про такие указатели, подскажите)

И еще вопрос. Если я буду инициализировать свой указатель на функцию-член вне функции класса, то что я получу в половине, отвечающей за адрес объекта? NULL?

Всем спасибо за ответы!!!


Название: Re: Указатель на функцию-член класса
Отправлено: Akon от Сентябрь 21, 2011, 16:22
Ну так, это и есть TMethod. Структура указателя не регламентируется. Лучший источник информации - сорцы. При инициализации указателя всегда устанавливаются оба члена структуры.