Здравствуйте Павел Кузнецов, Вы писали:
V>>Принципиальной вещью, добавляющей ту самую "статичность" типов является наличие в объявлении в качестве параметра шаблона X — класса, на функцию которого мы завязываемся. В случае __closure в C++Builder — класс X неизвестен. Что для С++ будет "грязным хаком" (выделено жирным):
ПК>Приведенный пример можно переписать иначе, скрыв информацию о классе Х от того, кто будет вызывать closure (схематичный код, не претендующий на правильность и/или полноту):
Да уж. Без поллитры такое не придумать. От reinterpret_cast ушли, но какой ценой
[...]
ПК>Поддержка со стороны компилятора потенциально позволяет избавиться от динамического распределения памяти (или спрятать его), но ничего не меняет принципиально.
Да я ничего не имею против поддержки со стороны компилятора, я даже за. Я говорю о том, что легкость подобного подхода будет провоцировать использовать его там, где не надо (что я вижу в билдере).
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте Павел Кузнецов, Вы писали:
ПК>В рамках стандартного 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, ну и что бы оператор == присутсвовал как в данной реализации?
Здравствуйте AkaSaint, Вы писали:
AS>Вопрос: как можно реализовать сабж на чистом С/С++ или в MSVC 7? В Билдере есть очень удобная штука — __closure, с ее помощью можно определить указатель на функцию — член любого класса, лишь бы параметры и возвращаемые значения совпадали (ну и соглашения по вызову). А в MSVC получается, мне еще нужно знать, и какого класса функция.... Помогите пожалуйста.
Вопрос появляется с завидным постоянством
Насколько я понял принцип работы __closure
В указателе на метод хранятся
указатель на объект (void*)
указатель на функцию, которая вызывает конкретный метод, конкретного класса
То есть когда ты выполняешь присваивание
closure_variable=object.method
компилятор создает заглушку, которая именно этот метод и вызывает:
result_type method_caller(object_type* object,arg_list)
{
return object->method(arg_list)
}
И сохраняет в closure_variabe {(void*)this,method_caller}.
Значит нам нужно соорудить шаблонные конструкции, которые будут порождать
Класс для хранения данных __closure
Класс, в котором будет статический метод вызова указанного метода — *object_type::mem_func(arg_list). Указатель на обслуживаемый метод естественно должен храниться в статическом члене этого класса
Шаблонная функция, которая автоматизирует процесс создания содержимого __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
Надеюсь, что ответил по существу.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте Коваленко Дмитрий, Вы писали:
Хм. немножно неправильно объяснил
КД>компилятор создает заглушку, которая именно этот метод и вызывает:
КД>КД>result_type method_caller(void* object,arg_list)
КД>{
КД> return ((object_type*)object)->method(arg_list);
КД>}
КД>
Заглушка должна быть такого вида. Под каждый класс
object_type и каждый
method нужно генерировать свою заглушку.
С помощью шаблонов и больной фантазии, генерацию таких заглушек можно частично автоматизировать, что и продемонстрировано выше.
Теперь, кажется, все перепутано правильно
-- Пользователи не приняли программу. Всех пришлось уничтожить. --