Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Запутался с наследованием и полиморфизмом 
:(
    Опции темы
baldina
Дата 3.11.2010, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



Цитата

метод соотносится с классом D и работает с его данными

т.е. D, B и C связаны по смыслу, так? можно использовать дружбу.
но т.к. разработчик всех трех (четырех) классов один и может целиком влиять на проект, лучше изменить дизайн. например: почему B и C не могут использовать общедоступный интерфейс D?

Добавлено через 1 минуту и 52 секунды
я бы даже усилил: B и C связаны с D. при этом A не связан с D? или связан с чем-то более общим, чем D, но это не отражено в проекте?
PM MAIL   Вверх
Нитонисе
Дата 3.11.2010, 15:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: 2
Всего: 2



baldina, возможно архитектура классов у меня и не оптимальная, надо подумать, но интересовала именно техническая реализация моей задумки (пусть и не лучшей).

Что касается задачи - D производит некоторые вычисления, для которого требуются различные потомки А. При чем от конкретного типа потомка зависит алгоритм вычислений, при это из этих самых потомков А берутся некоторые данные. Результаты вычисления хранятс в D.

Пока реализовал все это через проверку типов, по аналогии с последним вариантом, что тут выкладывал.. ну а дальше посмотрю, может что-то более дельное в голову придет)
PM MAIL   Вверх
mes
Дата 3.11.2010, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 6
Всего: 250



Цитата(Нитонисе @  3.11.2010,  14:22 Найти цитируемый пост)
возможно архитектура классов у меня и не оптимальная,

ну тогда может поделитесь задачей, а не условными классами А,Б,Ц,Д.. ?
может кто подскажет что в таком случае подойдет.. 





--------------------
PM MAIL WWW   Вверх
Нитонисе
Дата 3.11.2010, 16:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: 2
Всего: 2



Цитата(mes @  3.11.2010,  15:25 Найти цитируемый пост)
ну тогда может поделитесь задачей, а не условными классами А,Б,Ц,Д.. ?может кто подскажет что в таком случае подойдет.. 

Задача техническая.
Цель - расчет балки - определение в ней внутренних усилий от нагрузки.
Класс А - это класс Нагрузка.
Классы В и С - это производные от класса Нагрузка - ТочечнаяНагрузка и ЛинейнаяНагрузка.
Класс D - это, собственно балка.
Таким образом запись Балка::РасчитатьУсилия(Нагрузка*) - вычисляет усилия в балке от аргумента. Причем в зависимости от конкретного типа аргумента (ТочечнаяНагрузка или ЛинейнаяНагрузка) выбирается свой алгоритм. В расчетах фигурируют такие параметры как ДлинаБалки (принадлежит классу Балки), а также ЗначениеНагрузки и ПоложениеНагрузкиНаБалке (это данные принадлежат семейству классво Нагрузка).
PM MAIL   Вверх
mes
Дата 3.11.2010, 16:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 6
Всего: 250



помимо расчета нагрузки балка что еще умеет ? 



--------------------
PM MAIL WWW   Вверх
xvr
Дата 3.11.2010, 17:03 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Цитата(Нитонисе @  3.11.2010,  16:09 Найти цитируемый пост)
Задача техническая.
Классическая задача на multimethod (или double dispatch). См. http://en.wikipedia.org/wiki/Multiple_dispatch http://en.wikipedia.org/wiki/Double_dispatch

NB. Это конечно в том случае, если и Балка и Нагрузка по отдельности еще что то умеют


Это сообщение отредактировал(а) xvr - 3.11.2010, 17:04
PM MAIL   Вверх
baldina
Дата 3.11.2010, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



Цитата

задача на multimethod

вариант mes как раз на подпорки из-за отсутствия мультиметодов в С++ или поддержки аспектно-ориентированного подхода
PM MAIL   Вверх
Нитонисе
Дата 3.11.2010, 17:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: 2
Всего: 2



Цитата(mes @  3.11.2010,  16:41 Найти цитируемый пост)
помимо расчета нагрузки балка что еще умеет ?

Пока я до конца с ее функциями не определился, сейчас она вычисляет усилия от n-го количества нагрузок, некоторые расчетные параметры, которые не зависят от нагрузки, но используются в более сложных расчетах, рисует себя на канве, ну и предоставляет всем данные о себе (длина, внутренние усилия).

