Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
Гипопотам
Зарегистрирован: 12.08.2005 Сообщения: 3
|
Добавлено: Вт Мар 14 2006 01:31 Заголовок сообщения: Про полиморфизм в С++: можно ли сделать такое и как? |
|
|
Доброе время суток!
Хочу запрограммировать на с++ семейство объектов, имеющих
следующую абстрактную наследственность:
Код: | AbstractParent
/ \
AbstractChild1 AbstractChild2
\ /
AbstractBattery
/ \
Real1 Real2
|
Есть общий родитель имеющий определяемую в дальних потомках
виртуальную функцию, на его основе есть много (в примере - два)
наследников, делающих некоторые вещи по-разному, но эту самую
виртуальную функцию они тоже не уточняют. Дальше я хочу получить
объект, в идеале, также наследника родителя, но можно и нет,
имеющего ту же виртуальную функцию и позволяющего на этапе
конструктора выбирать свойства одного из ранее созданных потомков.
А от него уже должны идти потомки, в которых определяется виртуальная функция.
Что за странная предметная область - спросите Вы?
Таких много - это и стек протоколов TCP/IP, где из под протоколом IP
множество сред передачи, а над ним - TCP и UDP, имеющиеся возможность
иной раз сливаться снова в один.
Это и семейство функций F(G(x)) над произвольным кольцом и т.п.
Я пишу так:
Код: | class AbstractParent
{
public:
virtual int DoSpecialFunction(void)=0;
// some data and methods to be placed here
};
class AbstractChild1 : public AbstractParent
{
// some data and methods to be placed here
};
class AbstractChild2 : public AbstractParent
{
// another data and methods to be placed here
};
class AbstractBattery : public AbstractParent
{
AbstractParent * selected;
public:
AbstractBattery(int i)
{
switch(i)
{
case 1: selected=new AbstractChild1(); break;
// ошибка получается вот здесь:
// error C2259: 'AbstractChild1' : cannot instantiate abstract class due to following members:
// warning C4259: 'int __thiscall AbstractParent::DoSpecialFunction(void)' : pure virtual function was not defined
case 2: selected=new AbstractChild2(); break;
}
}
};
class Real1 : public AbstractParent
{
public:
Real1(int i):AbstractBattery(i){}
int DoSpecialFunction(void){return 1;}
};
class Real2 : public AbstractParent
{
public:
Real2(int i):AbstractBattery(i){}
int DoSpecialFunction(void){return 2;}
};
|
Ясное дело, он не компилируется, т.к. нельзя брать объекты с неопределёнными
виртуальными функциями. Но как же тогда сделать такую конструкцию средствами С++?
Можно, конечно уйти от виртуальных функций, сделав указатель на функцию, switch и т.п.,
но ведь это неэстетично: чем тогда в данном случае с++ лучше Си без плюсов с
его структурами и указателями на функции... Есть подозрение, что что-то я про
с++ не знаю, должно же жто как-то решаться.
Заранее спасибо за ответы. |
|
Вернуться к началу |
|
|
kolobok0
Зарегистрирован: 22.04.2005 Сообщения: 253 Откуда: Мсква
|
Добавлено: Вт Мар 14 2006 14:53 Заголовок сообщения: Re: Про полиморфизм в С++: можно ли сделать такое и как? |
|
|
Гипопотам писал(а): | ...Заранее спасибо за ответы. |
возможно что то не так понял, но что то у Вас туман в логике...
си плас плас - есть продолжение, или формализация (понимайте как хотите) Обьектно Ориентированного подхода. Нравиться Вам или нет. Другими словами - не нужно мучительно что то искать... Представляйте на месте обьектов привычные в жизни сущности...
например машины, колёса, руль, дермантин, салон, бензобак, ДВС и т.д..
Судя по рисунку - Вы нарисовали красивое древо наследования(?) из которого видно что AbstractBattery УЖЕ СОДЕРЖИТ чайлда одын и чайлда два... То бишь под них память уже отведена, гораздо раньше чем передасться управление их конструкторам.
Судя по коду - тут совсем другая архитектура...
типа
AbstractParent
| | | | |
| | | | -AbstractChild1
| | | ----AbstractChild2
| | -------AbstractBattery
| ---------Real1
------------Real2
Все классы порождены от одного... почуйствуйте разницу...
Так что Вы сначала определитесь - что Вам нужно то, а то не понятно что хочеться...
Судя по задаче - Вам требуется вообще третье...
Наследование линейно и в нём вообще нет "схлёстываниям". А те проблемы которые нужно решать на уровне более нижнем - решаеться вызовом конкретных методов, конкретных классов. Если на уровень выше (ну не понятно какой там с верху обработчик) - дык всегда можете позвать ОБЯЗАТЕЛЬНый (или не совсем) виртуальный метод и вуаля - глагол отработался...
И ышо...
Рекомендую взглянуть на книгу Джефа Элджера "C++" - очень на мой взгляд интересные аспекты излагаются...
найдёте тут... с верху книга 32 кажись...
http://ftp.anyhost.ru/books/www.krf.bsu.by/
с уважением
(круглый) |
|
Вернуться к началу |
|
|
Kefir
Зарегистрирован: 16.04.2005 Сообщения: 443 Откуда: Пермь
|
Добавлено: Вт Мар 14 2006 15:04 Заголовок сообщения: |
|
|
Кажется, то что вы описали возможно. Но делать так не надо НИКОГДА!!! ДЛаже если и будет работать максимум через неделю вы запутаетесь в своем коде. Про семейство протоколов TCP/IP, в корне неверно! TCP, UDP не должны наследоваться от IP. а если появится Другой протокол сетевого уровня как вы его к своей иерархии присобачите... я кнешно понимаю желание наследовать все от всего, но это не правильно. Даже больше скажу наследование штука редкая, редко используется более 3х уровней наследования... Даже представить себе не могу такого. Но находятся умельцы, которые танк наследуют от пулемета... |
|
Вернуться к началу |
|
|
Гипопотам
Зарегистрирован: 12.08.2005 Сообщения: 3
|
Добавлено: Ср Мар 15 2006 13:56 Заголовок сообщения: |
|
|
Спасибо всем за ответы. Обошёлся множественным наследованием. Есть свои минусы, но в целом - пойдёт. |
|
Вернуться к началу |
|
|
|