Здравствуйте, unreg_flex, Вы писали:
_>Приведу код, надеюсь так будет понятней:
Вот за это спасибо.
_>typedef bool (Manager::*Listener)(double data);
_>class Manager {
_>public:
_> void AddListener(int nSlot,Listener pListener) {
_> // тут производится добавление pListener в некоторый список
_> ...
_> }
_>}
_>Этот класс менять нельзя.
Я так понимаю, в "некоторый список" добавляется пара (this,SomeMemberFunc)?
В противном случае это заподлянка: колбек-функция без пользовательского параметра.
_>Но хочется добавить в класс производный от Manager несколько методов, которые будут автоматически
_>генерировать некорые часто используемые типы Listener-ов (дабы не писать их каждый раз ручками),
_>например так:
_>_>class CoolManager: public Manager {
_>public:
_> template< class Object >
_> void AddCoolListener(int nSlot,Object *pObject) {
_> Manager::AddListener(nSlot,&CoolManager::CoolListener< Object >);
_> }
Не получится.
Указатели на объекты — ковариантны (указатель на наследника приводится к указателю на базу), а указатели на члены — контравариантны (указатель на член базы приводится к указателю на член наследника).
class Base
{
.....
void bbb();
};
class Derived : public Base
{
.....
void ddd();
};
void play_bm(void (Base::*f)()) { Base b; (b.*f)(); }
void play_dm(void (Derived::*f)()) { Derived d; (d.*f)(); }
void play_br(Base& b) { p.bbb(); }
void play_dr(Derived& d) { d.ddd(); }
int main()
{
// контравариантность членов
play_br(&Derived::ddd); // если бы скомпилировалось, то получим b.ddd() и вылетим
play_dr(&Base::bbb); // d.bbb() - всё законно, член bbb унаследован
// ковариантность объектов
Base b; play_dr(b); // если бы скомпилировалось, то получим b.ddd()
Derived d; play_br(d); // d.bbb()
}
Давай, показывай полностью объявление класса Manager. Будем искать точки кастомизации.
К>>О, кстати! Пришла в голову идея хака, действующего глобально. Точнее, обеспечивающего независимость между единицами трансляции.
_>Вот за это +3, хоть проблему это не решает (есть макросы), но это интересный способ увеличить диапазон действия __COUNTER__.
_>Вроде просто, но сам я не догадался
_>Кстати, а почему это хак???
Потому что эта штука, хотя и легальна, но отлично работает лишь в узких рамках.
Покуда все объекты в рантайме можно уникально идентифицировать местом в исходниках, где они создаются — всё работает.
Добавляем циклы, повторные вызовы, косвенность — до свидания.
И главное, что ты это не диагностируешь, пока не подорвёшься на нарушении логики работы.
... << RSDN@Home 1.2.0 alpha rev. 655>>