Объекты класса Нагрузка пока ничего делать особого не умеют, кроме предоставления всем информации о себе и рисования себя.

Добавлено через 34 секунды
Цитата(xvr @  3.11.2010,  17:03 Найти цитируемый пост)
Классическая задача на multimethod (или double dispatch)

Ох с инглишом туго  smile 
PM MAIL   Вверх
baldina
Дата 3.11.2010, 17:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



но таки ругань в сторону ТС была неоправдана, каюсь. double dispatch нужен, так что visitor в помощь

Добавлено через 3 минуты и 40 секунд
multimethod это множественный полиморфизм, когда функция для вызова определяется не по одному типу, а по нескольким типам аргументов:
типа
Код

class shape {};
class rectangle : public shape {};
class circle : public shape {};

virtual intersect (shape&, shape&) = 0;

intersect (rectangle&, rectangle&) {}
intersect (rectangle&, circle&) {}
intersect (circle&, circle&) {}

C++ не поддерживает, для  реализации используются подпорки типа visitor

Добавлено через 6 минут и 54 секунды
а у Нитонисе вероятно это
Код

virtual calc_stress (Элемент&, Нагрузка&) = 0;
calc_stress (Балка, ТочечнаяНагрузка) {}
calc_stress (Балка, ЛинейнаяНагрузка) {}


Добавлено через 10 минут и 11 секунд
если от теории к практике, то скорее всего типов элементов может быть много, заранее неизвестно каких, а типы нагрузок известны заранее, так что может быть самое разумное их просто захардкодить в виде отдельных функций для каждого элемента.
PM MAIL   Вверх
Нитонисе
Дата 3.11.2010, 18:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: 2
Всего: 2



Цитата(baldina @  3.11.2010,  17:37 Найти цитируемый пост)
если от теории к практике, то скорее всего типов элементов может быть много, заранее неизвестно каких, а типы нагрузок известны заранее, так что может быть самое разумное их просто захардкодить в виде отдельных функций для каждого элемента.

Тут дело в том, что мне в любом случае нужно в классе Балка прописывать алгоритмы обработок тех или иных нагрузок.
То есть, я сначала хотел в классе балка сделать так
Код

class Beam  // балка
{
  public:
    calculate(LinearLoad *load) {M = length*load->getValue();} // операция показана условно, LinearLoad - линейная нагрузка
    calculate(DotLoad *load) {M = length/load->getValue();}     // операция показана условно, DotLoad - точечная нагрузка

  protected:
    float length;
    float M;
}

И в программе использовать так
Код

Load *linLoad = new Load;  // Load - базовый класс для LinearLoad и DotLoad
Load *dotLoad = new Load;
Beam beam;
beam.calculate(linLoad);   // по типу аргумента определяем какой именно calculate() задействовать
beam.calculate(dotLoad);


Но как выяснилось это не работает и теперь я делаю так
Код

class Beam  // балка
{
  public:
    calculate(Load *load) 
       { 
            if (LinearLoad *ll = dynamic_cast<LinearLoad*>(load))
                M = length*ll->getValue();
            if (DotLoad *dl = dynamic_cast<DotLoad*>(load))
                M = length*dl->getValue();
       }

  protected:
    float length;
    float M;
}

Вобщем-то в любом случае, если у меня добавится новый тип нагрузки мне пришлось бы либо объявлять еще один метод  calculate(), где в качестве аргумента была бы новая нагрузка. И соответственно новый алгоритм расчета прописывать.
Либо в проверку типов (как по второму варианту) включать проверку на новый тип нагрузки и прописывать свой алгоритм.

Это сообщение отредактировал(а) Нитонисе - 3.11.2010, 18:14
PM MAIL   Вверх
mes
Дата 3.11.2010, 18:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 6
Всего: 250



а в чем отличие точечной нагрузки от линейной ?

и вопрос.. библиотека будет логически полной ? или предполагается дать возможность пользователю определять новые сущности ?

 и еще, что является наследником балки ?


Это сообщение отредактировал(а) mes - 3.11.2010, 18:39


--------------------
PM MAIL WWW   Вверх
Нитонисе
Дата 3.11.2010, 18:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: 2
Всего: 2



