Re[11]: Универсальный указатель на функцию-член класса
От: Vladik Россия  
Дата: 09.10.02 07:27
Оценка:
Здравствуйте Павел Кузнецов, Вы писали:

V>>Принципиальной вещью, добавляющей ту самую "статичность" типов является наличие в объявлении в качестве параметра шаблона X — класса, на функцию которого мы завязываемся. В случае __closure в C++Builder — класс X неизвестен. Что для С++ будет "грязным хаком" (выделено жирным):


ПК>Приведенный пример можно переписать иначе, скрыв информацию о классе Х от того, кто будет вызывать closure (схематичный код, не претендующий на правильность и/или полноту):


Да уж. Без поллитры такое не придумать. От reinterpret_cast ушли, но какой ценой

[...]

ПК>Поддержка со стороны компилятора потенциально позволяет избавиться от динамического распределения памяти (или спрятать его), но ничего не меняет принципиально.


Да я ничего не имею против поддержки со стороны компилятора, я даже за. Я говорю о том, что легкость подобного подхода будет провоцировать использовать его там, где не надо (что я вижу в билдере).
Как все запущенно...
Re[12]: Универсальный указатель на функцию-член класса
От: Павел Кузнецов  
Дата: 09.10.02 08:00
Оценка:
Здравствуйте Vladik, Вы писали:

ПК>>Поддержка со стороны компилятора потенциально позволяет избавиться от динамического распределения памяти (или спрятать его), но ничего не меняет принципиально.


V>Да я ничего не имею против поддержки со стороны компилятора, я даже за. Я говорю о том, что легкость подобного подхода будет провоцировать использовать его там, где не надо (что я вижу в билдере).


Ну, это уже совсем другой разговор. Воспитание манер не является задачей языка.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[4]: Универсальный указатель на функцию-член класса
От: Аноним  
Дата: 20.10.02 15:07
Оценка:
Здравствуйте Павел Кузнецов, Вы писали:

ПК>В рамках стандартного C++ наиболее адекватным решением являются всевозможные callback libraries: http://www.function-pointer.org/links.html#fpt


А кто нибудь проверял эту либу
http://www.function-pointer.org/zip/callback.zip ? Потому как у меня при использовании класса с множественным наследованием это все дружно рухнуло, и заглянув в класс CBFunctorBase на вскидку изменил вот так вот —

enum {MEM_FUNC_SIZE = sizeof(PMemFunc)*2};

На первый взгляд должно работать, но неизвестно к каким еще багам это может привести? Вообще есть какая то более легальная имплементация, что бы учитывалась 8-ми байтная структура указателя на метод класса, полученного множественным наследованием, как то обойтись без memcpy&memcmp, ну и что бы оператор == присутсвовал как в данной реализации?
Re: Универсальный указатель на функцию-член класса
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 21.10.02 08:51
Оценка: +1
Здравствуйте AkaSaint, Вы писали:

AS>Вопрос: как можно реализовать сабж на чистом С/С++ или в MSVC 7? В Билдере есть очень удобная штука — __closure, с ее помощью можно определить указатель на функцию — член любого класса, лишь бы параметры и возвращаемые значения совпадали (ну и соглашения по вызову). А в MSVC получается, мне еще нужно знать, и какого класса функция.... Помогите пожалуйста.


Вопрос появляется с завидным постоянством

Насколько я понял принцип работы __closure

В указателе на метод хранятся
  1. указатель на объект (void*)
  2. указатель на функцию, которая вызывает конкретный метод, конкретного класса
То есть когда ты выполняешь присваивание
closure_variable=object.method

компилятор создает заглушку, которая именно этот метод и вызывает:
result_type method_caller(object_type* object,arg_list)
{
 return object->method(arg_list)
}


И сохраняет в closure_variabe {(void*)this,method_caller}.

Значит нам нужно соорудить шаблонные конструкции, которые будут порождать
  1. Класс для хранения данных __closure
  2. Класс, в котором будет статический метод вызова указанного метода — *object_type::mem_func(arg_list). Указатель на обслуживаемый метод естественно должен храниться в статическом члене этого класса
  3. Шаблонная функция, которая автоматизирует процесс создания содержимого __closure. Например, такого вида
    template<class object_type,/*перечисляем типы из arg_list*/>
    closure_variable_type make_closure(object_type* obj,void (object_type::*method)(arg_list))
Естественно, то что Builder делает на уровне компилятора, прийдется собирать руками под разное число аргументов и разные типы вызово (__stdcall,__cdecl)

Это и есть вся теория __closure.

На практике, когда я пробовал это соорудить на BCB3, получилось следующее
Автор: Коваленко Дмитрий
Дата: 28.01.02


Надеюсь, что ответил по существу.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[2]: Универсальный указатель на функцию-член класса
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 21.10.02 09:06
Оценка:
Здравствуйте Коваленко Дмитрий, Вы писали:

Хм. немножно неправильно объяснил

КД>компилятор создает заглушку, которая именно этот метод и вызывает:

КД>
КД>result_type method_caller(void* object,arg_list)
КД>{
КД> return ((object_type*)object)->method(arg_list);
КД>}
КД>


Заглушка должна быть такого вида. Под каждый класс object_type и каждый method нужно генерировать свою заглушку.

С помощью шаблонов и больной фантазии, генерацию таких заглушек можно частично автоматизировать, что и продемонстрировано выше.

Теперь, кажется, все перепутано правильно
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.