|
|
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
dwl Сергей ИльичКем гарантируется ? Стандартом или конкретным компилятором ? гарантируется стандартом. вот вам пример из MSVC Код: plaintext 1. Да, я видимо основывался на устаревших сведениях. dwl Сергей ИльичНикто не сможет поместить в этот контейнер объект другого типа. Для этого понадобился бы С-Style cast или reinterpret_cast. А против лома не приема. В некоторых языках программирования, в которых нет generic programming, т.е. шаблонов и иже с ними, реализовывались классы контейнеров содержащие либо нетипизированные указатели, либо некий TObject от которого наследуются ВСЕ другие классы в языке, либо используют variant или что-то на него похожее. Итак, я беру в таком языке контейнер и хочу разместить в нем свой тип например TPoint. Ну и всякий раз чтобы к обращаться к членам этого класса в контейнере мне надо прибегать к преобразованиям типов. Уже постов 10 наверное я вам об этом говорю, но вы упорно игнорируете это и пытаетесь впарить мне что-то другое. TPoint - это тривиальный пример. Для нетривиальных объектов я всегда помещаю operator= и конструктор копирования в private секцию класса. Например, если в классе есть коллекция, чтобы не было позволено копировать все ее элементы в случае, если std::vector захотел еще раз перефасовать все элементы этого класса. А если в классе есть мандат на пользованием чем-то? Как его копировать? А если там какой-то хендл открытого ресурса? А если я пользуюсь статическими фабриками, чтобы кэшировать экземпляры объектов, и у меня все конструкторы находятся в закрытой секции класса? dwl В случае с шаблонами мне не придется прибегать к преобразованиям типов. Это усложнение порождает больше проблем, чем решает. В Java среда на основании динамического типа может во время исполнения дедуцировать, что объект реализует интерфейс List или Map, и вывести в дебагере его содержимое в удобоваримой форме. В C++ я такой возможности не имею. Для std::vector можно посмотреть, что там за внутренним указателем, в std::map или std::hash_map это будет проблематично. В Джаве я использую логирование только для отладки многопоточных программ. В С++ логирование - это по ходу единственное надежное средство. dwl Сергей ИльичНету никакого generic programming. Бредит бедняга. Лишь бы несогласится во всем. Это как люди которые не признают что есть ООП. Понимаешь ява-фан, мне пофиг какой термин зреет у тебя в голове при виде шаблонов Я не Ява-фан. Я сейчас сравниваю языки - Java и C++, как языки. Не платформы. И я утверждаю, что в С++ нету вещей, которые делали бы его более надежным и практичным, чем Java. И большей сложностью это не оправдывается. Он сложен как для человека, так и для компьютера. Есть нормальные фирмы, которые разрабатывают технологии. MS, Borland, Sun etc. Они - практики. Они знают, зачем было придумано ООП. А оно было придумано для быстрой разработки сложных программных систем. Чтобы можно было собирать проекты как бы из кирпичей. Чтобы кирпичи разных производителей хорошо срастались. И при этом можно было бы разделять api и реализацию. И чтобы каждый кирпич мог фигурировать в адресных пространствах разных процессов. Это ускоряет разработку. Это позволяет тестировать каждый компонент отдельно. Это позволяет минимизировать риски (в целом проект может оказаться провальным, но пара его компонентов - вполне юзаемыми). И вот эти фирмы независимо друг от друга пришли примерно к одной архитектуре. У MS - COM, у Borland - конпоненты, у Sun - Джава. Есть DCOM / CORBA - тоже мейнстрим. Есть ActiveX и EJB. Они все очень похожи. Разница у них - политическая. И есть люди типа Строуструпа, которые заняты тем, что выдумывают ненужные сложности. Можно писать на MS Visual C++. И использовать только WinAPI/COM, ATL_MIN_CRT и SEH. При этом получается маленький компонент, тем не менее очень надежный (из-за высокой гранулярности контроля) и шустрый. Если же зацепить какую-то хрень из std:: или boost::, начинает как снежный ком накапливаться огромное количество bullshit'a. Это потребует включения исключений. Это потребует включения жирной CRT. Подписываясь на каждое из этих обязательств, ты впоследствии вообще теряешь приемущества низкогоуровневого языка, не получая ничего взамен. Стандартные средства С++ намного более убоги, чем внутренние средства unix или win32. Ни гуя, ни networking, ни IPC. Локализация намного хуже, чем в win32. dwl Сергей ИльичПо умолчанию каждый объект к Яве равен только самому себе (дефолтовая реализация eqals в java.lang.Object сравнивает указатели на объекты). Можно его перегрузить, чтобы сравнивать тождество содержимого объектов. Но в объектах - хандлерах лучше этот метод не трогать. ставим галочку сравнить функторы в Яве нельзя. ясно. ваш ответ понятен. По какому критерию их сравнивать предлагаешь? dwl Сергей ИльичСтатический метод Collections.sort(...) может отсортировать любую последовательность содержащую объекты любых типов. И там не надо ничего переписывать. Не вижу никаких проблем с поздним связыванием (он делает downcasting к типу Comparable). В любом случае, пространства для нетривиального бага тут нет. В конце концов, operator< тоже можно неправильно перегрузить. Ну вы сделали революцию. А теперь попробуйте сделать еще один шаг дальше. С тем же подходом напишите контейнер для любых классов. Ну я имею ввиду, что элементы однотипны, но могут быть объектами разных классов. Чего ты все про контейнеры? Я сейчас пишу на С++ внутренний шедюлер для одного из своих проектов. Там есть CSheduler (синглтон), который содержит очередь с приоритетами из СEvent'ов. У каждого CEvent'a есть во-первых расписание (CSрedule), каждый элемент которого унаследован от CAbstractShedule. Очередь отсортирована по CAbstractShedule->getTriggerTimestamp(). CEvent дружественен к CAbstractShedule и может заставлять расписание переводить стрелки после кажого срабатывания. По отношению к другим классам у CAbstractShedule доступны только const-Методы. А во-вторых у кажого CEvent'a есть список IShedulerEventListener*. В CSheduler есть тред, который периодически просыпается, берет из хвоста несколько подходящих событий, и коммандует им trigger(). После этого он пихает их обратно в очередь, и они становятся на свое новое место. Да, тут я поюзал два своих шаблона - для очереди с приоритетами и для односваязного списка (не хочу CRT и исключения с собой таскать). И запихал я их в спецдиректорию для шаблонов. У меня все nmake'ом собирается, он рекурсивно вызывает самого себя для сборки составных частей проекта. Но тут пришлось проект немного подуродовать, сделать отдельную директорию. И ради чего? Все равно те же коллекции указателей. А если мне надо будет выставлять эти коллекции наружу, для доступа из других систем? А куда еще шаблоны в эту подсистему можно воткнуть, кроме коллекций? Никуда. dwl давайте возьмем у Александреску реализацию визитера и разберем его по полочкам, что там плохого, и что хорошего. Давай напишем такой визитер, который можно скомпилировать компилятором PRC, сериализовать, отправить через RPC на удаленное хранилище данных, дать ему там поработать, опять сериализовать и послать обратно с результатами. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.01.2005, 21:30 |
|
||
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
dwlОсновную суть я сказал. Повторю. Есть три класса Bitmap, VectorGraphics, textArea. Вы не можете менять их реализацию и структуру этих классов. Но вам позарез надо добавить еще одну функуиональность, например сохранение объектов этих классов в XML. Конкретно для этого случая (Скинуть дамп объекта в виде XML) можно использовать reflection API. В иных случаях для добавления функциональности можно использовать wpapper. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.01.2005, 21:57 |
|
||
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
Lepsik Сергей ИльичО, Лепрозорик! Привет, проказник! мы вроде бы не пили на брудершафт А чего с лепросником на брудершафт пить - потом всю жизнь придется на бацилл проверятся. Lepsik Сергей Ильич Ну, пусть будет так. Устами дилетантов глаголет истина. Вообще это твой стиль - сыпать какими-то терминами типа "мультиметод, функтор, абстрактная фабрика, политика etc" Это термины видимо дилетанты типа Алескандруску придумали, чтобы профессионалов мучать Нет, наверное, чтобы кто-то восхищался своей элитарностью. Lepsik Не ошибусь, если скажу что 90% софта на вашем компьютере написано на С++. --Мои рабочие тулзы - IDEA и Together - написаны на Java. а остальные 95% программ на вашем компьютере ? Там везде MS, COM и late binding, который суть корень всего зла. Lepsik только сначало надо сеть в песочницу с вами тыкать в каждый предмет и спрашивать как он называется на вашем языке. Бедняга... Это ты так со всеми разговариваешь? Lepsik --Когда я был на курсах по Джаве, мой руководитель мне дал задание - сделать два потока - один будет С++ я так понял тоже на уровне курсов остался ? дожились - программирование на курсах изучают. После вождения грузовиков надо полагать ? Могучий ЭпиLepsik никогда не ходил на курсы повышения квалификации - он и так крут. Lepsik Сергей Ильич Показал отделу кадров - вместе посмеялись. Они помнят, как по всему Питеру было не найти человека подходящего уровня. Искали год. А компания у нас большая. Специализация - IT. а вы как в IT сектор попали ? я так понял судя по курсам из другой отрасли ? А у вас контора когда-нибудь подготавливает план развития сотрудника, оплачивает курсы? Или вы там русиш рабы? Lepsik --Видимо могучий Лепсик пишет вообше без ошибок. конечно бывают, как же без них ? А может ты просто писать не умеешь? Lepsik честно говоря даже не знаю чего можно добавить к этим трем явно избыточным предложениям, чтобы понять как правильно исключениями пользоваться. В Java ты обязан либо ловить исключение, либо пихать его в сигнатуру метода. Есть там и Фаталы, которые наследуются от RuntimeException. Их можно не ловить. В C++ по ходу есть только фаталы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.01.2005, 22:24 |
|
||
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
---А чего с лепросником на брудершафт пить - потом всю жизнь придется на бацилл проверятся. культура так и брыжжет. работать сразу после ПТУ пошли работать ? Сергей Ильич Ну, пусть будет так. Устами дилетантов глаголет истина. Вообще это твой стиль - сыпать какими-то терминами типа "мультиметод, функтор, абстрактная фабрика, политика etc" --Это термины видимо дилетанты типа Алескандруску придумали, чтобы профессионалов мучать Нет, наверное, чтобы кто-то восхищался своей элитарностью. то-то некоего Сергея Ильича в песочницу тыкают еще другом форуме по поводу "великих" знаний в теории баз данных. Из этих людей бы гвозди делать. Сергей Ильич --Не ошибусь, если скажу что 90% софта на вашем компьютере написано на С++. --Мои рабочие тулзы - IDEA и Together - написаны на Java. а остальные 95% программ на вашем компьютере ? Там везде MS, COM и late binding, который суть корень всего зла. типичный прием демагога - уход в стороны от темы. Ему про Фому а он про Еерму. Я про языки спрашивал, а не способы реализации. Очень похоже на линуксоидов - ненавидят виндовс, но пользуются только им. Lepsik только сначало надо сеть в песочницу с вами тыкать в каждый предмет и спрашивать как он называется на вашем языке. --Бедняга... Это ты так со всеми разговариваешь? да тут на форуме все с вами мучаются, отчаянно пытаясь понять ту свалку фраз что выплескиваются из вашей головы в форум. --Могучий ЭпиLepsik никогда не ходил на курсы повышения квалификации - он и так крут. как это громко звучит "курсы повышения квалификации". Я их в состоянии прослушать и сдать не вставая с компьютера. --А у вас контора когда-нибудь подготавливает план развития сотрудника, оплачивает курсы? да уже тонну прослушал и сдал. ---Или вы там русиш рабы? Это что-то новое. Курсы для дилетантов стали признаком свободы. --А может ты просто писать не умеешь? Да уж за 20 лет научился поди. --В Java ты обязан либо ловить исключение, либо пихать его в сигнатуру метода. А вот в С++ я не обязан. Писать надо так, чтобы исключений не было. Впрочем это проблемы жабы, там везде трахаться надо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2005, 00:05 |
|
||
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
2 NotGonnaGetUs >Для самых остроумных поясню. Речь о том, что не обязательно компилировать приложение, что бы получить сообщения об ошибке. IDE 99% ошибок возникающих на этапе компиляции подсвечивают при наборе кода. Разве в c++ не тоже самое? Или с-шный код на бумаге всегда пишется правильно? :) В том то и дело, что и сишный и джавовский код, написанный на бумаге не гарантирован от ошибок в соответсвии типов и пр. Итак имеем: этап написания кода завершен в полном объеме, а ошибки в соответсвии типов есть. Где же обещанные гарантии? (NotGonnaGetUs> Проверка типов гарантируется на этапе написания кода.) Я понимаю, Вы хотели сказать, что в принципе возможна проверка некоторых правил до этапа компиляции, я с этим в принципе согласен (хотя есть проблема, теперь непонятно, что называть компиляцией). Просто нужно было это сказать как-то по-другому, а то фраза звучит комично. К тому же это не аргумент, подозреваю в паскале, например, такие проверки можно осуществить в гораздо большем объеме, так что, теперь все переключаемся на паскаль? >Речь не про IDE, а про ошибки на стадии компиляции. Тут я уже не понял, раньше вроде речь шла об стадии написания кода (Проверка типов гарантируется на этапе написания кода ). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2005, 02:21 |
|
||
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
Многоуважаемый си127! c127 NotGonnaGetUs Для самых остроумных поясню. Речь о том, что не обязательно компилировать приложение, что бы получить сообщения об ошибке. IDE 99% ошибок возникающих на этапе компиляции подсвечивают при наборе кода. В том то и дело, что и сишный и джавовский код, написанный на бумаге не гарантирован от ошибок в соответсвии типов и пр. Итак имеем: этап написания кода завершен в полном объеме, а ошибки в соответсвии типов есть. Где же обещанные гарантии? (NotGonnaGetUs> Проверка типов гарантируется на этапе написания кода.) Все пояснения были даны, зачем вы вернулись к искодному предложение - не понимаю, точнее не хочу, что бы мое понимание совпадало с реальностью... 99.99% программистов пишут код не на бумаге, а в IDE. Возможно отдельные оригиналы набирают мегабайты кода в ноутпаде. Вероятно вы решили, что являетесь оплотом этой могучей кучки... Всё проще! :) Я понимаю, Вы хотели сказать, что в принципе возможна проверка некоторых правил до этапа компиляции, я с этим в принципе согласен (хотя есть проблема, теперь непонятно, что называть компиляцией). Не некоторых - а практически всех. Это означает, что ни разу не возникло ситуации, когда IDE не отметила бы ошибку, а компилятор отметил. Я потому и спросил как дела обстоят в C++. Мне кажется, что там действительно только "некоторые" правила проверяются из-за их сложности :) Опровергните если это не так... К тому же это не аргумент, подозреваю в паскале, например, такие проверки можно осуществить в гораздо большем объеме, так что, теперь все переключаемся на паскаль? Задачи переключаться куда-либо не ставилось :) Если вы ещё не припоминаете контекст из которого вытащили данное предложение, напомню. Речь шла о generic в java и generic c++ - какие возможности у первого и второго: в чём разница, кроме проверки типов до/на этапе компиляции... >Речь не про IDE, а про ошибки на стадии компиляции. Тут я уже не понял, раньше вроде речь шла об стадии написания кода (Проверка типов гарантируется на этапе написания кода ). [/quot] Печально, что не поняли. Речь всё время шла об ошибках выявляемых на стадии компиляции, что в случае java равносильно ошибкам выявляемым при написании/отладке кода в IDE. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2005, 13:19 |
|
||
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
Сергей ИльичА если в классе есть мандат на пользованием чем-то? Как его копировать? А если там какой-то хендл открытого ресурса? А если я пользуюсь статическими фабриками, чтобы кэшировать экземпляры объектов, и у меня все конструкторы находятся в закрытой секции класса? Это вы приводите примеры классов которые нельзя хранить в динамическом массиве? Ну замечательно. Кстати, если у вас есть "мандатные" объекты, и только чтобы вовремя их разрушать все разрешается счетчиком ссылок - пример boost::shared_ptr. или boost::ref. Другой счетчик ссылок я приводил в этом флейме выше. Я их часто использую в своих проектах они хорошо помогают хранить например указатели в контейнерах. Также есть такой замечательный прием, который лично я переписал для себя при помощи boost::function. ScopeLock, это локальный класс который инициализаируется вызовом определенной функии для деструктора. Т.е. если происходит какое-то исключение в заданной области видимости при раскрутке стека вызывается деструктор этого класса а соответсвенно и функция которая может делать нужные вещи, такие как закрытие файла, закрытие окна и т.д. Что же касается фабрик, то сама по себе фраза "массив фабрик", мне кажется, скажем культурно, не востребованной на практике. Если следовать вашей логике, то если СинглТон (хе-хе) нельзя разместить в контейнере, то начерта эти контейнеры нужны. Интересная логика... Сергей Ильичв std::map или std::hash_map это будет проблематично.map ассоциативный контейнер, который по сути является красно-черным деревом. Не представляю как можно двусвязный список отбразить сразу весь в окне Watch. Только по-элементно. Дык это все? Вы сказали "проблемы", это множественное число. Пока ваш один минус (просмотр в отладчике связанных списков) не перевешивает тех плюсов, которые я называл. Сергей ИльичОн сложен как для человека, так и для компьютера. Ну ладно вы говорите за других людей, но еще и за компьютер!!! Давайте не будем спорить про сложность - это понятие относительное. Мне язык С++ не кажется сложным. тут я опять повторюсь, сложность или простота, это всего лишь привычка или опыт( положительный или отрицательный ) в использовании того или иного инструмента. Сергей ИльичА куда еще шаблоны в эту подсистему можно воткнуть, кроме коллекций? Никуда. посмотри внимательно те примеры которые я привел выше. увидишь где можно еще использовать шаблоны. Сергей ИльичДавай напишем такой визитер, который можно скомпилировать компилятором PRC, сериализовать, отправить через RPC на удаленное хранилище данных, дать ему там поработать, опять сериализовать и послать обратно с результатами. пожалуйста, визитера я использую, тот что у меня есть, а сериализацию из boost. Только вы на мой вопрос то не ответили, относительно ПРОСТОЙ реализации Визитера на Яве. И ваще отвечать вопросом на вопрос... Сергей ИльичКонкретно для этого случая (Скинуть дамп объекта в виде XML)можно использовать reflection API. В иных случаях для добавления функциональности можно использовать wpapper. вы очень и очень хорошо умеете не отвечать на вопрос. вас грамотно этому научили. Вы прекрасно имеет ввиду, что сохранение в XML я использовал как практический отвлеченный пример. Повторю еще ОООООООЧЕНЬ простую задачку: (удивительно как много воды вы успели налить на нее) 1) Есть четыре класса: Graphics (базовый), (наследники)Bitmap, VectorGraphics, textArea 2) Есть определеная функциональность (КОД), которую нужно добавить каждому. 3) реализация этой иерархии классов закрыта Я даже дал определенный вариант реализации этой "задачки" и до сих пор жду ваших вариантов, чтобы потом показать как можно сделать при помощи шаблонов. Но вы упорн этого избегаете. Жаль. Значит я по умолчанию признаю, что тут вы признали свое поражение. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2005, 13:20 |
|
||
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
Сергей ИльичЕсли же зацепить какую-то хрень из std:: или boost::, начинает как снежный ком накапливаться огромное количество bullshit'a. Это потребует включения исключений. Т.е. исключение по вашему это зло? Насчет прочих обощений я пропущу мимо ушей потому что это просто ничего не значащие слова не подкрепленные практическими примерами. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2005, 13:22 |
|
||
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
www.fun4me.narod.ruFar лучше любого IDE. подписался :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2005, 14:15 |
|
||
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
dwlАга и чтобы обезопасить каждый хранимый тип вам надо писать "оболочку" вокруг вектора. а попасть туда могут еще и наследники MyObj. А если вы закроете эту реализацию коллекции, тогда какой-нить другой программист поленится писать свою коллекцию и будет преобразовывать в MyObj какой-то другой класс. Или я не прав? Тогда попадать туда может черте что. Или я опять флеймю по вашему? Тут хочется сказать об двух вещах. Первое - далеко не факт, что нужно запрещать добавление наследников MyObj в MyCollection. Один из принципов наследования - соблюдение котрактов родителя детьми. Мне редко встречались ситуации, когда этот принцип был не уместен. Второе - если нужда в этом всё-таки возникает, в java есть простенький generic, который позволяет эту проверку вынести из runtime (как и в c++). Безусловно это удобно и спора по этому поводу нет. Про флейм: мой вопрос был об отличиях generic С++ и java. Возвращение к обсуждению общих черт значит флеймить :) (Конечно, по-моему.) примеры Пожалуйста. Теже яйца - вид сбоку, только любому понятно, что этот код делает :) Что бы добавить специфическое поведение для нового класса, достаточно реализовать свой StrategyImpl или оставить дефолтным. Никакой код при этом не будет затронут. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. Т.е. Сontainer<String, StringImpl> и Container<Integer, IntegerImpl> - это один и тот же класс Container - байт в байт. Ваш или мой код проще в дальнейшем модифицировать и использовать? :) простите, я думал вы знаете что такое паттерн проектирования Визитер. Задача показалась вам общей. Вы смотрите совсем не на те условия. Я не злобный препод который стремится поставить в любом случае вам плохую оценку. :) Задача показалось мне не чётко с фомулированной. Шаблон визитор предполагает, что существует абстрактный класс визитор, что в классе Graphics реализован метода accept(Visitor v); Что существует тот, кто этот метод будет вызывать и т.д. Вот я и стал уточнять, что вы хотите, реализовать всю это для трёх классов не понятно как существующих, или просто добавить новый подкласс vistor... Мне ваш ход мыслей не знаком, отсюда и уточняющие вопросы. Забыл самое главное - базовый класс этой закрытой иерархии Graphics. Таких условий достаточно? реализацию самой функции мне не надо главное суть. что-то вроде этого Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. Если абстрактный визитор был таким: [src java] abstract class Visitor { abstract void visit(Graphics g); }[/src java], то придётся повторить ваш код, коль скоро изменить код Visitor'a мы не можем. Без проверки типа g в рантайм не обойтись. Особенно если инстансы визитора создаются в рантайм, после считывания конфигурационного файла. Будет интересно почитать, как вы хотели это сделать при помощи шаблонов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2005, 20:47 |
|
||
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
alex_k www.fun4me.narod.ruFar лучше любого IDE. подписался :-) Удачи обоим :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2005, 21:03 |
|
||
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
NotGonnaGetUs Если абстрактный визитор был таким: Код: plaintext 1. 2. Особенно если инстансы визитора создаются в рантайм, после считывания конфигурационного файла. "повторить ваш код", т.е. тем или иным образом вызывать нужный метод в зависимости от реального класса объекта g передаваемого в метод visit (который можно определить только в runtime). А как делать проверку в рантайм и переходить к нужному методу - это уже не принципиальный вопрос, или вы именно его задаёте? Я сужу только со стороны java. Надеюсь на этой почве не доразумений не возникнет :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2005, 21:21 |
|
||
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
2 NotGonnaGetUs >99.99% программистов пишут код не на бумаге, а в IDE Тут уже 2 человека заявили, что пишут программы в фаре. Я тоже пишу в фаре, плюс чингиз, итого 4 человека как минимум. Если исходить из Вашей оценки, что 4 посетителя форума это 0.01%, то на форуме должно тусоваться 40000 человек. Многовато получается. Тут необходимо предположить либо что форум аномально популярен среди любителей фара, либо что у Вас неадекватное восприятие действительности. Второе мне почему-то представляется более вероятным. >Возможно отдельные оригиналы набирают мегабайты кода в ноутпаде. Вероятно вы решили, что являетесь оплотом этой могучей кучки... Всё проще! :) И сколько же мегабайтов кода Вы набрали за свою жизнь? Или Вы cut-paste интенсивно используете вместо вызова подпрограмм? И такая техника тоже есть. >Не некоторых - а практически всех. Это означает, что ни разу не возникло ситуации, когда IDE не отметила бы ошибку, а компилятор отметил. Необъявленные переменные и вызовы несуществующих функций (методов) тоже находит? Просто интересно, давно IDE не использовал для языков общего назначения. >Речь шла о generic в java и generic c++ - какие возможности у первого и второго: в чём разница, кроме проверки типов до/на этапе компиляции... Не бывает этапа ДО компиляции. Компиляция первый этап обработки программы компьютером. То, что делает IDE, проверяя типы и выдавая Вам ошибки это и есть использование куска компилятора, встроенного в IDE. В С++ и других языках такое тоже можно сделать, в каких-то IDE наверняка сделано, только ИМХО это бесполезное свойство. Как я уже говорил, в Паскале в этом смысле можно наворотить гораздо больше чем в джаве, потому что паскаль проще и строже, но это ничего не доказывает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2005, 06:32 |
|
||
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
NotGonnaGetUsпро флейм: мой вопрос был об отличиях generic С++ и java. Ващет изначально вопрос был про то (грубо говоря), а нужны ли ваще шаблоны. Было высказано мнение что они нафиг не нужны. О сравнении generic Java и шаблонов С++ я давал ссылку выше - посмотрите внимательно. Может почерпнете что ли бо инетересное. Что же касается обсждения вообще, то я старался придерживаться рамок аргументации использования generic programming, сторонники же Явы и Ильич в частности, чаще сводили разговор в сравнении языков (что считаю не уместным), теперь вот вы хотите сравнить шаблоны С++ и generic в Яве. Т.е. косвенно признаете ТУ МЫСЛЬ что я отстаивал - generic programming существует и во некоторых ситуациях эффективнее, чем ООП. NotGonnaGetUsВ java generic является своего рода "инструкциями" для компилятора и отслужив своё они убираются из кода. Шаблоны С++ это тоже средство управление компиляцией, в часности созданием типов и функций на этапе компиляции. NotGonnaGetUsВаш или мой код проще в дальнейшем модифицировать и использовать? :) не понимаю о чем речь. Что сравнивать то? NotGonnaGetUsБез проверки типа g в рантайм не обойтись. Да полностью от нее не избавиться( хотя существуют и такие решения ). Но есть еще одно. Впервые предложенное Александреску. Чтобы немного разобраться в сути этого решения, я позволю себе упомянуть, что благодаря комбинаторному подходу при сборке шаблонов, возможно создание такой штуки как список типов. Впервые идея создания списка типов пришла к нему при написании реализации фабрики. Обычное самое простое решение без регистрации типов: Код: plaintext 1. 2. 3. 4. 5. 6. Т.е. в данном кнкретном случае мы не смогли обощить тип Фабрика, и при реализации того или иного ПО, нам приходится писать различные фабрики. Спорить внутри проекта о соглашениях в интерфейсе, в написании имен методо и классов и прочее. Напрашивалось такое ОБОЩЕННОЕ решение Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. Но вирутальные функции не могут быть шаблонными, потому что нельзя под одним типом(функцией) сочетать динамическое и статическое связывание. Однако списки типов придуманные Александреску сумели обойти эти ограничения (там еще были ограничения в указании аргументов шаблона ). Код: plaintext 1. 2. 3. 4. 5. 6. Чтобы избежать таких записей Код: plaintext 1. 2. Код: plaintext 1. 2. Теперь перейдем непосредственно к Визитеру, как я и говорил, полностью избавиться от рантайм проверки не получится (для этого есть решение StaticDispether, но оно гораздно больше и сложнее визитера, см boost::mpl ). Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. Роберт Мартин в 1996 году впервые предложил реализацию Acyclic Visitor, правда он не подходит для поставленной здесь задачи, потому что предусматривает метод Accept для каждого из членов иерархии визитируемых классов. Этому методу Accept передается некий базовый Визитер имеющий в свое распоряжении виртуальный деструктор и виртуальный метод Visit. Именно такой подход используется чаще всего. Но и он кстати получил свой статический аналог в обощенном шаблоне визитера. Теперь о "подсказке" про избалении от dynamyc_cast Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. Код: plaintext 1. Лично МНЕ это решение кажется более гибким, чем решение содержащие кучу if else . Более подробно решение Цикилического Везетера разбирается в книге Александреску, которую вы так обильно ругаете. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2005, 13:52 |
|
||
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
с127Я тоже пишу в фаре, плюс чингиз, итого 4 человека как минимум. Вам тоже удачи :) И сколько же мегабайтов кода Вы набрали за свою жизнь? Или Вы cut-paste интенсивно используете вместо вызова подпрограмм? И такая техника тоже есть. ^_^ Необъявленные переменные и вызовы несуществующих функций (методов) тоже находит? Просто интересно, давно IDE не использовал для языков общего назначения. Конечно. Абсолютно всё. В том числе автокомплит, переход на реализацию методов и т.п. очевидные вещи. Не бывает этапа ДО компиляции. Компиляция первый этап обработки программы компьютером. То, что делает IDE, проверяя типы и выдавая Вам ошибки это и есть использование куска компилятора, встроенного в IDE. У вас не бывает. А у нас бывает :) Отличается от компиляции тем - что ничего некопилируется, а проверятся синтаксис и существование классов/методов и т.д., происходит в online режиме. В С++ и других языках такое тоже можно сделать, в каких-то IDE наверняка сделано, только ИМХО это бесполезное свойство. Как я уже говорил, в Паскале в этом смысле можно наворотить гораздо больше чем в джаве, потому что паскаль проще и строже, но это ничего не доказывает. А это и не должно ничего доказывать. Если что-то можно сделать, но этого не сделали - значит этого ещё нет. Тем не мнее, очень рад за паскаль, только никак не могу понять причём он тут. Но если вам интересно поговорить, то пожалйста. Можно завести отдельный топик на эту тему. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2005, 14:07 |
|
||
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
списки типов вообще удивительная вещь. Хотя на мой взгляд проще их использование показать не на Визитерах, а на фабриках объектов. Точнее асбтрактных фабриках. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. Вопрос - что в ней такого плохого в этой реализации. (Я вырезал из ней классы стретегий отвечающие за обработку ошибок, за размещение в памяти и т.д.). Но что тут плохого, что вызвалорвотную реакцию у поклонник Явы? можно по пунктам? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2005, 14:25 |
|
||
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
Ну а для сравнения возможностей generic Явы и шаблонов С++, я уже предлагал задачку - создание УНИВЕРСАЛЬНОГО типа Функтор. Поясняю (цитируя Г.Саттера, недословно): Функции или что-то ведущее себя как функции есть почти в любом языке программирования. В С++ это функции-члены, статические функции-члены, обычные функции (находящиеся в пространстве имен), и функторы (классы у которых перекрыт вызов оператора () ). Когда дело доходит до простого обращения к ним все просто Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. Однако, когда нам неизветсно либо ЧТО либо КОГДА вызывать, в дело вступают указатели, простейшим примером их использования является реализация callback функций (которых для Ильича почему-то не существует, как и generic programming): Код: plaintext 1. 2. 3. 4. 5. 6. 7. Все вроде чудненько, однако f может указывать только на ОБЫЧНУЮ (не член класса) функцию. В случае с Ява это будет ТОЛЬКО статик функция. Второе ограничение - это сигнатура функции. Для того, чтобы подружить указатель с членами-функциями надо сделать нечто вроде этого Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. Есть еще одно решение при помощи STL Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. Итак, вот вам ЗАДАЧА - определить тип, который может содержать в себе ссылку(указатель) на ЛЮБОЙ функциональный объект или функцию, или функцию-член, или статическую функцию. Этот тип не должен иметь перечисленных выше недостатков и уметь хранить в себе любые сигнатуры функций или функторов. Я уже предлагал такую задачку на первых страничках этого флейма. Но Ильич очень умело ушел от первичной постановки задачи на конкретику удобную ему. Поэтому я просто повторяю свой вопрос - насколько возможно создание такого типа в Яве. В С++ такая задача была решена в типа boost::function , а в 2002 году она была включена в новый черновой стандарт С++. те кто имеет возможность его закачать см tr1::function . До декабря прошлого года, для этого типа не была решена проблема сравнения (operator ==), потому что отношение порядка (operator <) для таких типов нереализуемо. И в результате такие типы стало возможно соединять в неповторяющиеся списки, см. boost::signal и boost::ref . Поэтому вопрос о создание типа multi_function уже не стоит. Добавим к той части задания которую я уже сформулировал требование реализации операции сравнения между двумя экземплярами типа. А пока простой пример использование function (только не надо создавать Ява типа для этого примера) Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. Помимо callback функций у такого типа есть ряд других областей использования, например Паттерн Проектирования Observer реализацию которого я могу привети. Функции возвращающие указатели на функции, в том числе функции возвращающие указатель на самих себя или себе подобных (с той же сигнатурой или тем же типом) Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. привести шаблон Observer для демонстрации ? ЗЫЖ жду ответа - реализацию function в Яве. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2005, 14:59 |
|
||
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
dwlВащет изначально вопрос был про то (грубо говоря), а нужны ли ваще шаблоны. Было высказано мнение что они нафиг не нужны. Я в ваш диалог с С.И. влез с другим вопросом. Если вы мне отвечаете на его вопросы, то для меня это флейм :) Я согласен, что "идеи" заложенные в generic полезны на практике и могут не плохо дополнять ООП. Другое дело, что "идеи" в java generic и c++ templates - не сколько различаются. Мне было интересно, есть ли в с++ "идеи", которых нет в java и которые стоило бы туда перенести. Многое, что вы приводили в качестве доводов в пользу generic programming, можно сделать в java без его применения. Отсюда ответы C.И., где он говорит, что generic не даёт ничего нового и не является самостоятельной технологией программирования. Доля истины в его словах есть :) ... сторонники же Явы и Ильич в частности, чаще сводили разговор в сравнении языков (что считаю не уместным), теперь вот вы хотите сравнить шаблоны С++ и generic в Яве. Простите меня за это :) Т.е. косвенно признаете ТУ МЫСЛЬ что я отстаивал - generic programming существует и во некоторых ситуациях эффективнее, чем ООП. Я признаю мысль, что генерик расширяет и делает более эффективной технологию ООП, а не заменяет её более эффективным образом. Шаблоны С++ это тоже средство управление компиляцией, в часности созданием типов и функций на этапе компиляции. В итоге это приводит к тому о чём говорил С.И.: требуется пересборка класса А объявленного с использованием темплейтов, если добавляется новый тип в коде, т.к. для этого нужно сконструировать новый метод класса, а для этого нужно запустить компилятор... Сложности никакой если код доступен. А если нет, то ... Или я не правильно понял слова C.И. ? ... решение Цикилического Везетера разбирается в книге Александреску, которую вы так обильно ругаете. [/quot] Я алекандреску не ругаю :) NotGonnaGetUsБез проверки типа g в рантайм не обойтись. Да полностью от нее не избавиться( хотя существуют и такие решения ). Но есть еще одно. Впервые предложенное Александреску. Поэтому я и спрашивал, чего же вы хотите на самом деле :) Вместо добавить функциональность к уже существующему визитёру, вы хотели увидеть реализацию визитёра, в которой это добавление будет "простым". Вот вариант, где не используется generic и не требуется перечисления всех subclass'oв Graphics. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. Вот если често, что вы глядит проще в данном случае, ваши темплейты или код java? :) Или может быть в итоге получилась разная функциональность? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2005, 17:19 |
|
||
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
dwlИтак, вот вам ЗАДАЧА - определить тип, который может содержать в себе ссылку(указатель) на ЛЮБОЙ функциональный объект или функцию, или функцию-член, или статическую функцию. Этот тип не должен иметь перечисленных выше недостатков и уметь хранить в себе любые сигнатуры функций или функторов. Я уже предлагал такую задачку на первых страничках этого флейма. ЗЫЖ жду ответа - реализацию function в Яве. Для java это не задача :) Рефлекшин (стандартная библиотека) позволяет выдрать любой метод класса, как объект java.lang.reflect.Method. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2005, 17:26 |
|
||
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
NotGonnaGetUs Мне было интересно, есть ли в с++ "идеи", которых нет в java и которые стоило бы туда перенести. не мне решать, что стоить переносить, а что не стоит. Думаю на нашем уровне (говорю за себя) это не решить да и не жаждю я этого. насчет разницы между шаблонами и дженериками я уже отвечал. NotGonnaGetUsВ итоге это приводит к тому о чём говорил С.И.: требуется пересборка класса А объявленного с использованием темплейтов, 1) я уже отвечал, что идеальных решений не бывает. что у каждого решения есть плюсы и минусы - надо выбирать оптимальное. ну да в случае с шаблонами - нужна открытость кода 2) пересобираться будет только инстанцируемый метод. Если метод или часть кода шаблонов не используется - он не компилируется. 3) существует идеома pimpl, которая позволяет сильно снизить кол-во модулей необходимых для перекомпиляции. Например, библиотеки boost и loki постронны по тому же принципу. Поэтому время компиляции это сильно не увиличивает. Особенно повторной. к слову pimpl - это pointer to implementation, если я не ошибаюсь. NotGonnaGetUsЯ алекандреску не ругаю :) С.И. ругал причем на пропалую, не приводя никаких примеров. NotGonnaGetUsВот вариант, где не используется generic и не требуется перечисления всех subclass'oв Graphics. несколько не верное решение. 1) Вся иерархия типов закрыта. мы ее не можем изменить. Поэтому одбавление метода accept не удовлетворяет условию задачи. 2) применение некоего абстрактного типа Method как раз ослабляет контроль типов(раз). Это как применение нетипизированных указателей для создания универсального контейнера. Во-вторых, это решение требует RTTI. В-третьих: целиком и полностью позднее связывание, компилятор почти ничего не проверяет. А если visit будет не с той сигнатурой? вобченм не подходит ваше решение. Это как раз тот случай что я описал. что обычно ООП программисты определяют accpet у визитуемых объектов и передают туда базовый класс визитера. Повторюсь, что иерархия закрыта и менять интерфейс ты не можешь. относительно сложности: ничего не виже сложного в объявлении Код: plaintext Далее определение конркетного списка типов позволяет определить множество только тех объектов из иерархии, которые подлежат визитированию. Например, если появится тип TLine , то мы можем не определять для него визитера а просто игнорировать. в вашем случае придется делать пустышку, потому как вы написали в базовом классе метод accept, то есть он будет(ну или должен быть) у всех потомков. ПРедставим что там иерархия из 25 классов, а нам нужно провизитировать только ТРИ. Вобчем повторю главное - иерархия закрыта. Ну если она открыта, то конечно я ничего не имею против циклического визитера что вы написали. за исключением тех оговорок о более слабой защите типов (сигнатуры метода) и т.д., которые я привел выше. NotGonnaGetUsДля java это не задача :) Рефлекшин (стандартная библиотека) позволяет выдрать любой метод класса, как объект java.lang.reflect.Method Это не решение. 1) переменной типа Method можно присвоить функции разных сигнатур. Тип function не даст этого сделать. 2) переменная Method - это rtti (ничего не имею против), т.е. динамическое связывание. в случае с function мы имеем статическую проверку типов. 3) я не знаю как вы будете сравнивать две переменные Method, потому что существует возможность что одна из них показывает на функцию совсем с другой сигнатурой. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2005, 18:05 |
|
||
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
dwl 1) Вся иерархия типов закрыта. мы ее не можем изменить. Поэтому одбавление метода accept не удовлетворяет условию задачи. ... Это как раз тот случай что я описал. что обычно ООП программисты определяют accpet у визитуемых объектов и передают туда базовый класс визитера. Повторюсь, что иерархия закрыта и менять интерфейс ты не можешь. ... Ну если она открыта, то конечно я ничего не имею против циклического визитера что вы написали. за исключением тех оговорок о более слабой защите типов (сигнатуры метода) и т.д., которые я привел выше. У нас какие-то разные понятия о шаблоне визитёр. Разницы объявлен метод accept(), как член Graphics или нет - нет. Просто вызов g.accept(v) меняется на v.visit(g). Ни какие интерфейсы я не меняю. Просто предлагаю дургой варинт базового класса визитёра и способ его использования. Тоже самое проделали вы в посте выше. ПРедставим что там иерархия из 25 классов, а нам нужно провизитировать только ТРИ. Вобчем повторю главное - иерархия закрыта. Три метода и объявим в визитёре. Какие проблемы? Пустышка есть в базовом класе визитёра. Если мешает, можно и её убрать :) 2) применение некоего абстрактного типа Method как раз ослабляет контроль типов(раз). А если visit будет не с той сигнатурой? Вы про случай, если в каком-то из SubVisitor будет объявлен метод visit(String s) ? Просто будет бесхозный метод. В вашу реализацию абстрактоного визитёра такой метод нельзя будет вставить? При помощи generic в java нельзя задать шаблон для класса, так, как это можно делать в C++. Generic java - это параметризация параметров методов, но не самих методов. Для нужно использовать aннотации и apt. Это технология, наверное, сложнее, чем С++ templates, но зато позволяет использовать собвственные процессоры для валидации или создания классов на уровне приложения, а не языка. В данном случае от "душка" рефлекшина можно избавиться путём использования generic + interfaces. Та же идея применима для фабрик о которых вы писали. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. С вашей помощью, я получил ответ на интересовавший меня вопрос. Спасибо :) Думаю можно смело прекрщать наш "флейм" на тему generic vs generic ^_^ NotGonnaGetUsДля java это не задача :) Рефлекшин (стандартная библиотека) позволяет выдрать любой метод класса, как объект java.lang.reflect.Method Это не решение. 1) переменной типа Method можно присвоить функции разных сигнатур. Тип function не даст этого сделать. 2) переменная Method - это rtti (ничего не имею против), т.е. динамическое связывание. в случае с function мы имеем статическую проверку типов. 3) я не знаю как вы будете сравнивать две переменные Method, потому что существует возможность что одна из них показывает на функцию совсем с другой сигнатурой. 1)На то это и "любой метод". 2)Правильно, в рантайм всё. Искать статическую function в java бесмысленно, поскольку "сслыки на методы" были убраны из неё намерянно. Что бы не вводить в грех и не множить сущности без которых свободно можно обходиться :) Использовать метод отдельно от класса, которому он принадлежит, bad oop practics. 3)Сравнивать методы будем вызвая methodA.equals(methodB), отлично работает :) Вы мыслите категориями C++ и ведёте дискусию о "полезности" generic programming в их свете. Я не стремлюсь искать пользу/вред от использования generic в С++. Меня интересовали общие (не уникальные для С++) принципы того, что вы назвали generic programming, за этим я влез в ваш восхитительный диалог с C.И., а теперь опять превращаюсь в читателя :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.01.2005, 22:56 |
|
||
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
Сергей ИльичПрограмму на OCaml кстати, можно статически скомпилировать в машинный код, и язык этот строго типизирован. Там, кстати, нет уборки мусора, но управление памятью там сделано более по уму. У OCaml'а ЕСТЬ сборка мусора. Безо всяких "более по уму". Сергей ИльичБиблиотека fftw (Fatest Furier Transform in the West) была написана вовсе даже не на c/С++, а на ML, функциональном языке. Библиотека fftw (FaStest FOurier Transform in the West) была написана не НА ML, а С ПОМОЩЬЮ ML (точнее, OCaml), который использовался для генерации специализированного исходного кода. Теперь по теме. Мне кажется, "ранний" C++ (до появления современной трактовки шаблонов как инструментов метапрограммирования) произвел непоправимое повреждение в умах. Если ad hoc полиморфизм (overloading) был вполне себе насущен и уместен, то реализация как бы true полиморфизма (на самом деле - убогой пародии на него) с помощью механизма наследования и виртуальных функций - породила целое поколение людей, которые, в определенном смысле, уже безнадежны. Я это, отчасти, знаю по себе. Все эти ужимки и прыжки с "делегатами" и бог знает чем еще - борьба с ветряными мельницами. Выкиньте в помойку "объекты" с "наследованием" и проблемы исчезнут как утренний туман (ВАЖНОЕ ЗАМЕЧАНИЕ - в современном C++ все это используется, но для совершенно других целей - а именно, как инструмент реализации функционального языка шаблонов, интерпретируемого во время компиляции; здесь не должно быть путаницы - слова остались те же, но смысл изменился). Венцом этого ООП-безобразия стала Java. Я жабц не знаю, никогда на ней ничего не писал, чтение исходников на нем вызывает у меня почти непреодолимое отвращение. Вместе с тем, с моей дилетантской точки зрения, жаба сильна двумя вещами: автоматическое управление памятью, reflections. Ну и VM, разумеется. Все это давно не новость в академической среде, но впервые это было (насильно) внедрено на промышленном уровне. И это серьезный шаг вперед. Но САМ ЯЗЫК - худший из компонентов жабы как платформы. Мне C++ в современном понимании нравится намного больше и я его активно использую. Однако, поскольку его мощь вскрылась случайно - шаблоны делались для других целей - синтаксис оказался неадекватным. Приходится мириться. Если же кто-нибудь из присутствующих хочет получить эстетическое наслаждение - попробуйте Haskell - язык удивительной мощи и красоты. Сколько времени потребуется, чтобы поправить искалеченные ООП мозги я не знаю - мне понадобилось много. До недавнего времени с практической точки зрения это было бессмысленно, сейчас компилятор GHC с библиотеками дорос, с моей точки зрения, до уровня, когда его можно назвать промышленным средством разработки. Конечно, для реальной работы необходимо владеть еще, как минимум, С (на худой конец под виндами какой-нибудь Delphi сойдет). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.01.2005, 10:55 |
|
||
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
dwl Сергей ИльичА если в классе есть мандат на пользованием чем-то? Как его копировать? А если там какой-то хендл открытого ресурса? А если я пользуюсь статическими фабриками, чтобы кэшировать экземпляры объектов, и у меня все конструкторы находятся в закрытой секции класса? Это вы приводите примеры классов которые нельзя хранить в динамическом массиве? Ну замечательно. Во - первых хранить это дело в дин.массиве можно, если хранить указатели. При этом приемущества шаблонов перед Object* становятся умозрительными. Во-вторых не юзаю буст. Если без библиотеки можно обойтись - значит нужно аргументировать, зачем ее цеплять к проекту. Если нельзя обойтись, значит чего это за язык, на котором ничего не работает без установки доп. костылей? STLport я еще терплю, так как он гарантирует тредовую безопасность, и при этом более зрел как библиотека, в отличие от того что входит в стандартную поставку. И вообще, нафиг мне чего-то создавать в стеке? Зачем это? Сначала создавать это в стеке, потом юзать конструктор копирования для того чтобы перегнать это в кучу? Может, сразу создать в куче и хранить указатель? А чтобы не получить memory leak, компилировать без исключений и юзать чего - либо более умное типа SEH? Кстати, ты мне так и не ответил, как ты относишься к тому чтобы при каждой перефасовке содержимого std::vector производить копирование всех внутренних коллекций? Присобачивать к каждой коллекции подсчет ссылок? Буста у меня нет, а в std:: нету никакого shared_ptr . Сам я это дело писать не хочу. Скотт Мейерс опубликовал небольшой прототип смарт-указателя в своей книжке, и потом очень долго писал к нему errata на своем сайте. dwl Что же касается фабрик, то сама по себе фраза "массив фабрик", мне кажется, скажем культурно, не востребованной на практике. И это еще меня обвиняет в передергивании. Массив указателей на объекты, порожденные статическими методами генерации. Вполне может быть чего-то такое. Применительно к Джаве многие авторы, например Джошуа Блох, рекоммендуют использовать вместо конструкторов статические методы генерации. Как эту техника себя ведет в С++, мне не довелось попробовать. Вреде бы, это один из (может, единственный) способов запретить наследование класса в С++. dwl Сергей Ильичв std::map или std::hash_map это будет проблематично. map ассоциативный контейнер, который по сути является красно-черным деревом. Не представляю как можно двусвязный список отбразить сразу весь в окне Watch. Только по-элементно. Дык это все? Вы сказали "проблемы", это множественное число. Пока ваш один минус (просмотр в отладчике связанных списков) не перевешивает тех плюсов, которые я называл. Это очень объемный плюс, и возможность наблюдения всей коллекции в отладчике - это одна из граней этого плюса. Какой-то объект в рантайме определяется как связанный список. Причем, если ты написал свою коллекцию и в ней реализовал List или Map, то отладчик все равно отобразит все его содержимое. Это возможность анализа работающего кода. Любого анализа. Каждый функциональный кирпич в джава так и остается этим же самым функциональным кирпичем. dwl Сергей ИльичОн сложен как для человека, так и для компьютера. Ну ладно вы говорите за других людей, но еще и за компьютер!!! Давайте не будем спорить про сложность - это понятие относительное. Мне язык С++ не кажется сложным. За компьютер очень просто сказать - надо сравнить время компиляции идентичных по функциональности программ на разных языках. Если компилировать в нативный код, то C++ можно сравнивать, скажем, с Дельфи. dwl тут я опять повторюсь, сложность или простота, это всего лишь привычка или опыт( положительный или отрицательный ) в использовании того или иного инструмента. Чем больше пишешь на С++, тем более сложным он кажется. Писание кипятком по поводу гениальности STL и изящества указателей на функции - признаки восторженного неофита. Вряд ли я ошибаюсь. dwl Сергей ИльичА куда еще шаблоны в эту подсистему можно воткнуть, кроме коллекций? Никуда. посмотри внимательно те примеры которые я привел выше. увидишь где можно еще использовать шаблоны. Не вижу. Полиморфизм там работает изумительно. Я отладил этот модуль изолированно от всей программы, и я не вынужден его больше пересобирать, покуда я не внесу в него изменений. dwl Сергей ИльичДавай напишем такой визитер, который можно скомпилировать компилятором PRC, сериализовать, отправить через RPC на удаленное хранилище данных, дать ему там поработать, опять сериализовать и послать обратно с результатами. пожалуйста, визитера я использую, тот что у меня есть, а сериализацию из boost. Только вы на мой вопрос то не ответили, относительно ПРОСТОЙ реализации Визитера на Яве. ваще отвечать вопросом на вопрос... В Яве надо реализовывать интерфейс Визитор из корня. Если иерархия не доступна, писать враппер. На работе мы вообще всегда пишем врапперы для всех third-party иерархий. Чтобы отказ от одной библиотеки и переход на другую повлиял только на подсистему, в рамках которой эта библиотека используется. А подсистема была бы одинаково красивой и расширяемой вне зависимости от используемых библиотек. dwl Сергей ИльичКонкретно для этого случая (Скинуть дамп объекта в виде XML)можно использовать reflection API. В иных случаях для добавления функциональности можно использовать wpapper. вы очень и очень хорошо умеете не отвечать на вопрос. вас грамотно этому научили. Вы прекрасно имеет ввиду, что сохранение в XML я использовал как практический отвлеченный пример. Повторю еще ОООООООЧЕНЬ простую задачку: (удивительно как много воды вы успели налить на нее) 1) Есть четыре класса: Graphics (базовый), (наследники)Bitmap, VectorGraphics, textArea 2) Есть определеная функциональность (КОД), которую нужно добавить каждому. 3) реализация этой иерархии классов закрыта Если не доступен корень, то функциональность не добавить никак. Ни в Яве, ни в С++. Если мне, как руководителю проекта С++, кто - нибудь принесет такое извращение, я заставлю переписать. Если я буду рядовым участником комманды, я напишу враппер, как бы я это сделал на Джаве. И никто не заметит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.01.2005, 11:55 |
|
||
|
C++ & Java
|
|||
|---|---|---|---|
|
#18+
NotGonnaGetUsРазницы объявлен метод accept(), как член Graphics или нет - нет.Просто вызов g.accept(v) меняется на v.visit(g). думаю что все таки разница есть. NotGonnaGetUsВ вашу реализацию абстрактоного визитёра такой метод нельзя будет вставить?Можно, только она не будет задействована, потому что будут инстанцироваться только те методы Визитера, типы аргументов которого перечислены в typedef. NotGonnaGetUsС вашей помощью, я получил ответ на интересовавший меня вопрос. Спасибо :) Думаю можно смело прекрщать наш "флейм" на тему generic vs generic ^_^ взаимно. я лишь отставиал то, что generic programming это еще одна парадигма программирования, которая удачно может дополнять имеющиеся технологии разработки. Я бы и остаюсь противником позиции С.И, которую он упорно НЕ аргументирует, а только сыплет эмоциями про нефочитов и прочее. С вами было приянее беседовать. Сергей ИльичВо - первых хранить это дело в дин.массиве можно, если хранить указатели. При этом приемущества шаблонов перед Object* становятся умозрительными. С этим я тоже не соглашусь. 1) для этого надо иметь условие типа все классы в языке являются наследниками Object 2) Это по сути не отодвигает вас от идеи использование нетипизированных указателей, потому что от Object* можно "получить" якобы указатель на люой другой тип. Компилятор тебя не остановит. тебе придется полгаться только на собственную внимательность. Сергей ИльичВо-вторых не юзаю буст. Если без библиотеки можно обойтись - значит нужно аргументировать, зачем ее цеплять к проекту. согласен. я нигде не устверждал что boost нужно использовать повсеместно. Я приводил эту билиотеку как пример возможностей generic programming. Сергей ИльичЕсли нельзя обойтись, значит чего это за язык, на котором ничего не работает без установки доп. костылей? 1) Вы переворачиваете смысле идеи повторного использования кода. 2) Фраза типа " ничего не работает " является аголделым обощением которые обычно использует желтая пресса или тупицы мужья кричащьие в пъяном бреду "все бабы Б..ди!". Все это глупое сотрясение воздуха. Сергей ИльичИ вообще, нафиг мне чего-то создавать в стеке? Зачем это? Взаимный вопрос про кучу. насчет "нафиг" я достаточно обоснованно ответил - это повышает 1) быстродействие 2) безопасность обработки исключений разговаривать на эту тиму в режими "спора с журналистами", которые задают десткие вопросы, никак не обращая внимание на мои аргументы( ПРАКТИЧЕСКИЕ АРГУМЕНТЫ) - не вижу смысла. Это как обращать внимание на лающую грязную дворняжку. Сергей ИльичА чтобы не получить memory leak, компилировать без исключений и юзать чего - либо более умное типа SEH? В некоторых виндовых компиляторах, например в MSVC, Intel, есть механизм отображения SEH исключений в обычные исключения. Опять скажу что ничего плохого в обработке исключение не вижу. Покажите мне пример доказывающей обратное, мне надоели ваши голословные крики, похожие на возгласы агитаторов. Сергей ИльичКстати, ты мне так и не ответил, как ты относишься к тому чтобы при каждой перефасовке содержимого std::vector производить копирование всех внутренних коллекций? Вопрос не понятен - приведите код. Я дам вам ответ. Сергей ИльичБуста у меня нет, а в std:: нету никакого shared_ptr . 1) надуманна проблема 2) я приводил кода счетчика ссылок не думаю что он сложен 3) не думаю что разработчики других языков сторонятся использования внешних библиотек. Кстати, умные указатели буста приняты в черново стандарт нового С++ еще в октябре 200 года. Сергей ИльичСам я это дело писать не хочу. Так можно далеко пойти. Это не аргумент. Я же не выдвигаю аргументов по управлению кучей в С++. Уж не знаю имеются ли подобные средства в Яве, в чем я глубоко сомневаюсь. Тогда я просто не представляю как портировать туда несколько моих проектов, где для std::list используются два аллокатора, где есть std::vector, которые использует VirtualAlloc. И вообще, менлкие объекты лежат в куче мелких обхектов со своим алгоримом выделение освбождения памяти, а большие и средние в другой куче. мне это не нужно я не собираюсь сравнивать два разных языка предназаначенных для разных целей. Я уже про все это устал говорить. Сергей ИльичИ это еще меня обвиняет в передергивании. Массив указателей на объекты, порожденные статическими методами генерации.Вполне может быть чего-то такое. 1) я не это, я как минимум ОН. 2) я не обвиняю я показываю не неопровержимые факты 3) это кончено не аргумент, я говорил не о теоритической необходимости и возможности разместить в массиве. Я говорил, о том что на прикитке это не потребуется. 4) не вижу никаких сложностей см размещением их в контейнерах. Сергей ИльичВреде бы, это один из (может, единственный) способов запретить наследование класса в С++. 1) это неверный способ 2) вы конечно ооочень внимательно смотрели мои примеры. раз пропустили действительно верный способо сделать класс ненаследуемым. В очередной раз доказывает методику ваших высказываний. Сергей ИльичЗа компьютер очень просто сказать - надо сравнить время компиляции идентичных по функциональности программ на разных языках. Если компилировать в нативный код, то C++ можно сравнивать, скажем, с Дельфи. По каким критериям? Быстройдествие, вряд ли у вас получится создать билиотеку матричных вычислений быстрее чем biltz или хотя бы boost::uBLASt. Меньший объем кода? хмм. маловероятно что это верно. Делфи ориенирован на создание визуальных интерфейсов. Стандарта Делфи как тогого не существует. Он меняется от версии к версии. Даже поставки одной версии меняют объем VCL. Так что все далеко не очивидно. Но в одном я уверен. Написание дествительно безопасного кода с кучей try except (в делфи), убдет выглядет замороченней, чем подобный код на С++. Сергей ИльичList или Map, то отладчик все равно отобразит все его содержимое. интересно посмотреть как он это сделает. Это ведь связанный список и по нему надо пробежаться, чтобы кинуть в Watch. тем ни менее мы перешли к обсуждению инструментальных средств языков, которые частью язка не являются. так недалеко до обсуждений IDE. Я не знаком со всеми средами С++, и не могу днозначно утверждать что нету отладчика, который может отбразить связанный список. Сергей ИльичКаждый функциональный кирпич в джава так и остается этим же самым функциональным кирпичем. То же самое могу сказать о С++. Да и многи других языках. Сергей ИльичНе вижу. Полиморфизм там работает изумительно. Я не говорил что он не работает. Это вы утверждали что generic не пашет и не нужен. Давайте от слов к делу. Мне было не лень написать коды теперь ваш чередж написать ОБОБЩЕННОЕ решение для каждого моего примера но средствами только ООП. Хватит наконец языком молоть воздух. Вы это умеете я заметил. Сергей ИльичВ Яве надо реализовывать интерфейс Визитор из корня. Если иерархия не доступна, писать враппер. Код в студию. Звтит из пустого в порожнее переливать. вы повторяетесь. Даешь код! Сергей ИльичЧем больше пишешь на С++, тем более сложным он кажется. Пустые слова, которые являются только мнением. обычон это дополняют словом ИМХО. Не выдавая за истину. так вот мое ИМХО, чем больше я пишу на С++, тем более логичным мне он кажется. Сергей ИльичПисание кипятком по поводу гениальности STL и изящества указателей на функции - признаки восторженного неофита. Вряд ли я ошибаюсь. Вот глупый человек! Просто непроглядно! Я показал код, рассказал аргументы в пользу такого подхода. все по полочкам. попрошу и вас дорогой пустомеля привести примеры (аргументы вашего бреда). Насчет писания кипятком - вы навероне рядом с туалетом работаете. вам показалось. сто раз говорил, что любое решение обладает плюсами и минусами. и что как не крути существуют ситуации, когда шаблоны жффективно дополняют парадигму ООП. примеры я устал уже приводить. а ваши голословные бредни мне уже надоели. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.01.2005, 13:24 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=32857244&tid=2029679]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
167ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
72ms |
get tp. blocked users: |
2ms |
| others: | 243ms |
| total: | 527ms |

| 0 / 0 |
