//родитель
class Class1
{
...
void (Class1::*p)(void)
...
}
//потомок
class Class2:public Class1
{
...
}
Как описать указатель на метод класса-потомка?(C++)
Ситуация такая:
Есть класс-родитель с полем типа "указатель на метод класса" и его потомок
Код:
Указатель p наследуется таким, каким был в родителе, т.е. может указывать только на методы Class1
Как можно описать указатель p так, чтобы он указывал на метод текущего класса (т.е. потомка), а не на метод родителя?
Цитата:
Указатель p наследуется таким, каким был в родителе, т.е. может указывать только на методы Class1
Классы потомки имеют доступ (можно сказать "содержат") к открытым и защищенным полям класса-предка.
Цитата:
Как можно описать указатель p так, чтобы он указывал на метод текущего класса (т.е. потомка), а не на метод родителя?
это называется полиморфизм. Но p не видит методы кроме тех что описаны в предке.
Код:
class Class1
{
...
public:
virtual void method();
Class1 *p;
...
}
class Class2: public Class1
{
....
public:
void method();
void methodClass2();
....
}
main()
{
...
Class1 c1 = new Class1();
c1.p = new Class2();
c1.p->method(); // вызовется метод с класса Class2
c1.p->methodClass(); //ERROR
...
{
...
public:
virtual void method();
Class1 *p;
...
}
class Class2: public Class1
{
....
public:
void method();
void methodClass2();
....
}
main()
{
...
Class1 c1 = new Class1();
c1.p = new Class2();
c1.p->method(); // вызовется метод с класса Class2
c1.p->methodClass(); //ERROR
...
Но если вам просто нужно вызвать метод класса любым образом я бы предложил для вызова метода класса использовать не указатель на метод, а указатель на екземпляр класса. Я в С++ не силен но могу предположить что екземпляры потомков приводятся к типу родителя и проблем не должно возникнуть.
Кроме того передавая не метод а целый объект в качестве "оброботчика" вы получаете приемущество, поскольку выполнение метода может зависить от состояния переданного обекта.
ЗЫ. Модераторов прошу по рукам меня не бить за оффтоп. Помоему ето не лаба а самообучение.
Я тут попробовал это дело через шаблоны
Код:
template <class A> class C1
{
void(A::*p)(void)
...
}
class C2:public C1<C2>
...
{
void(A::*p)(void)
...
}
class C2:public C1<C2>
...
На этих примерчиках компиляция проходит без ошибок, а в курсаче - error LNK2019: unresolved external symbol "public: void __thiscall CUI<class CalcCUI>::Run(void), и так на все родительские методы ругается
Стоит дальше шаблоны копать или лучше другой путь искать?
Цитата: Генерал Фейлор
Блин, мне-то как раз надо c1.p->methodClass2() - в родителе прототипы методов не описываются, т.к. в потомке могут быть добавлены любые функции.
Почитал и не понял. Ты что хочеш с помощю класса предка вызывать новые методы потомка ??
Или тебе надо вызывать метод который есть у предка но который может быть переопределен в потомке ?
Стоит изменить архитектуру приложения.
Методы, на которые будут ссылаться указатели, в родителе не объявлены, а появляются (и описываются, и реализуются) только в потомках
stimpi, т.е. с шаблонами вряд ли прокатит?
Ну ладно, всем спасибо за помощь, буду пробовать по-другому
Цитата: Генерал Фейлор
Rebbit, мне нужно первое. В родителе есть указатели на методы и функция, которая работает с этим указателем.
Методы, на которые будут ссылаться указатели, в родителе не объявлены, а появляются (и описываются, и реализуются) только в потомках
Методы, на которые будут ссылаться указатели, в родителе не объявлены, а появляются (и описываются, и реализуются) только в потомках
Зачем такое делать ?
Что мешает сделать абстрактные функции в родителе ? Ведь ето по большому счету те же указатели. Если Появились новые функции в потомке то что для них - доделываются новые указатели в родителе ?
Указатели на функции применяются для калбек вызовов и наследование тут вообще ни при чем.
Я не могу понять смысла того что ты делаеш. Может розкажеш саму задачу.
написать прогу с консольным интерфейсом, выполненным в ООП (с наследованием и прочей фигнёй).
Интерфейс я хотел сделать так:
1. Класс-родитель содержит:
- список указателей на методы
- методы, работающие с этими указателями (добавление новых, запуск существующих)
2. Ну а классе-потомке добавляются сами функции. В родителе их нельзя заготовить, потому что родитель не знает, чего там надобавляют в потомок.
Т.е. в родителе реализован только интерфейс и запуск команд, а сами команды описываются и реализуются в потомке (или потомках).
Но сейчас решил с этим не париться, и родителю оставил только список команд и интерфейс пользователя (т.е. ввод команд). А потомок пусть обрабатывает свои команды сам, без указателей на методы. Различать их будут просто - по имени или по какому-нибудь ID :)