Цитата(mes @  3.11.2010,  18:35 Найти цитируемый пост)
а в чем отличие точечной нагрузки от линейной ?

Точечная нагрузка прикладывается к какой-то конкретной точке балки, соответственно один из параметров нагрузки - координата точки приложения. У линейной нагрузки такого нет - она прикладывается на всю длину. Операции расчета усилий я написал условно, по факту же, если аргумент точечная нагрузка, то наряду со значением нагрузки из нее запрашивается и точка приложения.


Цитата(mes @  3.11.2010,  18:35 Найти цитируемый пост)
и вопрос.. библиотека будет логически полной ? или предполагается дать возможность пользователю определять новые сущности ?

Имеется ввиду новые типы нагрузок? Пользователь такой возможности иметь не будет, а я, как разработчик, могу добавить новые типы.


Цитата(mes @  3.11.2010,  18:35 Найти цитируемый пост)
 и еще, что является наследником балки ?

На самом деле тут я немного тоже упростил. Любая балка имеет две опоры. Опоры могут быть различные - шарнир, жесткая опора или свободный край (консоль). Так вот наследники Балки - это разные типы с точки зрения опирания. То есть есть такие классы БалкаШарнирШарнир (две шарнирные опоры), БалкаШарнирЖесткая (слева шарнир, справа жесткая опора) и т.д. У каждого типа балки внутренния усилия от одной и той же нагрузки определяются по разному.
PM MAIL   Вверх
baldina
Дата 3.11.2010, 19:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



потом окажется, что балки могут иметь разные сечения, потом - учитывать податливость опор...
классификация обширная)))
PM MAIL   Вверх
Нитонисе
Дата 3.11.2010, 19:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 917
Регистрация: 5.11.2009

Репутация: 2
Всего: 2



Цитата(baldina @  3.11.2010,  19:12 Найти цитируемый пост)
потом окажется, что балки могут иметь разные сечения, потом - учитывать податливость опор...классификация обширная)))

Это намек, что виды опор можно было сделать свойствами класса Балка, а не плодить потомков?) Может и так, но тут дело в том, что это мой первый проект, где я решил опробовать объектный-ориентированный подход, поэтому где-то обоснованность принятия того или иного решения не важна, а важно практическое знакомство с особенностями ООП - наследованием и полиморфизмом.

У меня кстати, в контексте этого объектно ориентированного подхода есть один вопрос. Есть класс А, который является частью В, а В является частью С, который в свою очередь является частью D. то есть такая последовательная вложенность. А есть внешний класс Е, которому часто требуется обращаться к параметрам и А, и В, и С, и D, но логично установить связь всего лишь с верхним классом - D. И теперь получается, что если мне надо получить некоторые данные класса А, выполняя операцию Е, то появляется такая цепочка:
Код

E::method(D* d)
  {
      d->getC()->getB()->getA()->getSomeData();
  } 

Что-то как-то это коряво выглядит.

Это сообщение отредактировал(а) Нитонисе - 3.11.2010, 19:31
PM MAIL   Вверх
xvr
Дата 3.11.2010, 19:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Цитата(Нитонисе @  3.11.2010,  19:30 Найти цитируемый пост)
Может и так, но тут дело в том, что это мой первый проект, где я решил опробовать объектный-ориентированный подход, 
Ох, не ту вы задачу выбрали для первого проекта  smile 
Цитата

поэтому где-то обоснованность принятия того или иного решения не важна, а важно практическое знакомство с особенностями ООП - наследованием и полиморфизмом.
То, что вы хотите, выходит за рамки ООП, как оно реализовано в С++. 

В вашем случае функции расчета нагрузки не должны быть членами класса 'Балка'. Равно как и членами класса 'Нагрузка'. Это должны быть вообще отдельные сущности, выбираемые по сочетанию динамических типов 'Балка/Нагрузка'

Цитата(Нитонисе @  3.11.2010,  19:30 Найти цитируемый пост)
сть класс А, который является частью В, а В является частью С, который в свою очередь является частью D.
Это наследование (как одна из возможных реализаций)
Цитата(Нитонисе @  3.11.2010,  19:30 Найти цитируемый пост)
Код

d->getC()->getB()->getA()->getSomeData();
А это динамическое агрегирование (как одна из возможных реализаций). Вы уж определитесь, что у вас 'есть'


PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0648 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.