C++ и указатели на методы

Все о программировании под *nix
Аватара пользователя
satanic_mechanic
Интересующийся
Сообщения: 56
Зарегистрирован: 18 июл 2003, 01:36
Контактная информация:

C++ и указатели на методы

Сообщение satanic_mechanic »

Итак, я хочу иметь клаcc op_table, содержащий таблицу указателей на функцию. Я определяю тип
typedef void (op_table::* op_func) ();

После этого я наследую от op_table новый класс pyxis_op_table, который уже будет содержать конкретные фунекции.

Но через указатель на метод op_table я не могу вызывать методы производного класса.

Объясните
1. Как работают указатели на члены класса;
2. Почему не работает мой код (читать вывод компилятора я умею, скажите как заставить работать) ;
3. Как сделать то, что я хочу грамотно.

(... - пропущенный код)

cat op_table.hxx

Код: Выделить всё

#ifndef __op_table_hxx
#define __op_table_hxx

#include "../runtime.hxx"

namespace engine_stuff {

  struct op_table_exception {
    enum op_table_exception_type {
      index_out_of_range
    } type;

    op_table_exception (op_table_exception_type t): type (t)
    {}
  };

  class op_table {
  public:
    typedef int op_index;

    typedef void (op_table::* op_func) ();

  private:
    runtime * rt;

  protected:
    op_func * op_tbl;
    int size;

  public:
    op_table (runtime & r);
    virtual ~op_table ();

    void op (int index);
  };

};

#endif //__op_table_hxx
cat op_table.cc

Код: Выделить всё

#include "op_table.hxx"

engine_stuff::op_table::op_table (runtime & r): rt (&r)
{}

engine_stuff::op_table::~op_table ()
{}

void
engine_stuff::op_table::op (int index)
{
  if (index < 0 || index >= size)
    throw op_table_exception (op_table_exception::index_out_of_range);

  (this->*op_tbl[index]) ();
}
cat pyxis_op_table.hxx

Код: Выделить всё

#ifndef __pyxis_op_table
#define __pyxis_op_table

#include "op_table.hxx"

namespace engine_stuff {

  class pyxis_op_table: op_table {
  public:
    ...
    static const int op_push_const;
    ...

  private:
    ...
    void push_const ();
    ...

  public:
    pyxis_op_table (runtime & r);
    virtual ~pyxis_op_table ();
  };

};

#endif // __pyxis_op_table
cat pyxis_op_table.cc

Код: Выделить всё

#include "pyxis_op_table.hxx"

const int engine_stuff::pyxis_op_table::op_push_const =  9;

void
push_const ()
{
  ...
}

engine_stuff::pyxis_op_table::pyxis_op_table (runtime & r): op_table (r)
{
  op_tbl = new op_func[...];

  ...
  op_tbl[op_push_const] = pyxis_op_table::push_const; // !!! выдает ошибку здесь !!!
  ...
}

engine_stuff::pyxis_op_table::~pyxis_op_table ()
{
  delete [] op_tbl;
}
Вывод:

Код: Выделить всё

pyxis_op_table.cc: In method `engine_stuff::pyxis_op_table::pyxis_op_table(engine_stuff::runtime &)':
pyxis_op_table.cc:22: assuming & on `engine_stuff::pyxis_op_table::push_const'
pyxis_op_table.cc:22: converting `void (engine_stuff::pyxis_op_table::*)()' to `void (engine_stuff::op_table::*)()' is a contravariance violation
pyxis_op_table.cc:22: conversion to `void (engine_stuff::op_table::*)()' from `void (engine_stuff::pyxis_op_table::*)()'
pyxis_op_table.cc:22: type `engine_stuff::pyxis_op_table' is not a base type for type `engine_stuff::op_table'
pyxis_op_table.cc:22:    in pointer to member conversion
make: *** [pyxis_op_table.o] Ошибка 1
а по ночам, девушка, я программы пишу ...

sAm
Интересующийся
Сообщения: 42
Зарегистрирован: 03 дек 2003, 13:49
Откуда: г.Минск

Сообщение sAm »

>Объясните
>1. Как работают указатели на члены класса;

Для виртуальной функции - смещение в таблице виртуальных методов
Для обычных - адресс вычисляется для конкретного экземпляра объекта

>2. Почему не работает мой код (читать вывод компилятора я умею,
>скажите как заставить работать) ;

Указатели должны быть на виртуальные функции

>3. Как сделать то, что я хочу грамотно.

?
Если количесво обработчиков конечно - абстактный базовый класс и переопределение функции в потомках. Иначе friend класс обработчиков и т.д.

sAm

Ответить