| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > ромбовидное наслежлвание |
| Автор: fuckingniger 3.11.2010, 00:26 |
| ситуация такова: класс1 / \ класс2 класс3 \ / класс4 указатель на класс 1(по типу) нужно поставить на класс4 соответственно компилятор не знает через какую ветку это ему делать ...как бы ему это сообщить??? |
| Автор: Crafty 3.11.2010, 00:37 | ||
Используйте виртуальное наследование.
|
| Автор: fuckingniger 3.11.2010, 00:41 |
| так и сделано ...но дело в том что имеется массив указателей на класс 1 и нужно чтобы можно было указать на все классы ...т.к они производные. то есть этот массив будет хранить указатели на все объекты этой иерархии |
| Автор: mes 3.11.2010, 00:47 |
| 1. static_cast, если известно что тип соответсвует, 2. dynamic_cast с проверкой соответсвия в рантайме 3. организовать архитектуру с сопоставлением иерархии объектов к иерархии операций, подробнее в поиске по "двойная диспетчеризация" Добавлено через 1 минуту и 27 секунд тип наследования (ромбовидный) к проблеме не относится.. |
| Автор: fuckingniger 3.11.2010, 01:08 |
| static помог спасибо |
| Автор: mes 3.11.2010, 01:12 |
чтоб быть уверенными что он помог правильно, разберитесь внимательно когда нужно использовать статик_каст, а когда диамик_каст.. |
| Автор: fuckingniger 3.11.2010, 01:42 | ||||||||||
declaration of 'worker'
почему такая ошибка ?...ведь вроде бы всё правильно написано worker_procent_of_sum наследник worker и почему тогда он не полтиорфный ??? |
| Автор: mes 3.11.2010, 01:49 |
| полиморфным класс становится при наличии хотя бы одной виртуальной функции ( в том числе и виртуального деструктора).. |
| Автор: fuckingniger 3.11.2010, 01:51 |
| а dynamic_cast только к полиморфным можно применять? чем простые хуже? |
| Автор: fuckingniger 3.11.2010, 01:59 |
| то есть если я щас возьму сделаю 1 полиморфную функцию в worker то всё заработает? Добавлено через 3 минуты и 1 секунду и правда ошибки не стало ...чудеса да и только |
| Автор: mes 3.11.2010, 02:03 |
насчет всего не знаю, но эта ошибка пропадет .. |
| Автор: fuckingniger 3.11.2010, 02:15 |
| извините, что столько вопросов, но не клеится что-то сегодня . имеется массив указателей на класс1 под названием workers я при помощи static_cast преобразую указатель на класс4(из 1 поста) к классу1(чтоб хранить можно было в массиве) а потом для вызова специфических функций класса 4 делаю обратное преобразование при помощи dynamic_cast . вылетает след ошибка : http://savepic.net/77225.htm |
| Автор: Леопольд 3.11.2010, 08:10 | ||||||||||
Обратного неявного преобразования нет, поэтому нужно указывать static_cast. Однако, это "опасное" действие, потому что можно сделать так:
Добавлено @ 08:24 Возможно, выскакивает std::bad_cast (правда он возникает когда приводишь ссылки, а не указательи). http://cplusplus.com/reference/std/typeinfo/bad_cast/ Поведение dynamic_cast не очень очевидно. В случае с указателями, исключения не возникает, но указатель устанавливается в NULL. В случае с ссылками, вылетает исключение bad_cast (просто потому что ссылку нельзя установить в NULL)
|
| Автор: baldina 3.11.2010, 11:20 | ||
Проверьте, включено ли в параметрах проекта runtime type info нужно для работы dynamic_cast, по умолчанию в VC выключено |
| Автор: Леопольд 3.11.2010, 12:17 |
| Тогда не компилировалось бы, нет? gcc так себя ведёт, если RTTI отключить. |
| Автор: fuckingniger 3.11.2010, 13:01 | ||||||||
Просто у меня почему-то не получается указателю на базовый класс(класс1) присвоить объект на самого дальнего наследника (класс 4)
у меня указатели и только указатели Добавлено через 11 минут и 16 секунд
http://savepic.net/94666.htm также вроде всё??? |
| Автор: fuckingniger 3.11.2010, 13:16 | ||||||
в строке
ошибка
worker - родитель а worker_percent_plus_base это класс4 на схемке из 1 поста Добавлено через 2 минуты и 33 секунды http://rghost.ru/3131552 вот весь проект на всякий случай |
| Автор: mes 3.11.2010, 13:52 | ||
потому что у Вас базовый дважды включен, так как наследование не виртуальное.. Добавлено через 1 минуту и 10 секунд та же причина.. Добавлено через 2 минуты и 2 секунды я то думал, Вам уже надо было давно сдать.. если время сть, вместотого чтоб костыли городить, может лучше сделать по человечески ? |
| Автор: fuckingniger 3.11.2010, 13:58 |
| я понимаю что надо разобрться с виртуальным наследованием но если коротко то везде надо написать virtual public вместо public? |
| Автор: mes 3.11.2010, 14:06 | ||
т.е. еще глубже в лес ? может не стоит так необдуманно ? |
| Автор: Master01 3.11.2010, 14:16 | ||
Если без виртуального наследования, то можно и так (Class4*) static_cast<Class2*>(Class1*) т.е. сначала явно кастите к нужной ветке, а потом уже простой каст на базовый класс |
| Автор: fuckingniger 3.11.2010, 14:30 |
| теперь уже ошибка появилась в реализации класса 4 он не может вызвать конструкторы для класса 2 и 3 Добавлено через 1 минуту и 52 секунды mes я то сдал. Просто дело в том что 1 предметная область и в неё пихать нада сначала просто классы потом наследование затем полиморфизм ...перегузка ...и шаблонами должно всё ограничиться Добавлено через 2 минуты и 40 секунд Master01 пробовал так - не работает у меня Добавлено через 9 минут и 9 секунд в классе 4 пишет что не доступного default конструктора для самого главного класса worker |
| Автор: mes 3.11.2010, 14:46 | ||
ну а сказать, что такое у Вас стало после добавления виртуального наследования не надо ? или форумчане сами должны догадываться ? добавьте в список инициализации конструктора 4го класса инициализацию виртуального класса.. |
| Автор: fuckingniger 3.11.2010, 14:52 | ||||||
после добавления виртуального наследования меня изменилось следующее:
это прямые предки worker больше ничего не изменял
как это делается?? |
| Автор: mes 3.11.2010, 14:56 |
| также как прямые предки инициализируете, так и косвенные виртуальные предки.. |
| Автор: fuckingniger 3.11.2010, 14:56 | ||||||
после добавления виртуального наследования меня изменилось следующее:
это прямые предки worker больше ничего не изменял
как это делается?? |
| Автор: mes 3.11.2010, 15:01 | ||
|
| Автор: fuckingniger 3.11.2010, 15:08 |
| mes - извиняюсь что-то и-нет тормозил просто да....заработало а в википедии такого не было) то есть если используешь виртуальное наследование - то надо явно вызывать конструкторы всех предков до точки начала этого наследования ??? я просто думал что они и так слишком часто у меня вызывались |
| Автор: mes 3.11.2010, 15:18 | ||
нет, инициализировать можно только прямые предки и виртуальные косвенные и дата_члены текущего класса.. явно нужно только те, у кого нет конструктора по умолчанию.. Добавлено через 1 минуту и 6 секунд заведите себе более надежный учебник, чем вики.. ее можно использовать лишь для внешнего ознакомления.. |
| Автор: fuckingniger 3.11.2010, 15:51 |
| mes это правда очень заметно повлияло на производительность .....у меня программа секунд 10 запускается |
| Автор: mes 3.11.2010, 16:03 | ||
правда ?! но однозначно, что повлияло не "это" |
| Автор: fuckingniger 3.11.2010, 16:04 |
| видимо пора перзагрузиться))) |
| Автор: fuckingniger 3.11.2010, 19:02 |
| меня клинит сегодня))) не надо запускать проект с флешки просто |
| Автор: Master01 3.11.2010, 19:15 | ||||
странно, вот этот код у меня работает нормально (VS2008 Express) Может я что-то не так понял ....
|
| Автор: fuckingniger 3.11.2010, 19:16 | ||
| Master01 не уверен но кажется что если конструкторы добавить то упадёт ..ну или у меня руки не оттуда растут что вполне вероятно Добавлено через 5 минут и 26 секунд ещё одна проблема(. Сделал класс 1 абстрактным (по заданию надо) теперь у меня 3 неразрешимых внешних символа в классе 3 и 4 . даже не знаю что вам выложить чтоб стало понятно ... вот ошибки :
вот весь проект : http://rghost.ru/3135108 |
| Автор: fuckingniger 3.11.2010, 19:38 |
| теперь не разрешает через :: обращаться к одноименным методам предков ... Добавлено @ 19:51 или не разрешает обращаться к виртуальным функциям предков через :: Добавлено @ 19:52 но мне надо сделать так : виртуальная функция потомка состоит частично из функции предка + ещё некоторый код в книге ща нашёл - именно так и делается а у мну косяки ( |
| Автор: fuckingniger 3.11.2010, 20:40 |
| (( |
| Автор: fuckingniger 3.11.2010, 21:24 |
| mes чувствую, что вся надежда на тебя !!! |
| Автор: mes 3.11.2010, 21:51 | ||
покажите пример использования.. ( в прикрепленном проекте искать лень )
добавьте определение соответствующих функций, а если есть, то проверьте сигнатуры на несовпадение.. |
| Автор: Леопольд 3.11.2010, 22:37 |
| fuckingniger, мне кажется что ты неправильно понимаешь для чего нужно public наследование. Не для того что-bы повторно использовать bазовый класс и его данные, а наоbорот, что-bы использовать наследника через унифицированный интерфейс bазового класса. Оbычно в роли интерфесов использются аbстрактные классы, которые "заставляют" переопределить чистые виртуальные функции у наследника. Как правило, при таком подходе подоbное (двойное) наследование не нужно. P.S. оbычно, каст от bазового к наследнику говорит о неправильном проектировании. |
| Автор: mes 3.11.2010, 22:49 | ||
при чем тут паблик-наследование ?! |
| Автор: Леопольд 3.11.2010, 23:46 | ||
При том что только public позволяет кастовать к bазовому типу. При этом неявно. В тоже время, это не пользовательский каст, т.е. в цепочке таких кастов может bыть bольше одного.
protected и private наследование не позовляют делать такой каст, даже явный, так что использовать указатель на bазовый класс для раbоты с виртуальными функциями не выйдет. Такое наследование скорее bлиже к агрегации по смыслу. P.S. новички часто допускают ошиbку в виде невиртуального деструктора в bазовом классе, при этом делая delete на него. Если класс предназначен для наследования интерфейса то нужно или определить protected деструктор или виртуальный public деструктор. Если не читал, то стоит почитать "стандарты программирования на С++", Александреску и Саттер. Квинтэессенция знаний в виде простых правил. |
| Автор: fuckingniger 4.11.2010, 01:13 | ||||||
| в классе percent_plus_base (самый последний наследник ) ругается на print как и во все остальных впрочем вот пример в этом классе
ругается также в worker_procent_of_sum.obj как он пишет и также на print
а вот в worker_with_base и то же самое
Добавлено через 8 минут и 31 секунду MES !!!! |
| Автор: fuckingniger 4.11.2010, 01:43 |
| в хедерах объявлено что print просто виртуальная функция (начиная с класса worker - абстрактного (чисто виртуальная функция там = salary )).....что не нравится - не могу понять |
| Автор: mes 4.11.2010, 01:45 |
ну неужто трудно скопировать сообщение компилятора ? из за его отсутствия придется код пересматривать.. Добавлено через 1 минуту и 14 секунд это типа прикрик, почему я до сих пор не занялся Вашей темой ? |
| Автор: fuckingniger 4.11.2010, 01:51 | ||||
это огромная надежда лично на ВАС!!! сообщения компилятора скопированы чуть выше ....но вот ещё раз -правда чутка поменялись......
|
| Автор: mes 4.11.2010, 01:55 | ||
так на эти сообщения уже был ответ.. о том что нет тела функции названных методов.. Добавлено через 2 минуты и 27 секунд а почему не находит, смотрите внимательно.. или к проекту не все файлы подключены он не компилит или просто ребилд надо сделать.. или где то разница в написании - не узнает.. |
| Автор: fuckingniger 4.11.2010, 01:59 |
| ну понимаете просто пока не завиртуалил функции - всё работало ...так то тела есть и написаны правильно ... посмотрите пожалуйста опытным взглядом Добавлено через 50 секунд завиртуалил (абсолютно ) salary и print просто |
| Автор: mes 4.11.2010, 02:02 |
=0 показывает компилятору, что тела не должно быть.. если Вы этого не поставите, то обязаны написать тело.. |
| Автор: fuckingniger 4.11.2010, 02:05 | ||||
| mes - всё так и есть хедер
реализация
Добавлено @ 02:06 пока скилла просто нет -не понимаю вообще в чём дело даже примерно ( Добавлено через 2 минуты и 50 секунд что - то с принтом .....ума не приложу что |
| Автор: mes 4.11.2010, 02:17 | ||
ну разницы на вид нет..а остальные два пункта проверили ? |
| Автор: fuckingniger 4.11.2010, 02:20 | ||||||||||||||||||||||
worker.h
worker.cpp
worker_with_base.h
worker_with_base.cpp
worker_procent_of_sum.h
worker_procent_of_sum.cpp
worker_procent_plus_base.h
worker_procent_plus_base.cpp
и не особо относящееся к делу company.h
company.cpp
Добавлено через 4 минуты и 14 секунд компилил и линковал заново - кучу раз причём причём при компиляции не ошибок - все на линковке - подключено вроде бы всё - как я себе представляю(оно и до этого всё было подклюдчено) Добавлено через 4 минуты и 54 секунды и забыл main вот
|
| Автор: mes 4.11.2010, 02:25 | ||||
| вес- код можно (желательно) было не выкладывать, а только те куски что имееют значение... т.е. где непосредственно фигурируерт принт.. Добавлено через 29 секунд
|
| Автор: fuckingniger 4.11.2010, 02:34 |
| print фигурирует везде собственно а ругается на него в percent_plus_base предположительно строка - 16 worker_procent_of_sum предположительно строка - 23 worker_with_base предположительно строка - 18 в общем везде где переопределяется print Добавлено через 4 минуты и 35 секунд какие 2 пункта ? f7 и ctrll+f7 нажимал... всё вроде присоединено (в ресурсах и сурсах всё есть ) |
| Автор: mes 4.11.2010, 02:40 | ||
мм... как трудно в этой теме.. говорите об ошибке не приводя ее содержимого.. приводите весь код, а не нужные фрагменты о том что сделали, а что нет не рассказываете уточняющие вопросы обходите стороной.. форумчане не видят что у Вас там происходит, что Вы делаете, и что планируете... итак
|
| Автор: fuckingniger 4.11.2010, 02:43 |
| ничего особого не делал - тупо везде подключал много раз всё подряд - результата 0 Добавлено через 11 секунд про 2 пункта чуть выше |
| Автор: mes 4.11.2010, 02:50 |
ну вот опять.. я ведь не знаю какая у Вас иде , и к чему приаттачены эти клавиши... чтоб убедиться, что у вас иде все правильно сделалал, сотрите вручную в целевой папке все .obj и .exe и снова скомпилите .. |
| Автор: fuckingniger 4.11.2010, 02:55 |
| mes ты просто гений !!! я думал раньще - такое невозможно!!!! это глюк компилятора???? |
| Автор: mes 4.11.2010, 02:56 |
скорее глюк ИДЕ.. Добавлено через 1 минуту и 14 секунд если, конечно, Вы правильные клавиши нажимали.. |
| Автор: fuckingniger 4.11.2010, 03:08 |
| я и мышко тоже щелкал)))) а что такое иде???раскладка??? |
| Автор: mes 4.11.2010, 09:38 |
нет.. http://forum.vingrad.ru/forum/topic-270683/kw-compiler-linker-preprocessor.html |