Название: Реализация интерфейса[РЕШЕНО] Отправлено: Даниил от Апрель 02, 2012, 10:56 Приветствую. Возник вопрос, незнаю где найти ответ - как сделать правильно, подскажите?
Имеется интерфейс: Код
Нужно написать реализацию метода для класса PNumber. Затык случился в момент осознания, что мы передаем в метод тип, которые не знает, о существовании PNumber::acc и соотвественно сложение там выполнить нельзя. Понимаю, что пример христоматийный, но не могу сам додумать и найти не могу в книжках. Подскажите, где искать? Название: Re: Реализация интерфейса Отправлено: Пантер от Апрель 02, 2012, 11:18 Закастать?
Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 02, 2012, 11:20 Закастать? А это правильно? Или есть стандартное решение из учебника?Мне тоже такое в голову лезет, но пока я упорно отбиваюсь от такой идеи. Название: Re: Реализация интерфейса Отправлено: Igors от Апрель 02, 2012, 12:09 Чтобы Вас не грызла совесть - в книжке такого точно нет. Делать операторы виртуальными нет смысла, т.к. все равно так или иначе придется каститься, причем весьма неудобно. Напр Вы написали
Код
Код
"Правильный" тот оператор который повторяет привычную логику операции без всяких классов. Разве + меняет операнды? Нет (для этого есть +=). Разве он возвращает по ссылке? Нет, по значению. Зачем же Вы пишете оператор + который не облегчает а наоборот? Код Хотя вероятно все это я пишу напрасно - с полгода назад Вы задавали примерно такой же вопрос :'( Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 02, 2012, 12:15 Хотя вероятно все это я пишу напрасно - с полгода назад Вы задавали примерно такой же вопрос :'( Курсовики похожие :) Только тогда была просто реализация. А теперь нужно написать интерфейс - базовый класс, от него породить 3 класса. Суть:Код Чтобы используя 1 интерфейс можно было манипулировать разными типами. P.S. Я помню вашу помощь, и ценю ваше внимание. Название: Re: Реализация интерфейса Отправлено: Igors от Апрель 02, 2012, 13:15 Ладно, разжалобили :) Сделайте так
Код В принципе ничего особо не выигрываем - и так и так приводиться надо. Но операторы лучше оставить "обычными", другие очень быстро "вынесут моск" Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 02, 2012, 13:52 Я сдаюсь. Посмотрите задание. Надеюсь меня не спалят >_<
Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 02, 2012, 15:59 Обычно операторы сложения, вычитания, умножения и деления делают в виде дружественных функций класса, а не его членами и в этом есть зерно здравого смысла)
Цитировать Код
Это плохая идея. Во-первых n и n1 - это указатели. Формально вы конечно можете их сложить и компилятор даже ничего не скажет) Но в результате получите бред) Поэтому в любом случае придётся писать делать каст. Не вижу смысла в базовом (чисто абстрактном) классе объявлять эти операторы, да ещё и виртуальными.. Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 02, 2012, 16:11 Ну да, я там погорячился с указателями - просто хотел передать смысл. А делать операторы сложения, вычитания ... в виде дружественных функций - это нарушение ООП. Так что, ата-та-та.
Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 02, 2012, 16:33 Ну да, я там погорячился с указателями - просто хотел передать смысл. А делать операторы сложения, вычитания ... в виде дружественных функций - это нарушение ООП. Так что, ата-та-та. Где это там нарушение ООП?)Вариант, когда операторы сложения, вычитания.. пишутся в виде функций, а не членов класса - это более гибкий подход. Он даёт возможность писать более сложные конструкции выражений. А вариант, когда эти операторы являются членами класса более ограничен в этом плане. Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 02, 2012, 16:43 Нарушение инкапсуляции идет. Я уже получил звездюлей за такую реализацию. О внутренних деталях класса должен знать только класс. А сторонние функции/классы должны иметь доступ только к методам.
Может быть в вашем случае большая гибкость получается - не спорю. Но типа как - не клёва ^_^ ;D ;D ;D Название: Re: Реализация интерфейса Отправлено: Igors от Апрель 02, 2012, 16:46 идея. Во-первых n и n1 - это указатели. Формально вы конечно можете их сложить и компилятор даже ничего не скажет) Очень даже скажет (указатель + целое = новый указатель, но не указатель + указатель) А делать операторы сложения, вычитания ... в виде дружественных функций - это нарушение ООП. Так что, ата-та-та. Лучше совершенствоваться в языке чем в демагогии. Я сдаюсь. Посмотрите задание. Надеюсь меня не спалят >_< С точки зрения ++ такая реализация (как в Вашей методичке) неосуществима. Код Это значит что все классы наследующие TANumber должны иметь свои операторы + описанные точно так же как этот. Код Тип возвращаемого значения другой - значит это уже другой (еще один) оператор. Компилятор будет вякать пока Вы не объявите так Код Иначе TReal - абстрактный класс и создавать объекты такого типа нельзя Я уже получил звездюлей за такую реализацию. Хмм.. ну вообще-то правильно дали (хоть и не за то что надо) :)Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 02, 2012, 16:53 В пятницу пойду поговорю с человеком, который оформлял задание и отпишусь о результатах. Ну, максимум в субботу.
Название: Re: Реализация интерфейса Отправлено: Igors от Апрель 02, 2012, 17:08 Не слишком полагайтесь на эту методичку. Напр там пишут
Код А правильно так Код Конечно не надо конфликтовать и пытаться чего-то доказывать. Просто молча пишите правильно, за это не убьют Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 02, 2012, 17:09 Нарушение инкапсуляции идет. Я уже получил звездюлей за такую реализацию. О внутренних деталях класса должен знать только класс. А сторонние функции/классы должны иметь доступ только к методам. Может быть в вашем случае большая гибкость получается - не спорю. Но типа как - не клёва ^_^ ;D ;D ;D Интересно, почему же тогда во всех серьёзных мат. библиотеках эти операторы (+ - *) делаются в виде дружественных функций? Вот небольшой пример: Код Попробуйте скомпилируйте это, когда оператор сложения - член класса. А если не получится, закомментируйте его и раскомментируйте вариант, где этот оператор в виде дружественной функции. Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 02, 2012, 17:13 Нарушение инкапсуляции идет. Я уже получил звездюлей за такую реализацию. О внутренних деталях класса должен знать только класс. А сторонние функции/классы должны иметь доступ только к методам. Может быть в вашем случае большая гибкость получается - не спорю. Но типа как - не клёва ^_^ ;D ;D ;D Интересно, почему же тогда во всех серьёзных мат. библиотеках эти операторы (+ - *) делаются в виде дружественных функций? Вот небольшой пример: Код Попробуйте скомпилируйте это, когда оператор сложения - член класса. А если не получится, закомментируйте его и раскомментируйте вариант, где этот оператор в виде дружественной функции. Операторы вывода "<<" или ввода ">>" всегда перегружают как дружественные, это исключение. Во всех учебниках написано. P.S. И да, что закоментирован, что не закоментирован дружественный оператор ;D Это читерство Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 02, 2012, 17:18 Цитировать Операторы вывода "<<" или ввода ">>" всегда перегружают как дружественные, это исключение. Во всех учебниках написано. Я говорю о операторе сложения. Тот пример, что приведён выше не будет работать, если оператор+ является членом класса. У подхода, когда подобные операторы выносятся в виде функций есть ещё одно преимущество.. Цитировать P.S. И да, что закоментирован, что не закоментирован дружественный оператор Это читерство Это вам для наглядности))Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 02, 2012, 17:24 В вашем примере - может и не будет. А вот в этом:
Код Все работает и сдано с оценкой - отлично. Кстати отчасти этой оценке я благодарен данному форуму :) Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 02, 2012, 17:36 Цитировать Все работает и сдано с оценкой - отлично. Кстати отчасти этой оценке я благодарен данному форуму Вы меня не понимать) Хорошо, объясню на вашем примере. Пусть у вас есть два класса чисел Number и NumberF. Так вот, если вы пойдёте по пути когда оператор+ у них будет членом, то выражения вида: Код
вам будет проблематично реализовать. Придётся лезть в эти классы и добавлять в них доп. операторы+ Тем самым создавая связи между этими классами, от которых в ООП так пытаются избавиться) Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 02, 2012, 17:39 Цитировать Все работает и сдано с оценкой - отлично. Кстати отчасти этой оценке я благодарен данному форуму Вы меня не понимать) Хорошо, объясню на вашем примере. Пусть у вас есть два класса чисел Number и NumberF. Так вот, если вы пойдёте по пути когда оператор+ у них будет членом, то выражения вида: Код
вам будет проблематично реализовать. Придётся лезть в эти классы и добавлять в них доп. операторы+ Тем самым создавая связи между этими классами, от которых в ООП так пытаются избавиться) Собственно я никогда и не хотел складывать разнотипные объекты*. Типы всегда одинаковые, это контролируется программно. Просто я хотел, чтобы они ссылки на них хранились в указателях на их базовый класс, чтобы в процессе работы программы, я бы мог сменить тип обоих указателей и выполнить сложение двух других типов. Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 02, 2012, 17:54 Цитировать Просто я хотел, чтобы они ссылки на них хранились в указателях на их базовый класс, чтобы в процессе работы программы, я бы мог сменить тип обоих указателей и выполнить сложение двух других типов. Как вы себе это представляете?Так: Код Так не получится. Number - чисто абстрактный класс и разыменовать n1 и n2 не получится. Какой смысл объявлять в интерфейсном классе Number эти операторы? Интересно, кто у вас там методички пишет?) Название: Re: Реализация интерфейса Отправлено: Igors от Апрель 02, 2012, 18:01 Код Все работает и сдано с оценкой - отлично. Код Вообще для оператора + "что в лоб что по лбу" - ведь он использует сам класс и все. Поэтому оператор-член и friend равноценны вам будет проблематично реализовать. Придётся лезть в эти классы и добавлять в них доп. операторы+ m_ax говорит умные вещи (иногда), стоит прислушаться. Почему те же операторы слива в поток обычно friend? Потому что если бы это были операторы-члены - нам пришлось бы писать такТем самым создавая связи между этими классами, от которых в ООП так пытаются избавиться) Код Потом, по каким-то причинам мы решили перевести I/O напр на Qt. Придется писать #include <QFile>, удалять #include <fstream> и кромсать хедер в котором PNumber. Вот они - те "плохие" связи. Поэтому лучше сделать PNumber независимым Так не получится. Number - чисто абстрактный класс и разыменовать n1 и n2 не получится. Чего ж это я не могу разыменовать указатель на абстрактный класс? Ну получу ссылку на абстрактный класс, все нормуль.Какой смысл объявлять в интерфейсном классе Number эти операторы? Интересно, кто у вас там методички пишет?) Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 02, 2012, 18:59 Мы отошли немного от темы. Вопрос в принципе теперь в лоб, т.к. мы уже разобрали множество вариантов: как лучше организовать? через касты или другие методы искать?
Название: Re: Реализация интерфейса Отправлено: Igors от Апрель 02, 2012, 19:21 Мы отошли немного от темы. Вопрос в принципе теперь в лоб, т.к. мы уже разобрали множество вариантов: как лучше организовать? через касты или другие методы искать? Ну выбора-то у Вас нет, кастить придется. Мое мнение что базовый класс должен иметь операторы которые вызывают виртуальные ф-ции которые уже вызывают "родные" операторы. См пример реализации выше. Не хотите "показаться слишком умным" - ну это можно понять, нормально. Тогда тупо передираете текст методички, только типы возвращаемых значений везде ставите TNumber (по-другому не получится). Ну и каститесь внутри каждого оператора. Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 02, 2012, 20:42 Вобщем, я пока так решил сделать, по вашим советам через касты:
Код Возможно слишком криво, но вполне отвечает задумке ;) Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 02, 2012, 20:57 Цитировать Код
Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 02, 2012, 21:11 Напишите проще, если сможете :P
Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 02, 2012, 23:23 Напишите проще, если сможете :P Нужно стремиться делать не как проще, а как правильнее)Я бы сделал примерно так (упрощённый вариант) Код Этот приём используется в boost ublas и в blitz, но совсем для другой цели - чтоб избавится от создания временных объектов (матриц, векторов) при операциях сложения, вычитания, умножения и пр. с ними. Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 03, 2012, 06:13 Что-то страшное вы здесь написали) Это я то страшное написал?!Чем ваш вариант правильнее моего? Тем, что уже так кто-то делал в популярной библиотеке? P.S. Хорошо, варианты реализации могут быть самыми разными. Я подстраивал свое решение под конкретную проблему, чтобы после иметь возможность добавлять другие классы не переписывая управляющих конструкций. Если интересно - позже могу выложить весь материал по данной проблеме. Название: Re: Реализация интерфейса Отправлено: Tonal от Апрель 03, 2012, 08:53 И никто не вспомнил о методе двойной диспетчеризации. :)
Правда, в данном случае для стандартных сигнатур операторов красиво не выйдет, поэтому проще показывать на обычных функциях. Это делается примерно так: Код Как можно убедится нигде нет нужды в явном приведении типов. :) Да и по эффективноси, данный метод добавляет всего 1 косвенный вызов, вместо переборов перечислений или сравнений строк. :) Двойная диспетчеризация - это частный случай реализации мультиметодов в С++. Работает с полиморфизмом по 2м параметрам вместо 1 как в обычной виртуальности. Можно расширить и на большее количество аргументов, если не боятся много писать. :) Короче, читайте Страуструпа - он рулит! :) Название: Re: Реализация интерфейса Отправлено: Igors от Апрель 03, 2012, 10:37 С удивлением обнаружил что, оказывается, в методичке все правильно написано - а я был неправ!
Код То есть виртуальные методы могут возвращать разные типы ссылок. Мда :) Название: Re: Реализация интерфейса Отправлено: Igors от Апрель 03, 2012, 10:51 Как можно убедится нигде нет нужды в явном приведении типов. :) Так ведь расплата за это "каждый класс знает каждого". И в данном случае он не очень к месту, т.к. не планируются смешанные операции с разнородными классами. А приемчик красивый, кстати он часто помогает "раскрутить" template Да и по эффективноси, данный метод добавляет всего 1 косвенный вызов, вместо переборов перечислений или сравнений строк. :) Название: Re: Реализация интерфейса Отправлено: Igors от Апрель 03, 2012, 11:16 Возможно слишком криво, но вполне отвечает задумке ;) Да все нормально, только типы возврата верните взад (это я насвистел) и не забывайте после dynamic_cast проверяться на NULLДело вот в чем Код Первое впечатление что такой кривой оператор написал безграмотный человек :) Но это не так. Дело в том что "нормальный" оператор мы никак не сможем уложить в виртуальный механизм т.к. он возвращает по значению. TReal & (ссылка) может быть чем-то иным, но "просто TReal" нет - это только объект типа TReal". Др словами чтобы работали виртуалы - приходится изуродовать нормальную логику операторов. Если уж идти "до упора", то тогда так Код Это сохраняет нормальную логику +, но на что тогда указывает возвращаемая ссылка? Можно напр хранить в кольцевом буфере. Ладно, это уже "как правильно", разумеется за рамками лабы, не парьтесь Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 03, 2012, 11:58 Другими словами логика правильная, нужно просто проверку делать на bad_cast? В обработку исключения не проще засунуть?
Название: Re: Реализация интерфейса Отправлено: Igors от Апрель 03, 2012, 12:09 Другими словами логика правильная, нужно просто проверку делать на bad_cast? В обработку исключения не проще засунуть? dynamic_cast не генерирует исключений а просто возвращает 0 если приведение невозможно. Проверяйте и вываливайтесь по нулюКод
Название: Re: Реализация интерфейса Отправлено: V1KT0P от Апрель 03, 2012, 12:12 Другими словами логика правильная, нужно просто проверку делать на bad_cast? В обработку исключения не проще засунуть? dynamic_cast не генерирует исключений а просто возвращает 0 если приведение невозможно. Проверяйте и вываливайтесь по нулюКод
Код Проще воспринимается. Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 03, 2012, 12:24 dynamic_cast не генерирует исключений а просто возвращает 0 если приведение невозможно. Проверяйте и вываливайтесь по нулю Не понял, а это тогда что? http://www.cplusplus.com/reference/std/typeinfo/bad_cast/ (http://www.cplusplus.com/reference/std/typeinfo/bad_cast/)Название: Re: Реализация интерфейса Отправлено: Igors от Апрель 03, 2012, 12:37 Не понял, а это тогда что? http://www.cplusplus.com/reference/std/typeinfo/bad_cast/ (http://www.cplusplus.com/reference/std/typeinfo/bad_cast/) Так это если приводите ссылку, а у Вас указатель. Ну в данном случае можно и ссылку приводить - дело вкусаМожет все-таки лучше так: Согласен :)Код Проще воспринимается. Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 03, 2012, 14:17 Цитировать Код
Первое впечатление что такой кривой оператор написал безграмотный человек Но это не так. Дело в том что "нормальный" оператор мы никак не сможем уложить в виртуальный механизм т.к. он возвращает по значению. TReal & (ссылка) может быть чем-то иным, но "просто TReal" нет - это только объект типа TReal". Др словами чтобы работали виртуалы - приходится изуродовать нормальную логику операторов. Код Изменяется и сам объект B, что кажется немного безумным) Вы складываете два числа и одно из них (B) также меняется в результате сложения. Или оно не меняется? Тогда почему передаётся по ссылке, а не по константной ссылке? Вобщем я считаю, что подобный выкрутас в контексте данного класса чисел, выглядит бредовым.. Имхо, можно найти решение и по изящней. Название: Re: Реализация интерфейса Отправлено: Igors от Апрель 03, 2012, 14:51 Изменяется и сам объект B, что кажется немного безумным) Там и первый операнд (сам класс) меняется - что, мягко говоря, нетипично для оператора + :)Вы складываете два числа и одно из них (B) также меняется в результате сложения. Или оно не меняется? Тогда почему передаётся по ссылке, а не по константной ссылке? И да, полное отсутствие const конечно минус авторам методички - потом очень трудно будет переучиваться, начнутся отмазки типа "та зачем, ведь и так работает" Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 03, 2012, 15:15 Цитировать И да, полное отсутствие const конечно минус авторам методички - потом очень трудно будет переучиваться, начнутся отмазки типа "та зачем, ведь и так работает" Дело даже не в том, что const, не const.. Просто им дают изначально задания из разряда - как делать не надо (в смысле как проектировать не надо), но при этом в полной уверенности что так и должно быть с точки зрения архитектуры.А потом, при использовании таких чисел неожиданно выясняется (это в лучшем случае) что все аксиомы математики противоречат таким числам) Название: Re: Реализация интерфейса Отправлено: Igors от Апрель 03, 2012, 16:03 Дело даже не в том, что const, не const.. Просто им дают изначально задания из разряда - как делать не надо (в смысле как проектировать не надо), но при этом в полной уверенности что так и должно быть с точки зрения архитектуры. Ну хорошо, вот допустим Вы (или я) преподаватель. И что? Это одного мы сможем как-то поднатаскать (в меру наших скромных сил) - и то надо возиться с ним ого-го сколько. А что делать с группой из 20 чел (а из них любят программирование дай бог 2)? Вдаваться в нюансы архитектуры явно бесполезно. Дать одно "творческое задание" на всех? Так они перепишут друг у друга. А настаивая на "глубоком изучении" мы быстро заработаем славу препода который "выделывается" и.т.п. :) По-любому приходится как-то упрощать, обрезать тонкости, иначе процесс образования невозможен.Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 03, 2012, 20:13 Изменяется и сам объект B, что кажется немного безумным) Как я понимаю, речь идет об отсутствии в описании метода спецификатора "const". Мне сначала показалось это ошибкой, но позже у меня возникли проблемы с кастованием константных данных. Если приведете работающий пример, буду признателен.Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 03, 2012, 20:44 Изменяется и сам объект B, что кажется немного безумным) Как я понимаю, речь идет об отсутствии в описании метода спецификатора "const". Мне сначала показалось это ошибкой, но позже у меня возникли проблемы с кастованием константных данных. Если приведете работающий пример, буду признателен.C = A + B; После такого сложения A и B изменят свои значения. Это нормально? Как вообще такими числами пользоваться? Суперматематика отдыхает)) Я вам уже приводил пример, но вам он не понравился( Посмотрите на пример, который привёл Tonal Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 04, 2012, 06:25 Я вам уже приводил пример, но вам он не понравился( Посмотрите на пример, который привёл Tonal Ни вы, никто другой не приводил пример в котором в метод передается значение, а после приводится к другому типу.Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 04, 2012, 09:31 Я вам уже приводил пример, но вам он не понравился( Посмотрите на пример, который привёл Tonal Ни вы, никто другой не приводил пример в котором в метод передается значение, а после приводится к другому типу.Смотрите: Кода в классе (абстрактном) пишут подобные объявления оператора+ Код Возникает подозрение, что у автора либо проблемы с математикой, либо непонимание в прегрузки операторов. Либо и то и другое) Причём, класс реализует число и, соответственно, все операции с этими числами не должны противоречить математике. Но вам в вашей методичке явно указывают как вы должны делать. Так вот так делать как раз не надо) Это костыльный безграмотный вариант. Или ещё не очевидно почему это так? Название: Re: Реализация интерфейса Отправлено: Tonal от Апрель 04, 2012, 09:39 Как можно убедится нигде нет нужды в явном приведении типов. :) Так ведь расплата за это "каждый класс знает каждого".Да и по эффективноси, данный метод добавляет всего 1 косвенный вызов, вместо переборов перечислений или сравнений строк. :) Хотя это действительно ограничение данного метода - при добавлении нового класса нужно добавлять функции его обработки во все классы. Иногда это можно ослабить с помощью наследования... И в данном случае он не очень к месту, т.к. не планируются смешанные операции с разнородными классами. Перечитал стартовый топик.ИМХО, задание как раз было на использование dynamic_cast либо сравнение type_info. :) Решения с перечислениями вполне аналогичны двойной диспетчеризации - и там и там нужно предварительно объявить состав производных классов. Причём решение с перечисленим хуже - т. к. не практически не проверяется компилятором. Да, нет нужды в смешанных операциях, то с добавлением нового класса меняется сигнатура только базового объекта: Код
А приемчик красивый, кстати он часто помогает "раскрутить" template В шаблонах как раз полиморфизм по всем параметрам. Так что там в этом приёмчике смысла большого нет. :)П. С. Да, в С++ разрешеатся в переопределённом виртуальном методе возвращать указатель/ссылку производного типа, а не того, который был объявлен в предке. Так что оператор в примере выше действительно виртуальный. Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 04, 2012, 10:35 Я вам уже приводил пример, но вам он не понравился( Посмотрите на пример, который привёл Tonal Ни вы, никто другой не приводил пример в котором в метод передается значение, а после приводится к другому типу.Смотрите: Кода в классе (абстрактном) пишут подобные объявления оператора+ Код Возникает подозрение, что у автора либо проблемы с математикой, либо непонимание в прегрузки операторов. Либо и то и другое) Причём, класс реализует число и, соответственно, все операции с этими числами не должны противоречить математике. Но вам в вашей методичке явно указывают как вы должны делать. Так вот так делать как раз не надо) Это костыльный безграмотный вариант. Или ещё не очевидно почему это так? Цитировать ... у меня возникли проблемы с кастованием константных данных. Если приведете работающий пример, буду признателен. Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 04, 2012, 10:51 Цитировать Я все понял, а вы очевидно не читаете мои сообщения, а рассуждаете наедине с самим собой. Я не спрашиваю вас как решить мою задачу. Это я уже понял сам. Я спросил вполне конкретный вопрос. А вы мои читаете? Цитировать ... у меня возникли проблемы с кастованием константных данных. Если приведете работающий пример, буду признателен. В вашем варианте (тот что в методичке) сделать каст по константной ссылке не получится. Угадайте почему) И как следствие при операциях сложения, вычитания и пр. у вас автоматически будут меняться сами числа, участвующие в данных операциях. Осмыслите то, что вы делаете, а не слепо следуйте сомнительным указаниям) Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 04, 2012, 10:56 Есть такие ситуации в нашей жизни, когда нужно сделать так, как говорят другие люди, т.к. за ваш труд платят они и вам лучше плюнуть на свою гордость ...
Но, что-то мы немного отвлеклись. Всем спасибо за участие в обсуждение, вы все мне помогли осмыслить новые приемы в программирование на C++. Спасибо, m_ax. Спасибо, Tonal. Спасибо, Igors. Спасибо, V1KT0P. Спасибо, Пантер (он кстати первым выдвинул корректную идею :P). Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 04, 2012, 11:03 Цитировать Есть такие ситуации в нашей жизни, когда нужно сделать так, как говорят другие люди, т.к. за ваш труд платят они и вам лучше плюнуть на свою гордость ... Да, есть такие ситуации, кто же спорит.. Только вот сейчас это вы платите за такие решения и за такое образование.. Название: Re: Реализация интерфейса Отправлено: Igors от Апрель 04, 2012, 12:35 struct SomeNumber : BaseNumber { Какой Вы умный :) А на что же ссылается возвращаемое SomeNumber ?virtual const SomeNumber& operator + (const BaseNumber& other) const } Даниил, не обращайте внимания, Ваша лаба (давно) ни при чем, это мы о том "как правильно" :) Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 04, 2012, 17:02 Вобщем, я пока так решил сделать, по вашим советам через касты: Что ж вы за люди такие, могли ж конкретно носом ткнуть, что изменяю второй операнд :'( Только сейчас нашел ...Код Возможно слишком криво, но вполне отвечает задумке ;) Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 04, 2012, 17:08 Цитировать Что ж вы за люди такие, могли ж конкретно носом ткнуть, что изменяю второй операнд Только сейчас нашел ... Уж какие есть) Хотя я об этом вам уже неоднократно писал. Но вы, видимо, не обращаете на это внимания.. Что ж вы за человек такой))Уверяю вас, вы ещё много костылей найдёте, если будете придерживаться той схемы, что предложена вам в той методичке.. Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 04, 2012, 17:12 Оригинальный у вас метод помощи, т.е. если к вам подбежит человек, у которого сломана рука, вы отправите его в магазин за книгой? (естественно вы будете точно знать, что книга там про переломы есть)
Я к тому, что можно было написать конкретно: "В вашем варианте, происходит изменения передаваемого по ссылке объекта". А не отправлять думать над архитектурой программы, ссылаюсь на некоторые возможные проблемы :\ *Сломанной ногой, с рукой сломанной ходить можно ... а тут явный баг будет =] Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 04, 2012, 17:20 Оригинальный у вас метод помощи, т.е. если к вам подбежит человек, у которого сломана рука, вы отправите его в магазин за книгой? (естественно вы будете точно знать, что книга там про переломы есть) Я к тому, что можно было написать конкретно: "В вашем варианте, происходит изменения передаваемого по ссылке объекта". А не отправлять думать над архитектурой программы, ссылаюсь на некоторые возможные проблемы :\ Перечитайте, пожалуйста повнимательнее мой пост № 38, № 43 и № 48 Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 04, 2012, 17:25 Действительно, нашел. Ну очень осторожный совет. Да, был не прав. Извиняюсь.
Но думаю, в след. раз вам не помешало бы более конкретно выражать ваши мысли. Название: Re: Реализация интерфейса Отправлено: Igors от Апрель 04, 2012, 17:25 Что ж вы за люди такие, могли ж конкретно носом ткнуть, что изменяю второй операнд :'( Только сейчас нашел ... Так написано же так Код p1 константная ссылка? Нет - ну значит этот оператор его будет менять. Забили на const - получайте Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 04, 2012, 17:31 Забили на const - получайте Не "забили", а не использовали, в виду либо невозможности, либо неопытности.Название: Re: Реализация интерфейса Отправлено: Tonal от Апрель 05, 2012, 11:43 struct SomeNumber : BaseNumber { Какой Вы умный :) А на что же ссылается возвращаемое SomeNumber ?virtual const SomeNumber& operator + (const BaseNumber& other) const } Ссылок в сигнатуре, конечно, быть не должно. Что, однако, никак не влияет на остальные рассуждения. :) Название: Re: Реализация интерфейса Отправлено: Igors от Апрель 05, 2012, 11:57 struct SomeNumber : BaseNumber { Какой Вы умный :) А на что же ссылается возвращаемое SomeNumber ?virtual const SomeNumber& operator + (const BaseNumber& other) const } Ссылок в сигнатуре, конечно, быть не должно. Что, однако, никак не влияет на остальные рассуждения. :) Название: Re: Реализация интерфейса Отправлено: Tonal от Апрель 06, 2012, 08:41 Ссылок в сигнатуре, конечно, быть не должно. Влияет т.к. возвращая по значению мы никак не сделаем оператор (реально) виртуальным. Что, однако, никак не влияет на остальные рассуждения. :) Причём сам же, в первом своём сообщении это учёл и написал: Правда, в данном случае для стандартных сигнатур операторов красиво не выйдет, поэтому проще показывать на обычных функциях. Хотя вариант сохранить сигнатуру таки есть :) Если к коду, приведённому в первом посте (http://www.prog.org.ru/index.php?topic=21490.msg149030#msg149030) добавить оболочку: Код: struct AllNumber { Название: Re: Реализация интерфейса Отправлено: Igors от Апрель 06, 2012, 12:29 Хотя вариант сохранить сигнатуру таки есть :) Ну "пользоваться только" - это несолидно. А почему не так... Код: struct AllNumber { Код
Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 06, 2012, 12:36 Самое правильное решение - это отказаться от такого кастыльного пути и вынести уже все операторы+ (-) и подобные бинарные операторы из класса, реализовав их по человечески в виде функций (возможно дружественных).
Тогда все ваши проблемы и потребность в этих костылях сами собой отпадут) Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 06, 2012, 12:48 Самое правильное решение Само по себе существование такого решения в мире программирования на C++ абсурдно. Есть субъективные мнения и не более. И даже это мнение субъективно.©Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 06, 2012, 12:53 Цитировать Само по себе существование такого решения в мире программирования на C++ абсурдно. Есть субъективные мнения и не более. И даже это мнение субъективно.© Почитайте про шаблонное метапрограммирование, в частности про шаблоны выражений в соседней ветки: http://www.prog.org.ru/topic_21540_0.html (http://www.prog.org.ru/topic_21540_0.html)Как альтернатива вашему подходу, которую люди не просто так с потолка взяли и которая не на пустом месте стала очень популярным и мощным решением. Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 06, 2012, 13:13 Цитировать Само по себе существование такого решения в мире программирования на C++ абсурдно. Есть субъективные мнения и не более. И даже это мнение субъективно.© Почитайте про шаблонное метапрограммирование, в частности про шаблоны выражений в соседней ветки: http://www.prog.org.ru/topic_21540_0.html (http://www.prog.org.ru/topic_21540_0.html)Как альтернатива вашему подходу, которую люди не просто так с потолка взяли и которая не на пустом месте стала очень популярным и мощным решением. Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 06, 2012, 13:20 Цитировать Само по себе существование такого решения в мире программирования на C++ абсурдно. Есть субъективные мнения и не более. И даже это мнение субъективно.© Почитайте про шаблонное метапрограммирование, в частности про шаблоны выражений в соседней ветки: http://www.prog.org.ru/topic_21540_0.html (http://www.prog.org.ru/topic_21540_0.html)Как альтернатива вашему подходу, которую люди не просто так с потолка взяли и которая не на пустом месте стала очень популярным и мощным решением. У меня ощущение, что вы всячески пытаетесь оправдать то, что с костылями ходить приятнее.. Но вы ведь даже не пробовали избавится от них. О чём здесь ещё можно говорить? Название: Re: Реализация интерфейса Отправлено: Igors от Апрель 06, 2012, 13:26 m_ax, ну Вы явно перегибаете палку. Хотим реализовать конструкцию
Код Используя полиморфный механизм. Почему это плохо, кАстыльно (от слова "cast") ? :) Во всей Вашей уничтожающей критике я не увидел ни одного мало-мальски весомого аргумента, а Ваши альтернативные предложения звучат странно. Ввести id типа - никак не в духе полиморфизма. Вынести операторы friend - и что, как это поможет с обобщенной алгеброй? Возможно template здесь более подходящий подход - согласен. Ну так "в огороде бузина, а в Киеве дядька". Чем виртуалы-то плохи? Я так вижу что только одним - что-то не получилось, не удалось сделать "по известным образцам", скопировать известное решение. И все - моментально срабатывает рефлекс "костыль! велосипед! посмотри на..". Грустно :'( Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 06, 2012, 13:30 Мне тож гручтно :'(
Путь кто нить приведёт пример нормального поведения (и полиморфного в том числе) для данной постановки задачи. Основываясь на тех рекомендациях, что приведены в методичке. Потом я приведу свой вариант и сравним) Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 06, 2012, 14:37 И да, кстатии,
Цитировать Хотим реализовать конструкцию Я в курсе что мы это хотим реализовать. Именно с возможностью полиморфизма. c = a + b; Используя полиморфный механизм. Почему это плохо... А плохо то, что вы пытаетесь писать костыль у которого больше минусов, чем плюсов, вместо того, что бы немного изменить архитектуру и тогда можно будет строить подобные конструкции, как используя полиморфизм: Код
так и использовать конструкции вида: Код И всё это можно реализовать гораздо изящнее. И сами числа у вас, не с того не с сего, не будут менять свои значения при таких операциях. Так что грустно, от того, что вы оправдываете изначально кривую архитектуру. А почему в методичке был поставлен так вопрос - это уже другая история (возможно печальная)) Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 06, 2012, 19:16 Так что грустно, от того, что вы оправдываете изначально кривую архитектуру. А с чего вы собственно взяли, что архитектура кривая?Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 06, 2012, 21:02 Так что грустно, от того, что вы оправдываете изначально кривую архитектуру. А с чего вы собственно взяли, что архитектура кривая?Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 06, 2012, 21:24 Реализацию я переписал, числа у меня значения при арифметических операциях не меняют. Мне проще написания обращения через указатели, чем через 3 класса, т.к. обращения к арифметическим операциям у меня идут в отдельном классе и упоминаются лишь единажды в проекте. Фактически ваш вариант займет физически больше кода. Есть еще у вас варианты в пользу использования вашего метода, а не кастования типов?
Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 06, 2012, 21:27 Реализацию я переписал, числа у меня значения при арифметических операциях не меняют. Мне проще написания обращения через указатели, чем через 3 класса, т.к. обращения к арифметическим операциям у меня идут в отдельном классе и упоминаются лишь единажды в проекте. Фактически ваш вариант займет физически больше кода. Есть еще у вас варианты в пользу использования вашего метода, а не кастования типов? Любопытно взглянуть) Не выложите исходники?Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 06, 2012, 22:11 Да, конечно. Вот, в первозданном виде.
Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 06, 2012, 22:42 Да, конечно. Вот, в первозданном виде. Поздравляю, Даниил! Вы действительно (худо-бедно) избавились от проблемы изменения чисел при мат. операциях над ними.Вот только приобрели другую проблему... Даже и не знаю, какая из них страшней... Название: Re: Реализация интерфейса Отправлено: Igors от Апрель 07, 2012, 03:10 А с чего вы собственно взяли, что архитектура кривая? Ну вообще-то кривая :) Это называется "мнимая общность". Неск классов наследуются от Number, и это можно как-то оправдать, мол, "все эти классы - числа". Но если посмотреть а что же общего у этих классов - то выясняется что аж ничего. Нет ни одного метода который общий и имеет смысл напр как для PNumber так и для ComplexNumber. "Все они имеют оператор +", ну так в Assistant есть десятки (или больше) классов с таким оператором, но на этом основании они не наследуются от одного базового.Но не стоит это воспринимать так трагически как делает m_ax :) Это просто учебный пример, вполне возможен случай когда классы действительно имеют достаточно общего, виртуалов и сделать еще и операторы виртуальными может быть вполне разумно. Да, конечно. Вот, в первозданном виде. Ой :) Так у Вас "течет" память. Если оператор вернул класс по значению, то он автоматычно удалится когда станет ненужным. Но если оператор вернет ссылку - удалять ее никто не будет, и память (которую Вы выделили через new) не будет освобождена.Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 07, 2012, 14:10 Цитировать Но не стоит это воспринимать так трагически как делает m_ax Это просто учебный пример, вполне возможен случай когда классы действительно имеют достаточно общего, виртуалов и сделать еще и операторы виртуальными может быть вполне разумно. :) Нет, я не драматизирую) Кривость архитектуры здесь не в том, что они наследуются от "мнимой общности".. Фиг с ней, пусть наследуются - это как раз и даст им возможность полиморфизма. Дело то в другом. Они пытаются забивать гвозди утюгом, в уверенности, что утюг для этого и создан. Уже сам факт того, как они объявляют операторы+ - и др: Код говорит о том, что у автора в голове полное не понимание основ перегрузки операторов.. И авторитетность таких людей, которые ещё преподают c++, у меня под большим-большим сомнением. В этом и проблема) Название: Re: Реализация интерфейса Отправлено: Igors от Апрель 07, 2012, 14:29 говорит о том, что у автора в голове полное не понимание основ перегрузки операторов.. И авторитетность таких людей, которые ещё преподают c++, у меня под большим-большим сомнением. Как легко критиковать других :) Но такая критика только сваливает тему во флуд - и ничего большеВ этом и проблема) Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 07, 2012, 14:47 говорит о том, что у автора в голове полное не понимание основ перегрузки операторов.. И авторитетность таких людей, которые ещё преподают c++, у меня под большим-большим сомнением. Как легко критиковать других :) Но такая критика только сваливает тему во флуд - и ничего большеВ этом и проблема) Одно дело, когда такие архитектурные решения, в процессе обучения вояет сам обучающийся (что вполне нормально: все мы учимся на ошибках), а другое, когда такие решения навязывают, выдавая за правильные, преподы. Так вот потихоньку и разваливается наше классическое образование.. Вы меня понимаете? Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 07, 2012, 15:03 Так вот потихоньку и разваливается наше классическое образование.. Вы меня понимаете? Милости просим в министерство образования с инновационными идеями.Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 07, 2012, 15:04 Так вот потихоньку и разваливается наше классическое образование.. Вы меня понимаете? Милости просим в министерство образования с инновационными идеями.Название: Re: Реализация интерфейса Отправлено: Igors от Апрель 07, 2012, 15:06 Так вот потихоньку и разваливается наше классическое образование.. При всем желании никак не могу назвать свое образование классическим. Нет, ну формально я программирование изучал, но тогда рулили транзисторы и операционные усилители, а этот курс АЯиП никаким авторитетом не пользовался. Лектор был рыжий и один раз даже пришел на лекцию с яйцами (в смысле с лотком), всякому было ясно что программист - женщина и скоро уйдет в декрет.Так что по сравнению с тем что было - не так уж плохо, чего Вы напустились? И вообще - хватит порожняк гонять с учебным примером, для Вас есть напр такое http://www.prog.org.ru/index.php?topic=21481.msg148890#msg148890 (http://www.prog.org.ru/index.php?topic=21481.msg148890#msg148890) А то повыучивали тут паттерны всякие.. Название: Re: Реализация интерфейса Отправлено: Даниил от Апрель 07, 2012, 18:18 Вообще то, вы в этом должны быть больше заинтересованы, не находите? Дабы вы успокоились, скажу вам, что преподаватель выразил такую же идею - что именно перегружать операторы (+,-, /,*) не самая лучшая идея для данного решения. Но задумка была именно в dynamic_cast и кривизна решения тут мера необходимая. Просто для того, чтобы студенты думали головой и пытались найти лучшее решение в проигранной ситуации.А так да, он всерьез задумался о том, чтобы переписать методички. Название: Re: Реализация интерфейса Отправлено: m_ax от Апрель 07, 2012, 18:34 Вообще то, вы в этом должны быть больше заинтересованы, не находите? Дабы вы успокоились, скажу вам, что преподаватель выразил такую же идею - что именно перегружать операторы (+,-, /,*) не самая лучшая идея для данного решения. Но задумка была именно в dynamic_cast и кривизна решения тут мера необходимая. Просто для того, чтобы студенты думали головой и пытались найти лучшее решение в проигранной ситуации.А так да, он всерьез задумался о том, чтобы переписать методички. И этого эффекта можно добиться. И будет у вас возможность делать, например так: Код
Просто нужно вынести операторы + - * / из класса, а не пытаться делать их его членами. ЗЫ Ну вы меня успокоили) Преподу привет от Russia Qt Forum) ЗЫЗЫ Мы следим за качеством методичек 8) Название: Re: Реализация интерфейса Отправлено: Tonal от Апрель 09, 2012, 08:31 ... Ну "пользоваться только" - это несолидно.И пользоваться только AllNumber. :) Есть лучше/хуже соответствует задаче, например. :) А почему не так Потому что не контролируется переполнение :)Код
Код По сути отличается от моего кода только распределением памяти и контролем за ней. Ежели можешь рассчитать верхний предел одновременного количества временных объектов, и приделать гарантию, что они не пересекутся, то можно и так. :) Название: Re: Реализация интерфейса Отправлено: Igors от Апрель 09, 2012, 08:57 Потому что не контролируется переполнение :) То да, и возвращение константной ссылки не спасает. Причем не видно даже как отловить - ведь деструктор не будет вызван если вернули ссылку. Ну ладно, все имеет минусы |