Russian Qt Forum
Октябрь 02, 2024, 01:25 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Указатель на функцию-член класса  (Прочитано 4962 раз)
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
и он осуществляется нормально.

В общем-то, это то, что мне нужно, но очень хочтся понять, почему указателю
на функцию присваивается не адрес функции-члена, а адрес объекта и, как по такому
указателю вызывается функция???
Записан
zenden
Гость
« Ответ #1 : Сентябрь 20, 2011, 14:30 »

Потому что указатель на функцию-член класса в самом простом случае хранится в виде пары указатель на объект + указатель на код функции. Если же имеется наследование, то размер увеличивается (у борланда это  кажется 16 байт)

Кстати __closure - это не часть языка C++ и не поддерживается ни одним компилятором, кроме борланда.
Записан
konstantin
Гость
« Ответ #2 : Сентябрь 20, 2011, 15:14 »

Размерность моего указателя - 8 байт. Если указатель на функцию-член составной, то почему, при присвоении ему адреса функии, он принимает значение только адреса объекта?
Записан
Akon
Гость
« Ответ #3 : Сентябрь 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.
Записан
konstantin
Гость
« Ответ #4 : Сентябрь 21, 2011, 14:40 »

Залез в память. Как я уже говорил, под указатель отводится 8 байт. В четырех младших хранится адрес функции-члена, а в старших - адрес объекта. Из данных мне ответов напрашивается вывод о том, что структура указателя не регламентируется стандартом языка. Я правильно понял? Если кто знает хороший источник, где можно почитать про такие указатели, подскажите)

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

Всем спасибо за ответы!!!
Записан
Akon
Гость
« Ответ #5 : Сентябрь 21, 2011, 16:22 »

Ну так, это и есть TMethod. Структура указателя не регламентируется. Лучший источник информации - сорцы. При инициализации указателя всегда устанавливаются оба члена структуры.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.072 секунд. Запросов: 21.