![]() |
Модераторы: bsa |
![]() ![]() ![]() |
|
Zakary |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 59 Регистрация: 3.5.2006 Репутация: нет Всего: нет |
здраствуйте
![]() есть сейчас программа....использует наследование. (наследование это называется?) надо сделать так чтобы использовала полиморфизм. надо сделать вектор поинтеров к объектам класса checkingAccount и savingsaccount. разрешите указать кол-во денег чтобы снять со счета используя debit(), или положить используя credit(). определите тип счета. (определить тип - как? использовать надо typeid? по другому можно? как используется typeid?) а по другому можно? если счет savings - посчитать процент используя функцию calculateInterest. если счет checking - если транзакция успешная, то снять деньги за транзакцию. все коды есть....надо только сделать теперь это с помощью полиморфизма. неважно pure virtual это или просто virtual. чистая виртуальная функция называется?. класс абстрактный получается. вообще в россии обычно используют checkingAccounts. можно расплачиваться в магазине и т.д...а savings просто сберегательный, деньги только в банкомате снять можно.... ![]() вектор поинтеров легко сделать.
вот мой код. нет как таковой функции main ещё. просто проблема в том что я не знаю куда что переносить и делать virtual. про полиморфизм читал-читал...а тут непонятно как делать:
|
||||
|
|||||
Rififi |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1254 Регистрация: 9.3.2008 Репутация: 3 Всего: 36 |
Zakary,
фига себе улыбочка... тут животик надорвать можно (: полиморфизм у тебя работать не будет. он предполагает наличие виртуальных функций в классе, коих не наблюдается. определите тип счета. (определить тип - как? использовать надо typeid? по другому можно? как используется typeid?) а по другому можно? никакой typeid использовать не надо. в классе должна быть виртуальная функция которая возвращает тип
в наследниках переопределяешь GetType, возвращаешь нужный тип. всё. с остальными функциями аналогично. |
|||
|
||||
Zakary |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 59 Регистрация: 3.5.2006 Репутация: нет Всего: нет |
class Account
{ public: Account(double); void setBalance(double); double getBalance(); virtual void credit(double); virtual bool debit(double); void printBalance(); private: double balance; }; я ставлю virtual на 2 функции credit and debit. в одном наследнике эти функции изменены чуть. во втором классе они берутся из главного класса. вопрос: "Можно ли мне вызывать функцию credit и debit для savingsAccount не писав эти функции в savigns?" или надо virtual тоже? дальше. virtual AccountType GetType() = 0; это pure virtual. значит надо в двух наследниках засовывать эти функции. ЧТО буду возвращать эти функции? и КАК ![]() ![]() |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
в том варианте, что предложил Riffi, с каждым типом у Вас должно быть проассоцированно целое число, которое и будет возвращать упомянутая функция объекта каждого типа. И по значению этого числа Вы сможете косвенно определить какого типа у Вас объект. Однако этот вариант оставляет желать лучшего, так как для операций с объектом придется делать динамическое приведение типа. Но объяснять Вам более сложною, но надежную конструкцию, ИМХО, будет смысл только после того как разберетесж с основами ![]() |
|||
|
||||
Zakary |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 59 Регистрация: 3.5.2006 Репутация: нет Всего: нет |
а мне кажется можно и объяснить, а?
![]() ну пожалуйста.... будет мне очень полезно....хотя бы вкратце ![]() |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
||||
|
||||
fry |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 257 Регистрация: 4.10.2006 Репутация: 2 Всего: 3 |
Zakary, используй dynamic_cast. Для его использования необходимо, чтобы твои классы содержали виртуальную функцию (можешь читать как полиморфизм). используя его с указателем на интерфейсный класс (суперкласс с перечислением твоих методов в виде чисто виртуальных функций, это с "...=0") ты можешь узнать конкретный тип. Конкретный вариант исполнения можешь прогуглить (ИМХО долго искать не придется).
|
|||
|
||||
sdukshis |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 92 Регистрация: 23.3.2009 Репутация: нет Всего: 1 |
В этой задаче действительно лучше использовать динамический полиморфиз.
Если вкратце то идея такая: У вас есть базовый класс с методами debit() и credit() И есть его наследники, которые определяют собственные реализации этих методов. Далее нужно хранить набор указателей на эти классы. Поскольку хранить в контейнерах можно, только однотипные данные, то храниться будут указатели на базовый класс. Главное, что бы при вызове методов вызывались именно для данного типа счета. Все это позволяет реализовать динамический полиморфизм на основе виртуальных функций. Синтаксис примерно следующий
|
|||
|
||||
Zakary |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 59 Регистрация: 3.5.2006 Репутация: нет Всего: нет |
а как мне в таком коде вызывать функции с дочернего класса. что-то типа v[1]->setInterestRate не рабоатет ведь =\
а в конструкторах дочерних инициализация такая и останется разве? :Account(b)? |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
потому что операция не полиморфна. есть три (как минимум) варианта решения Вашей задачи (вызова setInterestRate текущего объекта, зная только указатель на базовый класс) 1 Сделать эту функцию в базовом классе, а. и результатом возвращать успешность применения операции к объекту текущего класса (т.е если текущий объект типа checking, то ф-ция ничего не сделает и вернет false) б. также ничего не делает, но для проверки можно ли применить эту операцию к текущему объекту сделать еще одну дополнительную ф-цию например HaveSetIntererestRate. 2.a. Каждому типу присвоить целое значение, например 1 для checking и 2 для saving. Возвращать это значение посредством виртуальной функции базового класса getType () и через switch в зависимости от возвращаеммого значения посредством dynamic_cast получать указательтекуего типа объекта. т.е примерно так switch (pBase->getType()) { eChecking : .. eSaving : { pSavingAccount * p = dynamic_cast<pSavingAccount*>(pBase); p->SetInterestRate (..); break; } } б. делать сразу динамик_каст и если не нуль то значит объект нужного типа и применять к нему операцию. if (pSavingAccount * p = dynamic_cast<pSavingAccount*>(pBase)) p->SetInterestRate (..); 3. использовать паттерн визитор, пример по ссылке двумя постами выше. 3й - самый безопасный вариант, наиболее подходит для вашего случая, но требует усилий и понимания основ. у двух остальных много слабых мест, но для простых задачек подойдут. Если двойного наследования не предвидится (наследование от детей), то на текущем этапе знаний легче всего будет применить 2б. |
|||
|
||||
toxx |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 653 Регистрация: 4.3.2009 Где: НН Репутация: 4 Всего: 13 |
fry dynamic_cast используется если программа не продумана тут вродебы можно вполне обойтись одними указателями и полиморфизм будет.
Потом если косвенно обращаться к методам... вобщем всё окей будет. |
||||
|
|||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
||||
|
||||
toxx |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 653 Регистрация: 4.3.2009 Где: НН Репутация: 4 Всего: 13 |
mes
Имел ввиду без dynamic_cast лучше делать. |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
без него конечно лучше, но мне что то подсказывает. что автор выберет именно этот вариант, так как остальное требует больших затрат. Буду рад, если ошибся ![]() |
|||
|
||||
toxx |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 653 Регистрация: 4.3.2009 Где: НН Репутация: 4 Всего: 13 |
Когда мне требовался полиморфизм, я без dynamic_cast обошелся...Да и тут вродебы все не на столько сложно чтоб указателями пользоваться.Вобщем выбор за автором, но советую пользоваться указателями. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Для новичков" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |