Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Указатель на метод в C++ (http://forum.oszone.net/showthread.php?t=29842)

pva 02-04-2004 11:40 206009

Есть классы A, и B : public A. Нужно, чтобы в A содержался список указателей на методы B. Известны только прототипы методов, но сколько и какие - не известно. Хотелось бы что-то вроде

A {
 typedef int(B::*handler)();
 map<int,handler> eventmap;
public:
...
}

B : public A {
 void handler1();
 void handler2();
...
}

Перевести B::* в A::* нельзя (требование ISO/C++), а в A класс B неизвестен.

hasherfrog 02-04-2004 13:04 206010

А что если перед объявлением A сказать, что есть такой класс B:
Код:


class B;
A {
 typedef int(B::*handler)();
 map<int,handler> eventmap;
... дальше все тоже самое, что и у Вас


pva 05-04-2004 11:57 206011

Ещё раз: класс B в A неизвестен. Например:
class Control {...}
...
class TrackBar : public Control {...}

Contol-у абсолютно пофигу на TrackBar.
Но хотелось бы поместить в Control обработчик события, который может не перекрывать TrackBar. Событие может и не обрабатываться, а вставлять пустую виртуальную функцию не хочется. Хочу сделать так:

class elink : public pair<UMSG, Handler> {
 bool operator<(...)
}

vector<elink> events;

... {
  ...
 i = lower_bound(events.begin(), events.end(), message);
 if (i!=events.end() && i->first==message) {
    (this->*Handler)(params)
 }
}

Это вроде как самая быстрая реакция на виндозные послания.

hasherfrog 05-04-2004 15:37 206012

Да, я понял. Все портит наследование  B : public A.
Цитата:

Цитата Страуструп
класс, который был поименован, но еще не был объявлен, нельзя использовать в качестве базового класса

Поэтому A должен быть объявлен до B. Но использование типа из класса B внутри его объявления обязывает компилятор знать полное объявление B, поскольку
Цитата:

Цитата Страуструп
Явное или неявное преобразование указателя или ссылки на производный класс к указателю или ссылке на один из его базовых классов должно однозначно относиться к одному и тому же объекту этого базового класса

А класс A не знает, каким образом его наследует B.
Вообще Ваша задача решается объявлением еще одного класса  - указателя на функцию и его использованием и в классе А и в классе В. Это не так красиво, как хотелось бы, но ИМХО, вариантов больше нет.

pva 08-04-2004 09:57 206013

Приятно, что в сети есть отзывчивые люди. С классом-функцией у меня, конечно, ничего не получилось (внутри не удаётся присвоить пресловутый A::* к B::*). Я сделал через union. Код получился овратительный, поэтому буду искать другие варианты. Спасибо, hasherfrog, за содействие; Возникнут какие мысли - подкинь, пожалуюста.


Время: 12:54.

Время: 12:54.
© OSzone.net 2001-