Форум программистов, компьютерный форум CyberForum.ru

Абстракция вызова функции - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Как использовать перегруженный оператор [ ], если дан не сам класс, а указатель на него? http://www.cyberforum.ru/cpp-beginners/thread960880.html
Это указатель на класс figure *f Это перегрузка оператора void figure::operator (int i) { cout << "(" << massiv.x << "," << massiv.y << ")" << endl; } В нужный момент вызываю оператор, но пишет, что он без побочного эффекта, и ничего не выводит f
C++ Масив через рекурсию В упорядоченном массиве целых чисел ai, i = 1 ... n найти номер элемента "c" методом бинарного поиска, используя очевидное соотношение: если c<= an/2, тогда c є1...аn/2] , иначе c єn/2+1...an] . Если элемент c отсутствует в массиве, то вывести соответствующее сообщение. Решить двумя способами с рекурсией и без нее.. спасибо! http://www.cyberforum.ru/cpp-beginners/thread960854.html
Перегруженные шаблоны C++
Написать перегруженные шаблоны для решения уравнения: ax^2+bx+c=0
C++ Перегруженные функции
Написать перегруженную функцию, которая возвращает площадь квадрата, прямоугольника, треугольника и круга. Считать, что для вычисления площадей фигур заданы целые величины длин сторон, а для круга – еще и pi =3.1415926
C++ Создание перегруженных функций http://www.cyberforum.ru/cpp-beginners/thread960846.html
Написать перегруженную функцию, которая возвращает сумму двух целых чисел, трех целых чисел, двух слов
C++ Двухмерний Масив char Как на с++ описать динамический масив символов в таблицу? подробнее

Показать сообщение отдельно
Melg
537 / 158 / 64
Регистрация: 23.09.2013
Сообщений: 314

Абстракция вызова функции - C++

23.09.2013, 23:45. Просмотров 966. Ответов 12
Метки (Все метки)

Итак я хотел бы обсудить с участниками форума такую задачу. Но перед тем как перейти к сути - замечу, что вопросы морально-этического облика человека, поставившего эту задачу, и степень адекватности постановки задачи впринципе - не должны стать ключевыми в ходе обсуждения. К сожалению ввиду множества нюансов описание может затянуться и боюсь это вопрос не из серии "С++ для начинающих", но доступа к той ветке у меня нет. Итак преступим.
Предположим, что на стороне пользователя (другого программиста использующего мой код) имеется некоторая функция, это может быть метод класса, статическая функция, или функция определённая глобально. Эта функция может иметь любое число параметров ( от нуля т.е foo(); до N т.е foo(T1 o1, T2 o2, T3 o3,...TN oN). У этой функции может быть любой тип возвращаемого значения. При этом функция может использовать любой тип передачи параметров и возвращаемого значния - т.е по значению, по ссылке, по указателю и т.д.
Задача: Необходимо создать такой механизм, который бы позволил пользователю используя мой код, в runtime этапе по своему желанию сначала зарегестрировать свою функцию в некотором объекте, а после - вызвать её через этот объект. (Для условности мы можем назвать его Delegate delegate. В процессе регистрации (одной или несколькими операциями) - должна быть задана сама функция, все объекты - аргументы функции, а так же некоторый способ обработки возвращаемого значения функции.
Подробнее: пользователь на момент регистрации функции создает все необходимые объекты, соответствующие сигнатуре функции, и регистрирует их, после чего эти объекты должны будут использоваться при вызове зарегестрированной функции, пользователь определяет некоторый алгоритм (функцией или объектом класса) который умеет обработать возвращаемое значение.
Пара примеров для иллюстрации: Допустим у меня есть функция int PrintIntValue(int value_for_print); - которая выводит значение переданного парметра на экран, и если она отработала успешно - то возвращает 0, иначе -1. Допустим у меня есть уже готовое значение равное 42. И есть некоторая функция, void HandleErrorCode(int error_code); Которая принимает значение кода ошибки, и в зависимости от кода - пишет в лог файл ( на экран, в консоль - не суть важно) - некоторую информацию (время возникновения, код и т.д.). Я хочу Имея объект Delegate delegate; Зарегестрировать некоторым образом (каким угодно) три перечисленных выше парметра (функция, набор конкретных значений параметров для вызова, и обработчик возвращаемого значения), а после - где-то в другом месте кода - иметь возможность сделать вызов delegate(); (ну или delegate.CallFunction(); ) после которого будтет выполнена последовательность: вызов функции с переданным значением 42 в качестве параметра PrintIntValue(42); -а после возврата значения - вызов функции c переданным кодом ошибки HandleErrorCode(*);
Требования: вызов delegate.Callfunction(); - можно производить неограниченное число раз. После того как в delegate была зарегестрирована одна функция, ничто не должно мешать зарегестрировать в нем другую, например метод класса, который принимает массив указателей на объекты, и ничего не возвращает. И после этого - вызов delegate.CallFunction(); Будет вызывать уже этот метод, и его обработчик вызова ( например который подсчитывает число вызовов), а не предыдущую функцию.
Ограничения: для реализации нельзя использовать сторонние библиотеки, нельзя использовать boost, можно использовать любые решения из std. Можно использовать любые возможности языка включая стандарт с++11. Сам класс Delegate - не должен быть шаблонным, должна быть возможность объединения некоторого набора объектов в любые структуры - например в список, для последовательного вызова CallFunction - для всех объектов в списке. Можно использовать шаблоны, в том числе с переменным числом аргументов. При этом вызов delegate.CallFunction(); должен быть всегда валидным, и если не зарегестрирована никакая функция, и если внутри зарегестрированной фукнции кидается исключение произвольного типа, и если обработчик кидает исключения. При регистрации пользователем своего "супового набора" - ему должна либо сразу предоставляться готовая функциональность - либо любой набор промежуточных абстракций, но пользователь в конечном счете не должен писать дополнительный код для реализации какой-то из абстракций, только код, непосредственно конкретизирующий его намерение зарегестрировать функцию, но он так же может использовать любые возможности языка и стандартной библиотеки. При вызове функции через delegate.CallFunction(); должны соблюдаться способы передачи парметров и возвращаемого значения в точности, для каждого из элементов. Если была функция, которая принимала один аргумент по ссылке, другой по значению, а третий по указателю, при этом возвращая указатель, то после вызова, аргумент, зарегестрированный и передназначеный для передачи по ссылке - в пользовательском коде - реально должен измениться, а обработчик вызова должен получить указатель на адрес памяти, который вернула функция. Реалзация должна быть максимально быстрой, (как ориентир: если сравнивать прямой вызов функции, с переданными в неё параметрами, и вызов обработчика значения, с таким-же вызовом, реализованным через delegate.CallFunction(); - время вызова ( исключая время выполнения непосредственно тел функций) - должно быть не более чем в 10 раз больше чем прямой вызов).
Собственно вопрос: каким образом Вы бы предложили решать поставленную задачу. Интересует либо код, либо схема, либо словесное описание на русском языке, хотя-бы с приблизительным уровнем детализации. Заранее спасибо.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
Текущее время: 23:57. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru