LINUX.ORG.RU

Параметризированная перегрузка: продолжение


0

0

Проблему решил так:

#define MAX_FUN
1. Вариант
class A {
public:
A();
typedef void (A::*pF)(int a);
vector<pF>;

f1(int a);
f2(int a);
..................
};

A::A() {
pF.resize(MAX_FUN);
pF[0] = &A::f1;
.......................
pF[MAX_FUN] = &A::fMAX_FUN;
}

Ну в общем понятно.
Так же можно сделать так

2. Вариант
class A{
public:
virtual void f1(int a) = 0;
}

class B : public A {
public:
void f1(int a) {cout << "Class B\n";}

}
........ Тут еще наследуем

Ну и создаем массив указателей на объект типа A, содержащий
указатели на производные классы.

1. Какой из методов лучше ?

2. А, если, у всех ф-ций будут разные типы аргумента a ?
f1(float a), f2(double a) и т.д. для варианта 1, и для ф-ций f1
разный тип в производных классах вариант 2.

Думаю, надо делать как-то так:

template<class X> class A {
public:
virtual void f1(X a) = 0;
};

class B : public A<float> {
void f1(float a);
};
......................

Но тогда вопрос какой тип должен иметь массив указателей на ф-ции
(Вариант 1) и объектов (Вариант 2) ? Ведь прототипы указателей тогда
будут у всех разные - (*f1)(X a), где Х - какой-то тип.


PS: И что ты изобретаешь? Диспетчеризацию оконных сообщений такую чтобы идентификатору сообщения соответствовал метод класса?

Absurd ★★★
()
Ответ на: комментарий от Absurd

> Как ты намерен сравнивать float-ы если их равенство нельзя проверять через == ?

А зачем мне их сравнивать ? не понял... Уточню, полиморфный параметр а предназначен только для внутреннего использования функцией, выбор ф-ции осуществляется по целочисленному индексу из массива указателей.

drZlo
() автор топика
Ответ на: комментарий от guest-3484-2009

> вы используете C++?

Прозреваю lisp хочеш предложить ты ). Скорость исполнения очень важна. > А вы можете по пунктам объяснить - зачем

Задача описана выше по ссылке.

drZlo
() автор топика

В общем-то задачу я решил тупо - f1(void *a); Но хочется как-то гламурно, через шаблоны )

drZlo
() автор топика
Ответ на: комментарий от drZlo

>Уточню, полиморфный параметр а предназначен только для внутреннего использования функцией, выбор ф-ции осуществляется по целочисленному индексу из массива указателей.

А можно хотя бы приблизительный сценарий работы того что ты пытаешься реализовать?

Absurd ★★★
()
Ответ на: комментарий от drZlo

>В общем-то задачу я решил тупо - f1(void *a);

Вообще-то f(Param a) можно привести к f() если забиндить к первому параметру инстанс Param. Это расширяется на произвольное количество аргументов если биндить несколько раз.

>Но хочется как-то гламурно, через шаблоны )

Не смешно. Шаблоны имеют плюс в том что они type-safe, и кучу минусов сводящихся к тому что они в отличие от (внешнего) препроцессора не позволяют сформировать *произвольный* код в статике и при этом не имеют никакого интерфейса с динамикой.

Absurd ★★★
()
Ответ на: комментарий от Absurd

Бин. данные достаю из файла. Они могут быть разного типа (int, float, double и т.д.), причем и организацмя хранения может быть разной. Для автоматизации обработки в файле введен признак типа данных (целое число), который является индексом массива указателей ф-ций-членов. По индексу (из файла) выбирается из массива ф-ция, реализующая алгоритм для данного типа данных. Так же мне посоветовали фабрику. Как я понял, почитав Александреску, это массив указателей абстрактного класса,каждый элемент которого инициализирован указателем производного класса с переопределенной виртуальной ф-цией. Но, если мне надо, чтоб эти ф-ции имели и аргументы разных типов, т.е. прототипы у ф-ций разные, то с методом массива указателей у меня не получается. Конечно, требование полиморфизма здесь избыточно, но просто стало интересно как такое можно реализовать )

drZlo
() автор топика
Ответ на: комментарий от drZlo

Фабрика какбе подразумевает чтение целых объектов из файла. То есть при записи в файл объект записывает в файл идентификатор типа и следом за ним все поля, рекурсивно вызывая то же самое для вложенных объектов. При чтении объекты инстанциируются из фабрики по метке типа записанного пишущим методом, читают из потока свои поля и рекурсивно инстанциируют вложенные объекты с помощью той же фабрики. Делать метку типа для примитивных полей вроде int/float это слишком мелко.

Absurd ★★★
()
Ответ на: комментарий от Absurd

> Делать метку типа для примитивных полей вроде int/float это слишком мелко.

Понятно, но для моей задачи достаточно )

drZlo
() автор топика
Ответ на: комментарий от drZlo

>> Делать метку типа для примитивных полей вроде int/float это слишком мелко.

>Понятно, но для моей задачи достаточно )

Обычно примитивы читают и пишут большими блоками по нескольку килобайт. По паре виртуальных вызовов на каждый int это слишком жирно.

Absurd ★★★
()
Ответ на: комментарий от drZlo

> В общем-то задачу я решил тупо - f1(void *a); Но хочется как-то гламурно, через шаблоны )

Если типов три штуки, то и задача решается в три строки. Я может чего-то, конечно, недопонимаю. Но зачем усложнять и делать код менее прозрачным ради сомнительных целей? Если представленное решение красиво - то у меня видимо напрочь отсутсвует вкус...

smh ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.