| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Классы |
| Автор: bel_nikita 3.11.2003, 14:43 |
| проблема следующая: class Base {...}; class Derived: public/private Base {...}; Возможно ли следующие наследование: class Test: public Base, public Derived {...}; |
| Автор: maxim1000 3.11.2003, 15:11 |
| да |
| Автор: Ars 3.11.2003, 15:24 |
| Билдер такое откомпилить не даст, да и зачем? |
| Автор: bel_nikita 3.11.2003, 15:36 |
| maxim1000 что значит ДА? подскажи как реализовать таку схему такое у меня не компилиться Ars class Base - некий стандартный обработчик Derived - имеет свою обработку Test - свою Но при этом Derived подчинен Test'у и имее свои методы отличные от Test |
| Автор: Vyacheslav 3.11.2003, 17:10 | ||
Это почему? Если Base не производный от TObject, то позволяет в соответствии со стандартом С++ |
| Автор: Ars 3.11.2003, 17:35 | ||||
Прошу прощения, это Warning: W8024 Base class 'Base' is also a base class of 'Derived'. И, истинно, он прав. Какой смысл повторно наследовать от Base?
А в 6-м билдере дозволено множественное наследование и потомков TObject |
| Автор: maxim1000 3.11.2003, 18:00 |
| упс... немного ошибся показалось, что это ничему не противоречит, а оно запрещено (по крайней мере пробовал в VC, BC) там как раз выдаются ошибки P.S. а зачем така схема? |
| Автор: RAN 4.11.2003, 07:14 |
| По идее, принципам ООП такое определение не противоречит. Вопрос "зачем это надо", по-моему, не к месту. Мало ли зачем человеку два экземляра базового класса. Но не компилиться. Говорит, что потом к этому базовому классу не добраться. |
| Автор: Vyacheslav 4.11.2003, 10:03 | ||
Это справедливо только для наследования интерфейсов (полнсотью абстрактных классов). Для "нормальных" классов ограничения на наследование с TObject сохраняются |
| Автор: Ars 4.11.2003, 12:28 | ||||||
Значит, с точки зрения компиллятора это принципам ООП всетаки противоречит. Для него возникает неразрешимая неоднозначность
|
| Автор: shedon 4.11.2003, 12:35 |
| Да, по-моему, это вообще чушь, за чем два раза наследовать одно и тоже? |
| Автор: bel_nikita 4.11.2003, 13:20 | ||
shedon
Пример: class cA {...}; class cB: public/private cA {...}; class cD: public/private cA {...}; class cE: public/private cB, public/private cD {...}; Такое допустимо, и наследуется два раза одно и тоже А вот так: class cE: public/private cB, public/private cA {...}; не работает! Почему? |
| Автор: shedon 4.11.2003, 13:49 | ||
Такое допустимо, т.к. ты наследуешь два разных класса(cB и cD), у которых один базовый класс, такое может быть(класс cA в таком случае наследуется не явно). А вот когда ты наследуешь cB и соответственно наследуешь cA, плюс ещё явно наследуешь cA. Зачем это нужно ? |
| Автор: bel_nikita 4.11.2003, 16:34 | ||
shedon
И вопрос был в том, что возможно ли реализовать такую схему? А не в том зачем это нужно? В том то все и дело, что это нужно. Пример: есть некоторый стандартный обработчик, допустим class cA{...} - отвечающий и обрабатывающий работу таймеров. class cB: public cA {...} - имеет свои методы на события cA. class cС: public cA {...} - имеет свои методы на события cA. Но в тоже время class cС должен также включать в себя методы class cB. |
| Автор: maxim1000 4.11.2003, 17:27 |
| но ведь класс cB включает методы класс cA, значит, при подключении cB в класс cC в нем и так будут методы обоих классов |
| Автор: bel_nikita 5.11.2003, 10:06 | ||
maxim1000
это так, но сА иммет виртуальный метод. class cC - не может изменить метод cB. У него должен быть свой метод на сА. |
| Автор: Vyacheslav 5.11.2003, 17:17 | ||||||
Ну а кто тебе мешает использовать промежуточный класс
Что же касается вопроса: "Почему?
"Класс не может быть специфирован как прямой базовый класс производного класса более чем одинраз. Примечание: класс может быть косвенным базовым классом более одного раза и может быть прямым и косвенным базовым классом " |
| Автор: Vyacheslav 5.11.2003, 17:39 | ||||||||||
Если каждый раз оглядываться на конкретную реализацию компилятора, то от стандарта ничего не останется.
Интересно, откуда она возмется? По стандарту при таком наследовании создаются две копии TBase А этот код действительно не пройдет.
Тут надо обязательно уточнять:значение Value которой копии TBase нам требуется. Поэтому нужно так
|
| Автор: Ars 5.11.2003, 18:46 | ||
Вот-вот. Как укажешь TBase, там-то он и загнется от невозможности решить, из какой же копии брать значение |
| Автор: mr.DUDA 5.11.2003, 20:35 | ||
Народ, мне вот интересно, а почему никто не вспомнил про виртуальные базовые классы ?
При обычном наследовании (без virtual) схема такова: X ----> Y ----> D <---- Z <---- X При виртуальном - схема наследования будет такова: D<----- Y <---- X +<----- Z <---- + ИМХО, это именно то, что надо спросившему. © Подбельский В.В. "Язык Си++", 1999 |
| Автор: RAN 5.11.2003, 22:25 |
| Не вспомнили, потому что вопрос не про виртуальное наследование. Если говорить про виртуальное наследование, то я вот с чем сегодня столкнулся. Изучая заголовочные файлы VisiBroker'а, обнаружил такую схему наследования: class A { public: virtual void f(); }; class B : virtual public A { public: virtual void f(); }; class C : virtual public B, virtual public A { }; Во-первых, не понятно зачем вообще наследовать С от 2 классов. Это я объясняю тем, что разработчики так "подстраховались" Во-вторых, при компиляции в VC выдаётся предупреждение, что функции A::f() не доступна. |
| Автор: Vyacheslav 6.11.2003, 10:24 | ||||
Я так понимаю, Вы уже со стандартом спорите , а не со мной. И кто интересно загнется? Компилятор? Проверить очень просто. Возьмите компилятор, который поддерживает стандарт, например VC7++ и проверьте, загнется или не загнется А компилятор четко понимает, что TIzvtar::TBase::Value это совсем другое, чем TIzvrat::TDerived::TBase::Value |
| Автор: Ars 6.11.2003, 11:04 | ||||||
Можно и на ты Я все-таки иногда проверяю то, что пишу в форум и это как раз один из таких случаев А результаты таковы. Компилим вышеприведенный код под CBuilder6:
Под Visual C++ 6.0:
Т.е. int I=Izvrat->TBase::Value; в двух ведущих компиляторах не проходит. Я не хочу сказать, что это все противоречит принципам ООП, а только то, что это реализовать не получится, да и не нужно, кроме случаев академического программирования |
| Автор: Vyacheslav 6.11.2003, 12:33 | ||||
| К сожалению компиляторы С++Builder 6 и Visual C++ 6.0 в данном аспекте не соответсвуют стандарту. Кстати они далеко не ведущие. Я же указал, надо использовать Visual C++ 7.0. Что касается С++Builder 6, я уже пару дней назад отправил Borland'у bug report за номером 6367.
Что касается чисто академического вопроса, то практически он спокойно решается
При этом фактически отличий от первого варианта нет |
| Автор: Ars 6.11.2003, 12:40 |
| Ну, сдаюсь, сдаюсь. |