powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / C++ & Java
160 сообщений из 160, показаны все 7 страниц
C++ & Java
    #32839736
gda
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kakoi globalinoe razlicie mejdu C++ i Java. I znaiu sledscie:

Java:
1. Net ukazatelei.
2. Suscesvuiet poniatie Garbage Colector, JVM sledit za osbojdeniem pamiati pri vihodi iz programi
3. Bolee lehhkii dlia izucenia iazik
4. Orientirova na Internet
5. Tipizirovanii iazik programirovania, na moment compiliatii vse peremenie i virajania imeiut tip.

4to esti u C++ i netu u Java.

Kakie sujestvuit ije razlicia mejdu atimi dvumea iazikami
...
Рейтинг: 0 / 0
C++ & Java
    #32839919
Lepsik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. templates - отсутствие этого в java делает язык игрушечным и малопригодным.

2. скорость работы приложений.

поэтому место java на мобилах и в скриптах. Ну а С++ вечен поэтому.
...
Рейтинг: 0 / 0
C++ & Java
    #32840997
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
-управление преобразованиями типов
-нет друзей, т.е. нет например возможности запрета наследования класса
-вызов перекрытого метода
-отсутствие работы с кучей, переопределение операторов new и delete
-отсутсвие префикса наследования классов virtual
-(кажется) отсутсвие встраиваемых функций и методов
-отсутсвие упаковки классов при наследовании
-я, чесно гря, ничего не слышал о статической инициализации переменных

всего чичаз и не упомнишь. в с++ каждый день открываю до сих пор что-то новое.

ЗЫЖ звиняйте за глупый вопрос, а typedef есть в яве? плюс каковы там правила поиска имен в плане различных областей видимости?
...
Рейтинг: 0 / 0
C++ & Java
    #32841078
Sie
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Sie
Гость
автор-нет друзей, т.е. нет например возможности запрета наследования класса
-вызов перекрытого метода
-отсутсвие префикса наследования классов virtual
-(кажется) отсутсвие встраиваемых функций и методов
-я, чесно гря, ничего не слышал о статической инициализации переменных
может я и гоню, но это в яве есть...
хотя спорить не буду, последний раз писал серъёзное 2 года назад.
надо будет почитать...

А ещё есть такая прикольная штука как сервлеты - удобно.
...
Рейтинг: 0 / 0
C++ & Java
    #32841395
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
ну значит мои данные устарели
...
Рейтинг: 0 / 0
C++ & Java
    #32842138
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Глобально - так: С++ - рулез, Java - отстой. Это если не вдаваться в подробности.
...
Рейтинг: 0 / 0
C++ & Java
    #32842444
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
а вот и врете! нету в Яве статической инициализации переменных. Нет, канеш там можно определить статический член класса, да и любой другой и задать для него значение. Но это не статическая а динамическая инициализация. Потому что классы в Яве можно распологать только в куче. Или я не те книжки читал. Статическая инициализация в С++ (чаще это обнуление) происходит до динамической, хотя имхо она происходит еще на этапе компиляции, когда статические данные связываются со своими значениями и просто размещаются в сегменте данных.
...
Рейтинг: 0 / 0
C++ & Java
    #32843240
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. Net ukazatelei.

Напротив, там *только* указатели либо атомарные типы.
На объекты можно ссылаться только с помощью указателей.

5. Tipizirovanii iazik programirovania, na moment compiliatii vse peremenie i virajania imeiut tip.

Вот с этим промах. В связи с отсутствием шаблонов чересчур часто используется Object и downcasting.
...
Рейтинг: 0 / 0
C++ & Java
    #32843248
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivГлобально - так: С++ - рулез, Java - отстой. Это если не вдаваться в подробности.
Только у нас почему-то всех С++идов на Джавистов и Дотнетчиков переучивают.
Интересно, с чего бы это?
...
Рейтинг: 0 / 0
C++ & Java
    #32843275
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwlа вот и врете! нету в Яве статической инициализации переменных. Нет, канеш там можно определить статический член класса, да и любой другой и задать для него значение. Но это не статическая а динамическая инициализация. Потому что классы в Яве можно распологать только в куче. Или я не те книжки читал. Статическая инициализация в С++ (чаще это обнуление) происходит до динамической, хотя имхо она происходит еще на этапе компиляции, когда статические данные связываются со своими значениями и просто размещаются в сегменте данных.
Есть там статическая инициализация.

Код:
1.
2.
3.
4.
class SomeClass {
  static private final int a = 10;
  static private final String b = "Cool";
}


a и b инициализируются во время загрузки класса в память и в дальнейшем изменить их нельзя. Чтобы их можно было изменить, надо убрать final.
Они имеют статическую область видимости, то есть они одни на весь класс. Чего еще надо?
...
Рейтинг: 0 / 0
C++ & Java
    #32843429
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей Ильич MasterZivГлобально - так: С++ - рулез, Java - отстой. Это если не вдаваться в подробности.
Только у нас почему-то всех С++идов на Джавистов и Дотнетчиков переучивают.
Интересно, с чего бы это?


Это провокация с целью повышения уровня всемирного отстоя.
...
Рейтинг: 0 / 0
C++ & Java
    #32843573
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivЭто провокация с целью повышения уровня всемирного отстоя.
2 my mind чем больше человеку нравится C++, тем меньше он его знает.
А вообще, какие копмиляторы C++ на дынный момент актуальны?

g++ - для написания консольных программ под уникс-образные ОС хорош, но Win32 GUI на нем не пишут.

Borland C++ Builder - отвратная документация, ориентированная на Паскаль.
Очень посредственное качество кодогенерации.
Нелюбимое дите Борланда, которое они выкинули на помойку.

Watcom - RIP

Comeau - одно время все восхищались его соответствию т.н Стандарту, приводили результаты онлайновой компиляции как эталон. Но сейчас про него ничего не слышно.

MSVC++ 6.0 SP5. Мой любимый компилятор. Но он был выпущен 8 лет назад.

MSVC++ 7.0 Занимает уже не первое почетное место в Visual Studio. По ходу повторит судьбу С++ билдера.
...
Рейтинг: 0 / 0
C++ & Java
    #32843956
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Сергей Ильич
a и b инициализируются во время загрузки класса в память и в дальнейшем изменить их нельзя. Чтобы их можно было изменить, надо убрать final.

Это не статическая инициализация - это динамическая, т.е. при вызове конструктора класса. А т.к. в Яве классы могут располагаться только в куче, то ни о какой статической инициализации речи быть не может. Статическая инициализация, когда не создается никакого кода, когда эти "константы" известны еще на этапе компиляции и они сразу попадают при линковке в область данных ЕЩЕ до ЗАПУСКА программы. На этом основано несколько приемов программирования С++, правда почти все они связаны с generic programming.

ЗЫЖ С++ умирал уже сто раз. Завидую стабильности этих возгласов о его скорой прискорой смерти.

ЗЫЖ2 судя по MSVC 2005 микрософт не оставляет компилер с++ без внимания, делая его использование в управляемой среде более удобным.

В сравнении языков не вижу смысла. Одни сплошные имхо. причем жутко эмоциональные.
...
Рейтинг: 0 / 0
C++ & Java
    #32843993
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl
Это не статическая инициализация - это динамическая, т.е. при вызове конструктора класса. А т.к. в Яве классы могут располагаться только в куче, то ни о какой статической инициализации речи быть не может. Статическая инициализация, когда не создается никакого кода, когда эти "константы" известны еще на этапе компиляции и они сразу попадают при линковке в область данных ЕЩЕ до ЗАПУСКА программы. На этом основано несколько приемов программирования С++, правда почти все они связаны с generic programming.


Никакого вызова конструктора еще нет. Эти переменные инициализируются, как только класс загружается JVM. Класс загружается в JVM *ДО* любого создания экземпляров этого класса.

dwl
ЗЫЖ С++ умирал уже сто раз. Завидую стабильности этих возгласов о его скорой прискорой смерти.
Это напоминает речи фанатов OS/2. (Чтоб ты так жил, как OS/2 умирает!!!) Чем яростнее фанаты, тем больше сигналов, что не все ладно в датском королевстве.
...
Рейтинг: 0 / 0
C++ & Java
    #32844087
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Сергей ИльичНикакого вызова конструктора еще нет. Эти переменные инициализируются, как только класс загружается JVM. Класс загружается в JVM *ДО* любого создания экземпляров этого класса.
еще раз повторю, они известны на этапе компиляции, по сути они равносильный константам, но только обладают областью видимости. Т.е. инициализации как таковой у них нет, в противовес глобальным константам, которые наподобие статичных переменных Явы инициализируются на этапе загрузки до вызова main().

не вижу смысла дальше это обсуждать - на вопрос автору темы ответили. Тему можно и нужно закрывать. Кстати, в добавлении о разнице между Ява и С++. Первый является обычным ООП-языком. С++ же помимо технологий ООП вмещает в себя еще и generic programming. Приемы последнего ПРИ УМЕЛОМ ИСПОЛЬЗОВАНИИ позволяют вывести разработку приложений на более высокий уровень безопасности типов, чем Ява. Пример - контейнеры. Для того чтобы их реализовать в Яве придется прибегать к преобразованиям типов или полиморфизму( если разрабатывать контейнер под известную иерархию классов ). Однако все это откладывает проверку типов с этапа компиляции на этап выполнения. И чаще требует от разработчика большего опыта, нежели использование контейнеров С++.

Возможность generic programming вместе с приемаи ООП, позволяет добиться еще большего. Например, создания некоторых возможностей языка, о которых не знали во время его разработки. Например, мультиметоды, делегаты, проперти. Язык достаточно прозрачен в реализации этих возможностей. Так, например, сделать это в Яве без изменения самого языка не представляется возможным. Тоже кстати можно сказать о сборщике мусора. Использование умных указателей выполняет ту же функцию, за той лишь разницей, что все в руках программиста.

С++, как и любой другой ЯП, как и любая другая программа не идальны и не лишены минусов. Я не говорю о том, что он лучший. Или о том что все остальные языки саксь, а те кто их используют - тупицы. Я так даже не думаю.

Фишка в том, что чем опытнее специалист становится в том или ином вопросе, тем больше он врастает в систему, которую использует. Поэтому естесственной реакцией является протест и скептицизм по отношение к другому. Кстати именно поэтому С++ пришлось делать во многом совместимым с С, и из-за этого он проиграл сильно в модульности. Как и теперь, нельзя сказать - то что происходило в С++ никак не повлияло на другие языки. повлияло!

вот вам "небольшая" разница между явой и с++ с моей точки зрения, т.е. в сочетании нескольких приемов программирования.

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

во флейме никогда нету смысла. сори за многословность.
...
Рейтинг: 0 / 0
C++ & Java
    #32844105
mardiyan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да... господа и дамы, ну вы конечно дали...

А на самом деле Java - полный отстой но по другой причине.

1. Там нет явных указателей! Они все подразумеваемые.

2. И еще но этом гребаном языке ничего нельзя сделать не создав класс. Вы представляете сколько нужно потратить времени чтобы написать обычную процедурную программку? Просто кошмар.

3. А еще, еще, знаете как они называют coredump? Они это называют NullPointerException. Ха-ха-ха

4. И вообще идиотский язык, который сразу же падает при попытке переполнения массива... Нет чтобы как в нормальном сишнике, взять да и упасть на попытке доступа к уже освобожденному объекту, чтобы потом хороший программист имел много приятных часов затраченных на ослеживаение того, чья же всетаки функция запорола объект и не вычистила его из списка.

5. Но особенно меня раздражают люди которые используют алгоритмы из STL. Это же каким надо быть уродом, чтобы лишать себя удовольствия в очередной раз написать qsort, поотлаживать его...

Вобщем я в шоке... каждый раз когда гляжу на себя в зеркало - думаю. Как же хорошо, что я программирую на C++ а не на Java.
...
Рейтинг: 0 / 0
C++ & Java
    #32844133
J--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
J--
Гость
- нет друзей, т.е. нет например возможности запрета наследования класса

а как же final классы?

Шаблоны - уже появились вроде

Насчет статики тодже не совсем верно - у меня может быть статический член класса,
я его могу использовать, не создав еще ни одного экземпляра класса, конструктор при этом не вызывается (он может вообще недоступным быть),
а только блоки статической инициализации.


И наконец, Жабу тоже все время хоронят, но она не скоро умрет
- это основной общий признак с C++ {после скобочек фигурных конечно}
...
Рейтинг: 0 / 0
C++ & Java
    #32844319
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Borland C++ Builder - отвратная документация, ориентированная на Паскаль.
Нелюбимое дите Борланда, которое они выкинули на помойку.

Документация видимо имеется в виду по VCL-ю.
А так вроде бы его хвалят. И на счет нелюбимого дитя - нелюбимое - это
BCB, а сам компилятор, я думаю, никто не собирается выкидывать.
Я его сам не использую, но говорят, что он у них

Comeau - одно время все восхищались его соответствию т.н Стандарту, приводили результаты онлайновой компиляции как эталон. Но сейчас про него ничего не слышно.

Кстати, я так понял, его у нас в России писали, хотя я могу и ошибаться.
Статья была (лирического содержания) о том, как это происходило. Без указания , естественно, бурж. фирмы, на которую они работали. Но я так понял, что это оно и было. Хотя это только догадки, конечно.

MSVC++ 7.0 Занимает уже не первое почетное место в Visual Studio. По ходу повторит судьбу С++ билдера.

Сомневаюсь, что повторит. Его вроде бы тоже хвалять, что странно для компиляторов от MS (речь о соответствии стандарту, до которого MSVC50 и 60 не дотягивались).

Еще я лично могу порекомендовать компилятор от Intel. Он встраивается в ту же Visual Studio. Работает хотя и заметно медленнее MS-овского (раза в три визуально), но гораздо лучше соответствует стандарту, не падает (как MS-овский иногда) и может генерировать код под Itanium. Мне он понравился очень хорошей диагностикой и действительно умными предупреждениями, которых MS не выдавал.
...
Рейтинг: 0 / 0
C++ & Java
    #32844574
Lepsik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2Сергей Ильич

---Borland C++ Builder - отвратная документация, ориентированная на Паскаль.

вы ей просто пользоваться не умеете

--Очень посредственное качество кодогенерации.

кого это сейчас волнует ?

--Нелюбимое дите Борланда, которое они выкинули на помойку.

у вас неверные сведения. читайте описание Borland Studio 2005
...
Рейтинг: 0 / 0
C++ & Java
    #32845402
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl Возможность generic programming вместе с приемаи ООП, позволяет добиться еще большего. Например, создания некоторых возможностей языка, о которых не знали во время его разработки. Например, мультиметоды, делегаты, проперти. Язык достаточно прозрачен в реализации этих возможностей. Так, например, сделать это в Яве без изменения самого языка не представляется возможным. Тоже кстати можно сказать о сборщике мусора. Использование умных указателей выполняет ту же функцию, за той лишь разницей, что все в руках программиста.
Шаблоны не могут быть скомпилированы в случае, если декларация класса лежит в одном файле, а реализация - в другом. Объединять их, чтобы персобирать весь проект в случае добавления одной строчки, я не собираюсь.

Если тебе нравится химичить, возьми какой нибудь язык функционального программирования (Lisp, Ocaml, Haskell ...) и поразись, насколько там все это круче.

mardiyan
1. Там нет явных указателей! Они все подразумеваемые.

Обычные там указатели. Только они безразмерные. Если бы они были размерными (некоторое смещение), то это бы бессмысленно, поскольку уборщик мусора имеет обыкновение периодически дефрагментировать кучу. Поэтому объекты периодически перемещаются по памяти. Что бы тебе дало число, которое само по себе изменяется? Кстати в С++ для того, чтобы переместить объект, надо использовать конструктор копирования и placement new. memmove не катит.

mardiyan
2. И еще но этом гребаном языке ничего нельзя сделать не создав класс. Вы представляете сколько нужно потратить времени чтобы написать обычную процедурную программку? Просто кошмар.

Гы. А сколько времени надо потратить в C++, чтобы состыковать несколько модулей от разных производителей, в нетривиальной программке?

mardiyan
3. А еще, еще, знаете как они называют coredump? Они это называют NullPointerException. Ха-ха-ха

Странная проблема. Написать в javadoc "cannot be null" и спать спокойно. А также возвращать вместо нулей коллекции нулевого размера.

mardiyan
4. И вообще идиотский язык, который сразу же падает при попытке переполнения массива... Нет чтобы как в нормальном сишнике, взять да и упасть на попытке доступа к уже освобожденному объекту, чтобы потом хороший программист имел много приятных часов затраченных на ослеживаение того, чья же всетаки функция запорола объект и не вычистила его из списка.

Это шутка?

mardiyan
5. Но особенно меня раздражают люди которые используют алгоритмы из STL. Это же каким надо быть уродом, чтобы лишать себя удовольствия в очередной раз написать qsort, поотлаживать его...

Не понял. Collections.sort() может отсортировать любую последовательность, реализующую интерфейс List, если элементы реализуют интерфейс Comparable.

Lepsik
---Borland C++ Builder - отвратная документация, ориентированная на Паскаль.

вы ей просто пользоваться не умеете

Почему документация на незнакомом мне языке? Ну не знаю я Паскаль...
Мне нужен компилятор С++... В Java документация - это вообще результат работы javadoc, натравленной на исходный код Java. И ничего, кушать можно.
...
Рейтинг: 0 / 0
C++ & Java
    #32845747
MKV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gda
Для Вас этот вопрос философский или имеет какое-то практическое значение? Если философский - то пардон, я тут ничего не могу сказать, кроме того что в этом случае вопрос целесообразнее перенести в пивную.
А если ближе к делу то язык, сам по себе, - это вообще пшик, ничто. Так, вершина айсберга. С++, Java, Pascal - одна батва, мелкие стилистические отличия. Вся разница в библиотеках. А в Java и С++ они совершенно разные. Перечислить нельзя - просто все другое.
...
Рейтинг: 0 / 0
C++ & Java
    #32846297
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Сергей Ильич
Шаблоны не могут быть скомпилированы в случае, если декларация класса лежит в одном файле, а реализация - в другом. Объединять их, чтобы персобирать весь проект в случае добавления одной строчки, я не собираюсь.

1)у вас неверные сведения. не те книжки читали.

2)Химичить? Т.е. для вас написать массив нетипизированных укзателей проще? а потом мучатся с кучей преобразований типов. а мне проще так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
class Shape{
...
void draw();
};
struct MyFunc{
 bool operator()( const& MyInt rhs ) const;
}

vector<MyInt> v;
..
for_each( v.begin(), v.end(), mem_fn(&Shape::draw) );
remove_if( v.begin(), v.end(), MyFunc );

что ж тут такого трудного? и главное строгая проверка типов. И все на этапе компиляции. Напишите контейнер на Яве, КОТОРОМУ БЫЛО БЫ ПОФИГ какой тип хранить. и вам сможете сделать только две вещи:
1) взять какой-нить аналог variant и писать массив для него. НУЛЕВАЯ ПРОВЕРКА ТИПОВ
2) взять какой-нить класс от которого наследуют все остальные классы вашей проги. Но тогда для вызова неполиморфных методов вам придется проверять на тип и вызвать при правильном преобразовании типа нужный метод. ХА. но это все делается в рантайм.

Шаблоны лучше и это очевидно.
...
Рейтинг: 0 / 0
C++ & Java
    #32846369
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl Сергей Ильич
Шаблоны не могут быть скомпилированы в случае, если декларация класса лежит в одном файле, а реализация - в другом. Объединять их, чтобы персобирать весь проект в случае добавления одной строчки, я не собираюсь.

1)у вас неверные сведения. не те книжки читали.

MSVC++ не позволяет разделять декларацию и имплементацию шаблонов. В g++ AFAIK та же история. А это основные компиляторы С++.

[quot dwl]
2)Химичить? Т.е. для вас написать массив нетипизированных укзателей проще? а потом мучатся с кучей преобразований типов. а мне проще так
<.. SKIP ..>
1) взять какой-нить аналог variant и писать массив для него. НУЛЕВАЯ ПРОВЕРКА ТИПОВ
2) взять какой-нить класс от которого наследуют все остальные классы вашей проги. Но тогда для вызова неполиморфных методов вам придется проверять на тип и вызвать при правильном преобразовании типа нужный метод. ХА. но это все делается в рантайм.

Шаблоны лучше и это очевидно.
[/quote]
В IDEA достаточно набрать
List list = obj.method();
А потом
itco<tab>
И среда сама сформирует цикл для итерации по коллекции, дедуцируя все чего надо.
Гораздо проще найти 10 рунтаймовых ошибок в Java, чем разобрать одну ошибку с STL, которая приводит к появлению 10+ килобайт error-сообщений с развернутыми шаблонами.
...
Рейтинг: 0 / 0
C++ & Java
    #32846398
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
у страха глаза велики - вы излишне все преувеличивайте, возводя это в ранг дефакто. я лично не испытаваю никаких сложностей с использованием шаблонов. у меня ни разу не было 10 килобайтных ошибок. более того сообщениями об ошибках я могу управлять при помощи тех же шалонов делая их более понятным и краткими.

нежелание разобраться с тем как использовать generic programming приводит к раздуванию из мухи слона. Еще раз говорю, статическая проверка типов, которую дают шаблоны гораздо удобней кучи преобразований типов. и не просто удобней, но и безопасней с точки зрения разработки.
...
Рейтинг: 0 / 0
C++ & Java
    #32846413
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
- насчет "среда сама сформирует" - не все среда может сама сформировать. Пусть вам среда "сама напишет" алгоритм удаления (недавно на форуме написал) из строки пробелов заключенных в двойные кавычки. это так фигня.

- а может ваща "среда" написать мультиметод? если вы канчно знаете что это такое.

- а может ваша суперсреда спрограммирует за вас анонимные методы?

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

список можно продолжать долго.
...
Рейтинг: 0 / 0
C++ & Java
    #32846423
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
а можете вы написать контейнер, в котором могут хранится как функции так и методы? Напишите. Потом я кину пару своих строчек - сравним, что безопасней и понятней.
...
Рейтинг: 0 / 0
C++ & Java
    #32846554
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl- насчет "среда сама сформирует" - не все среда может сама сформировать. Пусть вам среда "сама напишет" алгоритм удаления (недавно на форуме написал) из строки пробелов заключенных в двойные кавычки. это так фигня.

- а может ваща "среда" написать мультиметод? если вы канчно знаете что это такое.

Насколько я помню, Скотта Мейерса очень тяготила необходимость перекомпилировать все классы, после того как в его демо-программе, эмулирующей мультиметоды, появляется новая сущность. Если же мы для мультиметодов будем использовать Александреску-вские технологии, то о раздельной компиляции по видимому придется забыть.

dwl
- а может ваша суперсреда спрограммирует за вас анонимные методы?

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

Все это спокойно можно сделать с помощью интерфейсов.
...
Рейтинг: 0 / 0
C++ & Java
    #32846715
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
вы не говорите что это фигня и что можно сделать - вы сделайте. я потом приведу код на шаблонах, чтобы продемострировать разницу. Чего вы боитесь? Или вы только лозунги выдвигаете необоснованные, вернее основанные на слухах и домыслах. Переиначенные и перевранные.
...
Рейтинг: 0 / 0
C++ & Java
    #32846746
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl

Напишите контейнер на Яве, КОТОРОМУ БЫЛО БЫ ПОФИГ какой тип хранить. и вам сможете сделать только две вещи:
1) взять какой-нить аналог variant и писать массив для него. НУЛЕВАЯ ПРОВЕРКА ТИПОВ
2) взять какой-нить класс от которого наследуют все остальные классы вашей проги. Но тогда для вызова неполиморфных методов вам придется проверять на тип и вызвать при правильном преобразовании типа нужный метод. ХА. но это все делается в рантайм.

Шаблоны лучше и это очевидно.


Лишним доказательством этого является тот факт, что даже в Java в последнем JDK добавили шаблоны (в язык). Мотивайцией было именно это - чтобы иметь возможность хранить в коллекциях типизированные (ссылки на) объекты, а не абстрактные Object-ы.
...
Рейтинг: 0 / 0
C++ & Java
    #32846828
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwlвы не говорите что это фигня и что можно сделать - вы сделайте. я потом приведу код на шаблонах, чтобы продемострировать разницу. Чего вы боитесь? Или вы только лозунги выдвигаете необоснованные, вернее основанные на слухах и домыслах. Переиначенные и перевранные.
Делегат - это типа указателя на функцию? В Java его обычно так делают:

Код: Java
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.
public interface CoolHandler {
  void boZo() throws SomeException;
}

//....

class SomeClass1 {
  private CoolHandler coolHandler = null;
   
  public setCoolHandler(final CoolHandler coolHandler) {
    this.coolHandler = coolHandler
  }

   //

   void method() {
      //.......
      try {
        coolHandler.boZo();
      } catch  (SomeException e) {
        //....
      }
      //.......
   }
}

class SomeClass2 implements CoolHandler {
  void boZo() {
    // реализация
  }

  void method() {
      SomeClass1 c1 = new SomeClass1();
      c1.setCoolHandler(this);
      c1.method();
      // ..........
  }
}

...
Рейтинг: 0 / 0
C++ & Java
    #32846838
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivЛишним доказательством этого является тот факт, что даже в Java в последнем JDK добавили шаблоны (в язык). Мотивайцией было именно это - чтобы иметь возможность хранить в коллекциях типизированные (ссылки на) объекты, а не абстрактные Object-ы.
Чего-то мне непонятно, почему С++-иды стали такими фанатами строгой типизации. Уж и до смешного доходит - std::allocator<T>::allocate возвращает T*, а не void*. Хотя, если нормально подумать - ведь он возвращает указатель на сырую память, следовательно он не имеет права возвращать T* !
Хлеб нашей организации - это несклько монструозных программ на С++, и шаблоны и STL там нигде не используется. Огромные иерархии классов по 40 уровней, из которых первые 7 - абстрактные, тот же downcasting. Все отлично бегает.
У Страуса и Александреску парадигма может и красивая в чем-то, но непрактично это.
...
Рейтинг: 0 / 0
C++ & Java
    #32846965
SiebenteWerk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторХотя, если нормально подумать - ведь он возвращает указатель на сырую память
Хотя, если подумать, все указатели суть указатели на сырую память :)
Всё остальное делаётся по смещению.

автори шаблоны и STL там нигде не используется.
Это не значит, что они вообще нигде в мире не используются.

Область средств программной разработки - это как эволюция. Если кому-нибудь что-то для чего-то надо, оно появляется и приживается, если нет - оно отмирает.
Есть шаблоны - раз они не отмерли - значит это кому-то надо. Раз они появились в Яве, значит и в Яве это надо.

И я вообще не понял сабжа. Ладно ещё сравнивать С и С++. Но Яву-то что сравнивать с Сями? Два разных языка - две разные области применения. Никто же не станет писать виндовое приложение на Яве? И никто не станет писать апплет для веба на сях? А если кто-то станет, то он сам себе враг :)
...
Рейтинг: 0 / 0
C++ & Java
    #32846988
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Сергей ИльичДелегат - это типа указателя на функцию? В Java его обычно так делают:
код понятен. Уточняю делегат - это указатель скорее на функтор в понятии С++, то есть это может быть как указателем на функцию, так и указателем на метод. Делегаты в C# еще из себя представляют коллекции таких указателей, которые вызываются в порядке следования.

теперь посмотрим как это можно сделать в С++. Это будет безопасней( с точки зрения контроля типов) и удобней. Потому как в вашем случае вы можете опираться только на одну сигнатуру. Сделать же контейнер из делегатов разных сигнатур у вас не получится. Если только не прибегать опять к множественным преобразованиям типов.

Итак в С++ помимо удобного bind есть такой классный шаблончик, как function<T>. Аргумент шаблона здесь это сигнатура функции. Т.е. мы имеем в своем распоряжении класс, реализация которого для функци и методов не зависит от оных помимо строгой проверки типов. Пример
Код: 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.
// из документации
class button
{
public:

    boost::function<void> onClick;
};

class player
{
public:

    void play();
    void stop();
};

button playButton, stopButton;
player thePlayer;

void connect()
{
    playButton.onClick = boost::bind(&player::play, &thePlayer);
    stopButton.onClick = boost::bind(&player::stop, &thePlayer);
}

onClick я могу присвоить любую другую функцию возвращающую void без аргументов. Как видно из кода, классу можно присваивать как обычные функции так и методы классов с такой же сигнатурой.

Не сотавит труда написать и следующее vector< function<void> >, т.о. мы будем иметь несколько указателей, для последовательного их вызова. который может выглядеть так
Код: plaintext
1.
for_each( v.begin(), v.end(), _1() );

самое главное. мне не надо по сто раз писать ОДИН и ТОТ ЖЕ код для разных типов callback функций. Суть generic programming состоит в том, чтобы также как в ООП увеличить удобства повторного использования кода и сделать это БЕЗОПАСНО. Для того чтобы изменить сигнатуру вызова callback функции изминения в случае с шаблонами минимальны, сохраняя главное условие СТРОГОЙ СТАТИЧЕСКОЙ проверки типов.

а теперь скажите мне:
1) Это такой сложный код, который я привел? Он опасен с точки зрения проверки типов?
2) если бы у вас был контейнер callback функций с множественными преобразованиями типов, то в случае с изминением типа callback-функтора ругался бы ваш компилер на все места, где нужно сделать изминения? НЕТ.

В случае с шаблонами компилятор не даст вам пропустить ни одного некорректного использования типов. Скажите разве это плохо? НЕТ! Это отлично.
...
Рейтинг: 0 / 0
C++ & Java
    #32846993
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
относительно вашего полного непонимания книг Александреску. Вы конечно вправе иметь свое мнение, но оно больше смахивает на высказывания желтой прессы, которая не желает разбираться в том, что ей показывают. Она лишь делает "сенсационно"-крекливые возгласы, имеющие только одну цель - никакой разумности, главное взбудоражить.

Будьте последовательны. Давайте начнем с конструктива. Самый простой и часто используемый мной и моими друзьями, да и многим другими программистами, прием называемый СТРАТЕГИЯ. Скажите, что вам в нем не нравится? И почему вы считаете что он не имеет практического использования. Приведите пожалуста КОНКРЕТНЫЕ фрагменты кода это демонстрирующие в не просто голословные фразы типа: "Я ни разу его не использвал, значит он не нужен!"

Вопросик другой более сложный, скажите а вы знаете что такое фабрика объектов? Абстрастрактная фабрика? Вы считаете, что это не имеет практического использования? Или вы считаете, что реализация Александреску не подходит? Почему? укажите конкретные примеры. Желательно со ссылками на паттерн Фабрики(см.Гамму) а также с примерами кода.
...
Рейтинг: 0 / 0
C++ & Java
    #32847298
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторкод понятен....
Блин, надо же... я про boost не знал...
В msdn-е не увидел... Где почитать?
...
Рейтинг: 0 / 0
C++ & Java
    #32847487
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
www.boost.org - в большинстве своем будет включен в новый стандарт С++. уже есть в MSVC 2005 и MSDN 2005. В бусте реализованы многие приемы, которые описывал Александреску. Желающие воспользоваться только этими приемами могут найти библиотеку LOKI на сорцфорж. Но в бусте например гораздо лучше и богаче реализованы аллокаторы и функции выделения памяти для маленьких и средних объектов. Так например там есть выделение памяти для синглтонов. Но в тоже время boost не имеет реализации мультиметодов и генерации иерархий для фабрик. Хотя список типов в boost имеется mpl::vector. В локи также имеется очень удобная и гибкая реализация фабрики, абстрактной фабрики, rtti оболочки, синглтон-холдер с выбором стратегии уничтожения и оживления, ну и конечно визитер.
...
Рейтинг: 0 / 0
C++ & Java
    #32847509
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwlкод понятен. Уточняю делегат - это указатель скорее на функтор в понятии С++, то есть это может быть как указателем на функцию, так и указателем на метод.

Концептуально сложно. Зачем нужны функции и методы? Почему не одни методы?

dwl
теперь посмотрим как это можно сделать в С++. Это будет безопасней( с точки зрения контроля типов) и удобней.

Про "безопасней" не надо - в моем примере вообще нет преобразований типов. Один, пользуясь твоей терминологией "строгий контроль".
Про "удобней" тоже не надо. Это соберется компилятором javac из любой JDK и не потребует доп. библиотек. Твой пример вообще не соберется MSVC 6, может быть соберется MSVC7.0 (не отвечаю) и наверное, одним из свежих g++. И еще надо скачивать и инсталлировать boost. Про размер бинари - это тоже хороший вопрос. Мой пример займет несколько килобайт, твой - возможно несколько десятков или сотен килобайт.

dwl
Потому как в вашем случае вы можете опираться только на одну сигнатуру. Сделать же контейнер из делегатов разных сигнатур у вас не получится. Если только не прибегать опять к множественным преобразованиям типов.

Ковыряние в носу.

Заметь, тут нет никакого преобразования типов.
Код: 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.
 interface  ButtonClickHandler {
   void  onClick();
}

 class  Button {
   private   final  ButtonClickHandler listener;
   public  Button( final  ButtonClickHandler listener)  {
     this .listener = listener;
  }
   // ......
    void  onMouseDown() {
     listener.onClick();
   }
   // ......
}

 class  Player {
   private   final  Button startButton =  new  Button(
      new  ButtonClickHandler() {
        void  onClick() {
          start();
       }
     };
   );

    private   final  Button stopButton =  new  Button(
      new  ButtonClickHandler() {
        void  onClick() {
          stop();
       }
     };
   );

    void  start() {
    //.......
   }

    void  stop() {
    //.......
   }
}

dwl
а теперь скажите мне:
1) Это такой сложный код, который я привел? Он опасен с точки зрения проверки типов?

Концептуально довольно сложный. С точки зрения проверки типов очень опасен, поскольку если там где-нибудь будет неподходящий тип, то появится столько ошибок, что будет проще его переписать, чем разобраться "что же не так" ?

dwl
2) если бы у вас был контейнер callback функций с множественными преобразованиями типов, то в случае с изминением типа callback-функтора ругался бы ваш компилер на все места, где нужно сделать изминения? НЕТ.


Дальше мы не поняли чего вы пытались сказать.
Все design patterns элементарно реализуются на Джаве, и никаких четырехэтажных шаблонов там не надо.
...
Рейтинг: 0 / 0
C++ & Java
    #32847627
13th_apostle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
сергей ильич
imho, отличие вашего кода и dwl в том, что вы окончательно присваиваете playbutton & stopbutton соответствующие методы при декларации класса player, а у dwl возможно переназначение этих методов в дальнейшем. если я ошибаюсь, поправьте, plz.
...
Рейтинг: 0 / 0
C++ & Java
    #32847664
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Сергей Ильич
Зачем нужны функции и методы? Почему не одни методы?

таково уж определение делегата. не я его выдумал.

Сергей ИльичТвой пример вообще не соберется MSVC 6
надо же! только что собрал под MSVC 6. видимо мы живем в разных мирах.


Сергей ИльичКовыряние в носу.
Это практическая необходимость. Именно так работают делегаты C#.
Код: plaintext
1.
2.
3.
4.
5.
Form.OnClick += MyEvent;
...
Form.OnClick += AddEvent;
...
Form.OnClick -= MyEvent;
удобный и читабельный код. Вобчем, я так понял на яве нельзя написать контейнер для указателей на метод или функцию. На любую. Интересно глянуть как вы будете реализовывать удаление типа из списка callback методов.

Сергей ИльичКонцептуально довольно сложный. С точки зрения проверки типов очень опасен, поскольку если там где-нибудь будет неподходящий тип, то появится столько ошибок, что будет проще его переписать, чем разобраться "что же не так" ?
Я приблизительно так и думал что вы ответите.
1) можно поподробней в чем его КОНЦЕПТУАЛЬНАЯ сложность. с примерами кода. а то вы льете много воды не подтвержденой словами.
2) ошибок будет несколько вы правы. но насчет разобраться увы не так. все легко читается и исправляется. Это лучше чем лазить отладчиком и смотреть где какое преобразование типов неверно. Вы везде используйте ложные постулаты о том что ТО-ТО и ТО-ТО черезвычайно замочрочено. Это неверный подход. Хотя бы потому что это не является правдой.

вам видимо сложно понять подход generic programming, но его суть состоит и в том числе в отвлечении алгоритмов от типов операндов при сохранении строгой типизации. Как в случае с контейнерами. Я рад за программистов Явы и C#, что у них тоже появились generic. Это сильно облегчит им работу.
...
Рейтинг: 0 / 0
C++ & Java
    #32847731
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Вот полный список компиляторов, на которых ставится boost

Borland C++, Comeau C++ (win, non win), Metrowerks CodeWarrior Pro 6.x, 7.x, 8.x, and 9.x, GCC, Digital Mars C++, Edison Design Group, GNU GCC, Intel C++ for Linux, Intel C++ for Windows, KAI C++, Borland C++ for Linux (Kylix), MinGW, SGI MIPSpro C and C++, Microsoft Visual C++ version 6, 7, 7.1 (в SMVC 2005 включан фициально), SunPRO C++, Compaq C++ for Tru64 Version 6.5 and less, IBM Visual Age C++

Это еще в опровержении ваших поспешных высказываний.

Кстати относительно ваших поспешных высказываний, вы так и не ответили про книгу Александреску. Я вам задал пару наводящих вопросов. Делаем выводы...
...
Рейтинг: 0 / 0
C++ & Java
    #32847935
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl
Сергей ИльичТвой пример вообще не соберется MSVC 6
надо же! только что собрал под MSVC 6. видимо мы живем в разных мирах.

[/quot]

MSVC 6 довольно слабо поддерживает стандарт. Готов ли ты нести ответственность за поведение boost в этих условиях ?

dwl
{--- SKIP ---}
Вобчем, я так понял на яве нельзя написать контейнер для указателей на метод или функцию. На любую. Интересно глянуть как вы будете реализовывать удаление типа из списка callback методов.

В нижеуказанном примере используется downcasting. Но фича в том, что в контейнер *невозможно* положить сущность неправильного типа, не используя reflection или JNI. И это отслеживается статически. К тому же я это сделал потоковобезопасным: нельзя добавить иди удалить обработчик во время рассылки.

Код: 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.
 public   interface  Listener {
   void  handleEvent();
}

 public   class  EventBroadcaster {
   private   final  Set listeners =  new  HashSet();
  //............
   public   void  addListener( final  Listener listener) {
     synchronized (listeners) {
      listeners.add(listener);
    }
  }
   
   public   boolean  removeListener( final  Listener listener) {
     boolean  retVal = false;
     synchronized (listeners) {
      retVal = listeners.remove(listener);
    }
     return  retVal;
  }
  // .......................
   void  broadcastEvent() {
     synchronized (listeners) {
        for (Iterator iterator = listeners.iterator();iterator.hasNext(); ) {
          // do
           final  Listener listener = (Listener) iterator.next();
          listener.handleEvent();
       }
    }
  }
}


dwl
Я приблизительно так и думал что вы ответите.

Значит проблема действительно есть. У Скотта Мейерса в Effective STL есть даже целая глава "расшифровывание ошибок в STL" . Где - то даже были тулзы для того чтобы эти ошибки парсить.

dwl
1) можно поподробней в чем его КОНЦЕПТУАЛЬНАЯ сложность. с примерами кода. а то вы льете много воды не подтвержденой словами.

Слишком много сущностей.
dwl
Я рад за программистов Явы и C#, что у них тоже появились generic. Это сильно облегчит им работу.
Generics в Жаве появились ужедавно. Про шаблоны...
Не знаю, не смотрел я JDK 1.5 . Но там шаблонный класс вроде можно раздельно скомпилировать раз и навсегда.
...
Рейтинг: 0 / 0
C++ & Java
    #32848140
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Сергей ИльичMSVC 6 довольно слабо поддерживает стандарт. Готов ли ты нести ответственность за поведение boost в этих условиях ?
ну во-первых готов. Во-вторых это ответственность на самом деле несут разработчики буста. С самого ее первого появления она дружила с MSVC 6. И до появления 7.1 я спокойно юзал буст на шестерке. Никаких нареканий.

Сергей ИльичНо фича в том, что в контейнер *невозможно* положить сущность неправильного типа, не используя reflection или JNI
ктож спорит. я о другом. о том, что благодаря шаблонам я пишут ОДИН КЛАСС, который отвечает за использование callback функций и методов. Я полностью инкапсулирую все что мне нужно для этого класса. Ну там вызовы виртуальных функций (указатели на функцию или метод этого делать не могут), операции сравнения и т.д. Я делаю эту работу один раз. Далее я оформляю это в качестве шаблона. И в коде, потом просто указываю нужную сигнатуру. ВСЕ! Это как раз УМЕНЬШЕНИЕ СУЩНОСТЕЙ. Потому что мне не надо пложить классы для функций с другими сигнатурами. Понимаете, нет?

аналогично с контейнером. я беру vector и передаю ему нужный тип. мне не надо беспокоится о выделении памяти, синхронизации и прочее. Тот же прием. Мне не надо писать массив или копировать из другого файла что-то - УВЕЛИЧИВАЯ СУЩНОСТИ. я использую ОТЛАДЕННЫЙ КОД. Безопасно использую без всяких преобразований типов.

Сергей ИльичСлишком много сущностей. не больше чем в вашем варианте. Если вас так смущает ПРОСТЕЙШИЙ bind, то можно вместо boost::function написать boost::mem_fn. И код менять ОСОБО не надо, только убрав BIND. Просто в случае с function мы можем использовать не только методы, но обычные функции или СТАТИЧЕСКИЕ МЕТОДЫ. В вашем варианте такое совместное использование не возможно. Это(тип функтора) можно убрать в typedef, это можно спрятать в стратегию. Сущностей будет еще меньше. И код мне не придется почти менять. И читабельность не пострадает. Вы ИМХО предвзяты ОЧЕНЬ. Более подробно относительно УМЕНЬШЕНИЯ СУЩНОСТЕЙ см выше.

Теперь относительно больших сообщений обшибках, за которые вы ухватились как за соломинку бросив все остальное. Если посмотреть мое сообщение в этой ветке но страницей раньше, я уже сказал что все это флейм. Я написал, что помимо ООП есть generic programming и многие с ним не знакомы. Привычки выработанные годами вызвают бурю эмоций отторжения, которые зачастую ничем другим не мотивированны. Этим и объясняется большое колво ЛОЖНЫХ данных, которые даются о С++. Происходит как бы ИДЕОЛОГИЧЕСКОЕ ЗАПУГИВАНИЕ, особенно тех кто не знает что такое generic programming. Всему можно научится но обсуждать это в сравнении с принципиально другим языком - это флейм. так же я написал, что не считаю С++ идеальным языком. Как и любой другой язык и уж тем более яву. Но, во-первых это не дает право никому на ОБОБЩЕНИЯ. и, во-вторых, надо помнить о оптимальных решениях, когда кол-во плюсов, который дает инструмент превышает кол-во минусов. В той или иной ситуации.

Да, редко но случается большой дамп ошибок. ОН связан с глубиной иерархии шаблонного класса. Т.е. один класс инстанцирует другой, тот третий и т.д. и ВЕСЬ СТРАХ-ТО в том что компилятор печатает полное имя класса, которое получается нехилым. Страшно ли это? Да нет. я бы не назвал это армаггедоном.
1) умело проектируйте классы и используйте их с умом
2) есть такая штучка concept_check, которая в сочетании с static_assert побеждает этого зверя достаточно легко. Вы можете придумать свое сообщение об ошибке и ограничит глубину проверки. Используя те же шаблоны. Оба этих шаблона есть в boost, достаточно подробное их описание имеется у Александреску.
3) это была беда древних компилеров, теперь в большинстве своем они печатают сообщения более сжато, как бы ступенчато.

Итак, это происходит редко, это можно обойти, и это не ПЕРЕВЕШИВАЕТ кол-во ПЛЮСОВ использования шаблонов.

ЗЫЖ нучто ж. с контейнером функторов выяснили? вы поняли что вам придется пложить сущности в отличии от шаблонов? могу предложить еще задачку - анонимные методы. 8-))
...
Рейтинг: 0 / 0
C++ & Java
    #32848311
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MSVC 6 довольно слабо поддерживает стандарт. Готов ли ты нести ответственность за поведение boost в этих условиях ?

boost под MSVC 6.0 адаптирован и работает, несмотря на то, что действительно со стандартом в 6.0 плоховато.
...
Рейтинг: 0 / 0
C++ & Java
    #32848339
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей Ильич

Чего-то мне непонятно, почему С++-иды стали такими фанатами строгой типизации. Уж и до смешного доходит - std::allocator<T>::allocate возвращает T*, а не void*. Хотя, если нормально подумать - ведь он возвращает указатель на сырую память, следовательно он не имеет права возвращать T* !


С++, вообще-то, язык со строгой типизацией (не путать с языком С).
Что до типизированных коллекций - ну это просто ОЧЕНЬ СИЛЬНО практичнее, чем коллекции Object(*), иначе Sun в ряд ли "подвинулась" бы на изменение языка.

Что до std::allocator - пример неудачный, потому что и класс неудачный. Считайте , что нет в stl allocator-а вообще, и вам, возможно, станет легче
(понимать , что язык C++ - один из величайших из всех придуманных языков программирования ).
...
Рейтинг: 0 / 0
C++ & Java
    #32848348
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SiebenteWerk
Никто же не станет писать виндовое приложение на Яве?


Ой, пишут, гады, представляешь ? Пишут.

SiebenteWerk
И никто не станет писать апплет для веба на сях? А если кто-то станет, то он сам себе враг :)


Ну а про этих уже кажеться счастливо все забыли. И слава Богу!
...
Рейтинг: 0 / 0
C++ & Java
    #32848366
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl Сергей ИльичMSVC 6 довольно слабо поддерживает стандарт. Готов ли ты нести ответственность за поведение boost в этих условиях ?
ну во-первых готов. Во-вторых это ответственность на самом деле несут разработчики буста. С самого ее первого появления она дружила с MSVC 6. И до появления 7.1 я спокойно юзал буст на шестерке. Никаких нареканий.

А она кидает исключения? А будет ли утечка памяти, если исключение выкинуто из конструктора? А если я хочу компилировать без исключений ?

А она потоково - безопасна? А если мне
1) нужна многопоточность?
2) не нужна многопоточность, но нужна скорость?

dwl
я о другом. о том, что благодаря шаблонам я пишут ОДИН КЛАСС, который отвечает за использование callback функций и методов.

А если обобщенному классу A нужен обобщенный класс В, а обобщенному классу B нужен обобщенный класс A?

В каком порядке мы расположим инклюды? Если бы мы могли разделить декларацию и имплементацию, мы бы пожалуй поместили опережающие декларации в A.hpp и B.hpp, а реализации - в A.cpp и B.cpp. Но в MSVC так с шаблонами делать нельзя.

dwl
Потому что мне не надо пложить классы для функций с другими сигнатурами. Понимаете, нет?

Почему бы и не поплодить. Ведь в Java есть пакеты. По крайней мере я 100% знаю, что мне в качестве параметра будут передавать org.sergey.ilyich.sql-forum-conversation.Listener, а не какую-то сигнатуру.

dwl
Вы ИМХО предвзяты ОЧЕНЬ.
Привычки выработанные годами вызвают бурю эмоций отторжения
Происходит как бы ИДЕОЛОГИЧЕСКОЕ ЗАПУГИВАНИЕ
ВЕСЬ СТРАХ-ТО в том

Пардон за оффтопик и переход на личности, но ты немного похож на одного Свидетеля Иеговы, с которым я как-то переписывался. Те же обороты. Не у них полемике учился?
dwl
функторов выяснили? вы поняли что вам придется пложить сущности в отличии от шаблонов? могу предложить еще задачку - анонимные методы. 8-))
Лямбда чтоли?
...
Рейтинг: 0 / 0
C++ & Java
    #32848555
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Сергей Ильич
А она кидает исключения? А будет ли утечка памяти, если исключение выкинуто из конструктора? А если я хочу компилировать без исключений ?

А она потоково - безопасна? А если мне
1) нужна многопоточность?
2) не нужна многопоточность, но нужна скорость?

1) исключения в С++ никто не отменял, да кидает
2) про конструктор ваще смешно, стандартное раскручивание стека. никакой утечки памяти не бует. уничтожатся все объекты, кторые успели создаться. это стандарт. не только для буста.
3) если хотите без исключений ставьте опцию компилятора без исключений
4) да, буст потоково безопасна. многопоточность можно отключить.

Сергей ИльичА если обобщенному классу A нужен обобщенный класс В, а обобщенному классу B нужен обобщенный класс A?
конкретно, что вы имеете ввиду. если речь о форвардных декларациях в шаблонах они возможны.

Сергей Ильич Но в MSVC так с шаблонами делать нельзя.
я не знаю кто вам нашептывает на ушко. дайте кнкретный код, я его скомпилирую в MSVC.

Сергей ИльичПочему бы и не поплодить. Ведь в Java есть пакеты. По крайней мере я 100% знаю, что мне в качестве параметра будут передавать org.sergey.ilyich.sql-forum-conversation.Listener, а не какую-то сигнатуру.
да вы имеет право плодить сущности ради бога, я вас по рукам не бью. Однако меня вы очень рьбъяно и принципиально обвиняли в плодении сущностей. вы чертовски придирчивы и непоследовательны в своих высказываниях. не применяте свои же методы оценки к своим же методам решения. это идеализация.

насчет свидетелей я не знаю таких. но вы просто стабильны в методах своих высказываний. на свои оговорки не смотрите ко мне придираетесь. плюсов о которых я говорю вы вообще не признаете путем игнорирования(см пример с "плодением сущностей"), как минусов с++. ляпнули что-то про книжку Александреску и отказались это объяснить. ушли просто убежали от обсуждения. не берете ответсвенность за слова. если я об этом буду молчать, останется только ваша ложь про с++. а ваши ассоциации - это ваши проблемы. меня они не волнуют.

итог - не одного трезвого аргумента против использования шаблонов.

Сергей ИльичЛямбда чтоли?
ну наверное, я понятия не имею что вы конкретно подразумеваете под этим словом. опять возвращаясь к вашему любимому критерию, который два поста назад был для вас принципиальным, а теперь вы его отторгнули. я о кол-ве сущностей. 8-) анонимные методы, тоже ИНОГДА удобный способ не плодить чего-то понапрасну.
...
Рейтинг: 0 / 0
C++ & Java
    #32848743
Dimitry Ivanov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZiv
Лишним доказательством этого является тот факт, что даже в Java в последнем JDK добавили шаблоны (в язык). Мотивайцией было именно это - чтобы иметь возможность хранить в коллекциях типизированные (ссылки на) объекты, а не абстрактные Object-ы.

Это не шаблоны. Совсем не шаблоны... я бы даже сказал ни разу не шаблоны... А жаль.
...
Рейтинг: 0 / 0
C++ & Java
    #32848806
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Достаточно восторженная статья о генериках в сравнении с шаблонами. без комментариев.
...
Рейтинг: 0 / 0
C++ & Java
    #32848815
Siebentearbeit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторЗачем нужны функции и методы? Почему не одни методы?
Не писал, видимо, никогда на сях.
В Яве ни одна функция не может существовать сама по себе.
В сях может, и это удобно, для классонезависимых приседаний.
Например у меня одной функцией сделана работа дебага, со статических хэндлом окна, статическим указателем на файл и статическими флагами. Мне тут класс нафиг никакой не нужен, чё бы кто там про концептуальность и прочее не говорил.

авторнадо же! только что собрал под MSVC 6. видимо мы живем в разных мирах.
Ну у меня буст тоже не соберётся под VC60, ибо не поставлен.

авторПро размер бинари - это тоже хороший вопрос. Мой пример займет несколько килобайт, твой - возможно несколько десятков или сотен килобайт.
Звиняйте, ваш код - код для интерпретатора, а не бинарник. И работать, не смотря на малость, будет дольше.

авторОй, пишут, гады, представляешь ? Пишут.
Да, я подозревал, что такие есть.
Они либо не умеют С.
Либо страшные приверженцы Явы.
Либо лучше держаться от них подальше - неясно, что у них на уме :)
...
Рейтинг: 0 / 0
C++ & Java
    #32848820
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
не удержусь. там, кстати, в качестве преимущества говорится, что дженерики явы будут нормально инстанцироваться для полиморфных типов. В С++ же нужно строгое соответсвие типам. Я не считаю это недостатком.

1) объекты в яве всегда по сути указатели на их место в куче. поэтому когда вы пишете в яве vector<MyObj>, то это по сути вектор указателей. Указатели в С++ обладают тем же свойством, т.е. возможность присвоения полиморфных объектов. неверно наверное выразился. За исключением канечно даункастинга. Вопрос: а нафига так смешивать две разные технологии? Их взаимодействие необходимо, они т.о. компенсируют недостатки друг друга и услиливают преимущества. Вобчем возможно есть какие-то приемы программирования, для которых такая возможность нужна. Буду рад если мне о них кто-нить расскажет.

2) если бы мы написали полиморфные классы. Т.е. класс имеющий виртуальные функции и имеющий потомков. Ну это я к примеру. Можно ли в С++ такой класс распологать в динамических массивах или контейнерах напрямую без указателей? Нет нельзя. Потому что размер объекта в этом случае может быть разный. Вобчем это давняя ошибка начинающих программеров. В таких случаях как раз хранят только указатели на объекты.

Сергей Ильич
пирмеры форвардинга шаблонов полно в инете. сегодня меня не будет, вернее буду только поздно вечером. поэтому в добавок к способам применения generic programming, могу привести достаточно удачный и удобный способ управления преобразованием типов.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
// вы знаете, что в С++ можно управлять преобразованием типов
struct ToBool{
 // свое преобразование типов
 operator bool();
}

struct NotToBool{
private:
 // запретить преобразования к bool
 operator bool();
}

class Single{
public:
 std::string text_;
 int tag_;
private:
 // запретить любые преобразования типов 
 template<class T>
 operator T();
}

нам не надо писать кучу операторов для всех возможных типов. Мы пишем один шаблонный метод обычного класса. И теперь на этапе компиляции все ошибки нерадивых пользователей библиотеки или наши собственные будут присекаться. А если учесть, что методы можно перекрывать, то можно рарешать преобразования только для ОДНОГО или НЕСКОЛЬКИХ типов. Для остальных запрещать.

вот вам еще один удобный способ применения шаблонов. до вечера.
...
Рейтинг: 0 / 0
C++ & Java
    #32848825
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Cергей Ильич
кстати насчет бинарника, могу свой пример откомпилировать и он будет занимать килобайт ну или чуть больше. могу на спор. только интересно как вы будете проверять.

между прочим это связано не с шаблонами а опциями линковщика. 8-)))
Распухание EXE из-за шаблонов это миф. Известно ли вам в кратце механизм инстанцирования шаблонов? Известно ли вам, что инстанцируются, т.е. компилируются только те методы которые вызываются, все остальное так и остается простым текстом программы. Т.е. если мы бы писали контейнер на Яве и с теми методами которые есть у std::vector и его итераторов, то класс получился бы толще, чем std::vector на С++ именно, потому что инстанцируется только то что мы используем.
...
Рейтинг: 0 / 0
C++ & Java
    #32848866
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl
2) про конструктор ваще смешно, стандартное раскручивание стека. никакой утечки памяти не бует. уничтожатся все объекты, кторые успели создаться. это стандарт. не только для буста.

Гнусная багофича MSVC - при возникновении исключения в конструкторе память, выделенная под объект, *не освобождается*.
"Не бросайте исключений в конструкторах" (С) Microsoft
Честно говоря, это очень хреново, посколько инициализация - это зона повышенного риска.
Если писать только пустые конструкторы, а инициализацию выносить в Init() или Create(), то я не смогу инициализировать const - поля класса. Без const полей мне не нужны const методы. Без const методов клиент моего кода сможет делать не то, что я от него ожидал.

dwl
3) если хотите без исключений ставьте опцию компилятора без исключений

Придется вестимо. А как буст будет мне сигналить об ошибках?

dwl
Сергей ИльичА если обобщенному классу A нужен обобщенный класс В, а обобщенному классу B нужен обобщенный класс A?
конкретно, что вы имеете ввиду. если речь о форвардных декларациях в шаблонах они возможны.

Пример - в студию

dwl
Сергей Ильич Но в MSVC так с шаблонами делать нельзя.
я не знаю кто вам нашептывает на ушко. дайте кнкретный код, я его скомпилирую в MSVC.

Масоны мне шепчут. Помню я писал на ATL/WTL, там из-за шаблонов нельзя было разделять предварительную декларацию и имплементацию классов. Я конкретно задолбался подбирать порядок инклюдов. Кроме того, длительность компиляции возрастала квадратично в зависимости от объема кода. Когда проект вырос до ~300Кб исх.кода, начали выскакивать Internal Compiler Error. Кроме того, я огреб огромный гиморрой, когда два класса хотели сущности перекрестно друг из друга.
Влом сейчас поднимать, что там было, но вот тривиальный вариант.

Код: 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.
#ifndef _A_INCLUDED
#define _A_INCLUDED

#include "B.hpp"

template<class T>
class A {
	const B<T> _b;
public:
	A()
		:_b(B<T>())
	{}
};

#endif

#ifndef _B_INCLUDED
#define _B_INCLUDED

#include "A.hpp"

template<class T>
class B {
	const A<T> _a;
public:
	B()
		:_a(A<T>())
	{}
};

#endif

dwl
Сергей ИльичПочему бы и не поплодить. Ведь в Java есть пакеты. По крайней мере я 100% знаю, что мне в качестве параметра будут передавать org.sergey.ilyich.sql-forum-conversation.Listener, а не метод с какую-то сигнатурой.
Однако меня вы очень рьбъяно и принципиально обвиняли в плодении сущностей.
Сущностей языка, а не программы. Пользуясь интерфейсами, я имею большую гранулярность контроля, и большую type safety org.sergey.ilyich.sql-forum-conversation.Listener это не какая-нибудь сигнатура.

dwl
Ляпнули что-то про книжку Александреску и отказались это объяснить. ушли просто убежали от обсуждения.

Пока появились компиляторы, пристойно это поддерживающие (я ксати не знаю, появились ли и насколько пристойно), я успел сделать пару проектиков, и мне теперь их надо поддерживать.

Сергей ИльичЛямбда чтоли?
ну наверное, я понятия не имею что вы конкретно подразумеваете под этим словом. опять возвращаясь к вашему любимому критерию, который два поста назад был для вас принципиальным, а теперь вы его отторгнули. я о кол-ве сущностей. 8-) анонимные методы, тоже ИНОГДА удобный способ не плодить чего-то понапрасну.
Лямбда исчисление Черча - это термин из середины прошлого века.
Ламбда - функциями называются анонимные функции в функциональных языках.
...
Рейтинг: 0 / 0
C++ & Java
    #32848871
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пардон, длинный пост, неправильно отцитировал
...
Рейтинг: 0 / 0
C++ & Java
    #32848943
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Siebentearbeit авторЗачем нужны функции и методы? Почему не одни методы?
Не писал, видимо, никогда на сях.
В Яве ни одна функция не может существовать сама по себе.
В сях может, и это удобно, для классонезависимых приседаний.
Например у меня одной функцией сделана работа дебага, со статических хэндлом окна, статическим указателем на файл и статическими флагами. Мне тут класс нафиг никакой не нужен, чё бы кто там про концептуальность и прочее не говорил.

Кто тебе в Яве мешает сделать статическую функцию? И свалить все статические поля в радом? Не будет в глобальном skope всякое шайзе бултхаться

Siebentearbeit
авторПро размер бинари - это тоже хороший вопрос. Мой пример займет несколько килобайт, твой - возможно несколько десятков или сотен килобайт.
Звиняйте, ваш код - код для интерпретатора, а не бинарник. И работать, не смотря на малость, будет дольше.

PE EXE - это тоже интерпретируемый код для ядра win32. Он тоже не чистый native.

Siebentearbeit
авторОй, пишут, гады, представляешь ? Пишут.
Да, я подозревал, что такие есть.
Они либо не умеют С.
Либо страшные приверженцы Явы.
Либо лучше держаться от них подальше - неясно, что у них на уме :)
Я вообще пишу server - side, НО кстати, в Яве грид для контролов сделан более по уму. Если в немецкой версии программы на кнопке вместо "Cancel" будет написано "Abbrechen", то пропорции в сетке будут пересчитаны, вместо того чтобы откусывать чего-то.
...
Рейтинг: 0 / 0
C++ & Java
    #32848983
alex_k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей Ильич
PE EXE - это тоже интерпретируемый код для ядра win32. Он тоже не чистый native.

разве так? думаю нет...
...
Рейтинг: 0 / 0
C++ & Java
    #32849003
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex_k Сергей Ильич
PE EXE - это тоже интерпретируемый код для ядра win32. Он тоже не чистый native.

разве так? думаю нет...
Загрузчик PE EXE конкретно готовит код для работы. Он как минимум распихивает куски кода по страницам, и меняет адреса переходов по спец. таблице.
JVM комиплирует программу по ходу ее работы.
Уровень абстракии разндый, это да.
...
Рейтинг: 0 / 0
C++ & Java
    #32849024
alex_k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
это может быть и интерпретируемый код для ядра win32, но эта работа выполняется на стадии загрузки процесса в память.
На мой взгляд это разные уровни абстракций разных сущностей. Всетаки загрузка процесса в память и исполнение процесса - это разные сущности.
...
Рейтинг: 0 / 0
C++ & Java
    #32849073
Sie
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Sie
Гость
авторНе будет в глобальном skope всякое шайзе бултхаться
Что все так боятся глобальных переменных и функций?
Что в них плохого?

авторPE EXE - это тоже интерпретируемый код для ядра win32. Он тоже не чистый native.
Это кто?
Стоп, может я чё-то недопонимаю...
Вот в VC я собираю ехе-шник, он грузится в память по кускам и выполняется, как есть.
В Java я собираю class. Они разбирается машиной, и ей же выполняется.
(зато на разных(вроде) платформах) Но медленнее, чем родной код.
Поэтому я и говорю, что на яве писать виндовые апликухи - странно. А ещё использовать какой-нить свинг.. это вообще капец...(как я, когда был глупый и писал апплет,.. потом переписывал на стандарнтных, переделанных мной, контролах)

авторНО кстати, в Яве грид для контролов сделан более по уму.
В яве в стандартных контролах нету грида.

оффтоп: Как-то, однажды, тоже писал гр.интерфейс под немецкий язык :)
...
Рейтинг: 0 / 0
C++ & Java
    #32850564
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Cергей ИльичГнусная багофича MSVC - при возникновении исключения в конструкторе память, выделенная под объект, *не освобождается*.
"Не бросайте исключений в конструкторах" (С) Microsoft
специально запустил это на шестерке
Код: 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.
#include "stdafx.h"

struct A{
    A()  { printf("A construct\n"); }
    ~A() { printf("A destruct\n"); }
};

struct B{
    B()  { printf("B raise\n"); *static_cast<char*>( 0 )= 0 ; }
    ~B() { printf("B destruct\n"); }
};

struct C{
    A a_;
    B b_;

    C() : a_(), b_() { printf("C construct\n"); }
    ~C() { printf("C destruct\n"); }
};

int main(int argc, char* argv[])
{
   C c;
   return  0 ;
}

//выводит на экран
A construct
B raise
A destruct
шайтан!


Cергей ИльичПример - в студию
Код: plaintext
template<typename T> class my_forward;
существует еще ключевое поле export, которое эмулирует раздельную компиляцию шаблонов. Т.е. мы можем не юзать export а просто писать декларацию шаблона в хидере, а в модуле который инклудит этот хидер писать реализацию. Однако если надо перенести декларацию в глобальный хидер, который инклудится в модуль инстанцирующий класс. А реализацию юзать в совсем другом модуле, тогда лучше юзать export. Только мне ближе первый способ. Без export.


Cергей ИльичМасоны мне шепчут. Помню я писал на ATL/WTL, там из-за шаблонов нельзя было разделять предварительную декларацию и имплементацию классов.
вот ведь коварные какие масоны!
Код: 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.
// файл test.h
#ifndef _TEST_
#define _TEST_

template< typename T >
struct Templ{
    T t_;
    T get_value() const;
};

#endif /* _TEST_ */

// файло test.cpp
#include "stdafx.h"
#include "test.h"

template< typename T >
T Templ<T>::get_value() const{
    return t_;
};

int _tmain(int argc, _TCHAR* argv[])
{
    Templ<int> t;
    return  0 ;
}
от зараза! компилируется и инстанцируется.

теперь о перекрестном форвардинге. Чтобы проинстанцировать шаблон должны быть известны все типы и значения переменных и функций, на которых он собирается. Поэтому в некоторых случаях можно и придется явно проинстанцировать шаблон полностью. Только это очень плохо. Не стоит забывать что ООП, и generic это разные технологии. Прнименять один и тот же подход к обеим нельзя. Как например глупо писать массив нетипизированных указателей, когда можно определить шаблон контейнера. Форвардная декларция нужны для независимости от реализации типа, а привязки только к интерфейсу например. что ж в шаблонах это лучше делать так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
template<class T, template<class U> BT>
class A {
const BT<T> _b;
public:
// конструктор сам сгенерится
// да и написан он был неправильно
// создавался временный объект типа B<T> в стеке
// а потом только вызывался копирующий конструктор
// после чего вызывался деструктор временного объекта
// нахрена такие сложности???
};

именно этот прием используется в большинстве библиотек. Хотя на самом деле можно обойтись вложенными типами, по аналогии с итераторами. Реализация итератора зависит от реализации контейнера, поэтому класс инкапслуриуется внутрь контейнера. Так меньше сложностей. Так что в случае с шаблонами, т.к. это все таки другая технология, перкрестных ссылок можно избежать. Хотя повторюсь форвардная декларация как шаблона класса так и шаблона функции ВОЗМОЖНА . пример выше на два примера.


Cергей ИльичСущностей языка, а не программы. Пользуясь интерфейсами, я имею большую гранулярность контроля, и большую type safety org.sergey.ilyich.sql-forum-conversation.Listener это не какая-нибудь сигнатура.
А вот это увы голословность. А точнее просто вода. Не может массив Object* быть безопасней (да и вообще безопасным), чем vector<T>. Это очевидно из определений. Динамический полиморфизм ограничен рамками определенного интерфейса, т.е. он bounded и dynamic. bounded, как раз и означает ограничение по интерфейсам для типов участвующих в полиморфизме. Чтобы с этим "бороться" приходится повторно переписывать и копировать тот или иной код, или прибегать к НЕБЕЗОПАСНЫМ преобразованиям типов. Ну и наконец само связывание происходит динамически то есть на этапе ВЫПОЛНЕНИЯ ПРОГРАММЫ. Т.е. многие ошибки программиста при работе с интерфейсом будут вылетать только на этапе выполнения программы. Вот уж что нечитабельно так это AV.

но у такого подхода есть приемущества, как то меньший размер кода и нет необходимости в исходниках для предоставления библиотечных функций.

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

Связывание типов, которое происходит на этапе компиляции ПО ОПРЕДЕЛЕНИЮ более надежно, чем СВЯЗЫВАНИЕ НА ЭТАПЕ ВЫПОЛНЕНИЯ. Недостаток статического связывания напрямую зависит от программиста. Потому что семантика(алгоритмика) обощенных классов может быть перврана. Например определить оператор<< как операцию сложения, а оператор+ как вывод в поток. такие сдвиги по фазе не определяются компилятором.

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

Cергей ИльичПока появились компиляторы, пристойно это поддерживающие (я ксати не знаю, появились ли и насколько пристойно), я успел сделать пару проектиков, и мне теперь их надо поддерживать.
рад за вас. Но это ИМХО не дает вам право выдавать такие обощения как книга Александреску не имеет никакого пракитческого применения ну или пользы. В просто мели все одну гребенку.

Cергей ИльичЛямбда исчисление Черча - это термин из середины прошлого века.
Ламбда - функциями называются анонимные функции в функциональных языках.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
// плейс холдеры
list<int> v( 10 );
// заполняем адыницами
for_each(v.begin(), v.end(), _1 =  1 );
vector<int*> vp( 10 ); 
// заполняем указателями
transform(v.begin(), v.end(), vp.begin(), &_1);
// уловие сортировки
sort(vp.begin(), vp.end(), *_1 > *_2);
// вывод в консоль
for_each(vp.begin(), vp.end(), cout << *_1 << '\n');
// немного красявостей
for_each(v.begin(), v.end(), cout << ++var(index) << ':' << _1 << '\n');

// условия
for_each(a.begin(), a.end(), 
         if_then(_1 %  2  ==  0 , cout << _1)); 
ну и т.д. в некоторых простейших ситуациях проще использовать такие анонимные штучки. удобно.
...
Рейтинг: 0 / 0
C++ & Java
    #32850574
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Отдельным постом отвечу насчет Не увеличений сущностей языка .

Итак, бросаем на весы. ВЕСЫ МЕРЯЮТ ВРЕД И ПОЛЬЗУ только в ПЛАНЕ добавления и убавления сущностей языка. Что у нас добавляется:
1) шаблоны, а точнее технология статического полиморфизма, ну или связывания, как вам удобней. Это технология работает на обычном наборе УЖЕ ИМЕЮЩИХСЯ сущностей ЯП. ДОпустим это у нас в недостатки пойдет. Как вред в плане увелечения сущностей языка.
(ох как я не люблю философское бла-бла)

другая чаша весов. Чтобы мы получаем взамен из плюсов
1) большую безопасность типов. Статическое связывание дает большую безопасность, чем связывание во время выполнеия программы (виртуальные функции интерфейса или преобразование типов)

2) Большой запас прочности языка в плане востребованности других сущностей. Например, тип variant добавляется в некоторых языках, С++ не имеет такой необходимости, потому что такой тип реализуется посредством шаблонов, см. boost::any и boost::variant, который обходит ограничение на union+POD. Другой пример, проперти. Та же история, другие языки вынуждены добавлять новые ключевые слова, т.е преумножать сущности. проперти элементарно реализуются посредоством шаблонов, см. boost::poperty. Еще один пример, некоторые языки видя успех и преимущество контейнеров STL, добавляют новую структуру данных - динамические массивы, опять же преумножая сущности языка. Двигаемся дальше, делегаты - используя шаблоны реализуется даже более лучший(безопасный) и гибкий класс - boost::signal. Далее, анонимные функции. Далее, сборщик мусора. Т.е. создавая что-то одно (generic programming) мы избавляем язык от необходимости добавлять новые сущности.

3) Генерация более быстрого кода. Единственный язык, на котором при помощи шаблонов выражений (см. простейший пример std::valarray) была создана библиотека (матричные вычисления) более быстрая по скорости, чем аналогичная на фортране, которая держала короную многие десятки лет. Причем здесь сущности? Дело в том что другие языки, созданные для безопасного кода, чтобы получить какое-то ускорение добавляют в язык возможность написания ОПАСНОГО кода. Пример, unsafe и fixed в C#. Т.е. увеличивают кол-во сущностей языка.

Весы явно перевешивают в сторону положительных моментов Статического Связывания.
...
Рейтинг: 0 / 0
C++ & Java
    #32850581
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Добавочный короткий пост. уже запутался в длинных и мелких ПРИДИРКАХ к С++ от поклонника ИДЕАЛЬНОГО ЯЗЫК ЛИШЕННОГО НЕДОСТАТОКОВ.

Сергей ИльичБез const полей мне не нужны const методы.
ну у вас странное понимание относительно конст методов.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
class Array{
 int* p_;
 int cnt_;
public:
 Array( int sz ) : p_(new int[sz]), cnt_(sz) {}
 ~Array();
 int Count() const { return cnt_; }
}
вот вам и const метод без const членов. Нет если хотите используйте конст члены в этом случае, в С++ это можно и с кнгструкторами никаких проблем, как я показал в предыдущем посте.

Сергей ИльичПридется вестимо. А как буст будет мне сигналить об ошибках?
А зачем вам надо было отключать исключения? Вы спросили я ответил. Вы еще спросите, а можно что-то записать на нулевой адрес? и что тогда будет?

Вобчем народ! всех с НАСТУПАЮЩИМ праздником. у меня лично начались праздничные хлопоты, чего и вам желаю. Это лучше чем лаяться на форумах и сидеть у компа.

До после НОВОГО ГОДА, коллеги!
...
Рейтинг: 0 / 0
C++ & Java
    #32850757
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
las PS 8-)

подробнее о перекрестных форвардных объявлениях для шаблоннов можно почитать
здесь
...
Рейтинг: 0 / 0
C++ & Java
    #32851668
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl Cергей ИльичГнусная багофича MSVC - при возникновении исключения в конструкторе память, выделенная под объект, *не освобождается*.
"Не бросайте исключений в конструкторах" (С) Microsoft
специально запустил это на шестерке
Код: plaintext
1.
2.
3.
4.
5.
int main(int argc, char* argv[])
{
   C c;
   return  0 ;
}
шайтан!

Ты его в стеке, а не в куче создаешь.

dwl
Cергей ИльичПример - в студию
Код: plaintext
template<typename T> class my_forward;
Только мне ближе первый способ. Без export.

Ну и куда мне это пихать? В модуль - клиент, модуль - сервер, может быть между инклюдов куда - нибудь?

dwl
Cергей ИльичМасоны мне шепчут. Помню я писал на ATL/WTL, там из-за шаблонов нельзя было разделять предварительную декларацию и имплементацию классов.
вот ведь коварные какие масоны!
Код: plaintext
1.
// {--SKIP--}
от зараза! компилируется и инстанцируется.

Не удивил. Это вещь в себе. Компилятор начинает компилировать cpp файл,
с помошью препроцессора втыкает в середину hpp файл, и получается один плоский файл,
который ему надо скомпилировать.
Когда он начнет компилировать другой cpp файл, он забудет про реализацию из первого cpp.

dwl
Хотя на самом деле можно обойтись вложенными типами, по аналогии с итераторами. Реализация итератора зависит от реализации контейнера, поэтому класс инкапслуриуется внутрь контейнера. Так меньше сложностей. Так что в случае с шаблонами, т.к. это все таки другая технология, перкрестных ссылок можно избежать. Хотя повторюсь форвардная декларация как шаблона класса так и шаблона функции ВОЗМОЖНА . пример выше на два примера.

Кстати, в Java вложенные классы имеют доступ с переменным охватывающего класса, в контексте которого они порождены.
Внутренние типы в стиле C++ в Java известны как "статические внутренние классы",
т.е не имеющие доступ к охватывающему классу.

dwl
Cергей ИльичСущностей языка, а не программы. Пользуясь интерфейсами, я имею большую гранулярность контроля, и большую type safety org.sergey.ilyich.sql-forum-conversation.Listener это не какая-нибудь сигнатура.
А вот это увы голословность. А точнее просто вода.
Не может массив Object* быть безопасней (да и вообще безопасным),
чем vector<T>. Это очевидно из определений. Динамический полиморфизм ограничен
рамками определенного интерфейса, т.е. он bounded и dynamic.

Вышеприведенный пример с Notification Broadcaster вполне можно запихать в класс,
и повторно использовать сколько угодно раз, воспользовавшись агрегированием и Decorator design pattern.

Про большую безопасность не надо - уж сколько слез я вижу в нашей столовой
"Ой, у нас Protection fault выскакивает раз в 4 часа, и повторить условия мы не можем".
Хотя, нам наверное dwl'а не хватает, чтобы он пришел и все разрулил.

В Java подобные ошибки бывают, согласен, но все таки они не связаны с памятью,
а поэтому втречаются намного реже.
Какая-нибудь гнилая third-party библиотека, которую нам навязывает заказчик, пытается подключится к базе,
и после таймаута возвращает null pointer, который передается другой гнилой библиотеке,
которая куда-то его записывает. Причем этот тайм-аут там hardcoded.

dwl
Связывание типов, которое происходит на этапе компиляции ПО ОПРЕДЕЛЕНИЮ более надежно,
чем СВЯЗЫВАНИЕ НА ЭТАПЕ ВЫПОЛНЕНИЯ. Недостаток статического связывания напрямую зависит
от программиста. Потому что семантика(алгоритмика) обощенных классов может быть перврана.
Например определить оператор<< как операцию сложения, а оператор+ как вывод в поток.
такие сдвиги по фазе не определяются компилятором.

В Java проверка соответствию типов осуществляется в процессе компиляции.
Нормальные люди выставляют наружу (в public методах) специализированные интерфейсы.
Есть утилиты типа checkstyle, которые анализируют код проекта, и сигналят, когда кто-то
злоупотребляет типом Object, либо используют вместо функциональных интерфейсов конкретные типы.
В С++, кстати, подобных утилит я не видел. Наверное, сложно все это проанализировать.

Кстати, давно хотел спросить - спецификации исключений (throw) являются в С++
частью сигнатуры функции или не являются?

dwl
Cергей ИльичЛямбда исчисление Черча - это термин из середины прошлого века.
Ламбда - функциями называются анонимные функции в функциональных языках.
Код: plaintext
1.
//{--SKIP--}
ну и т.д. в некоторых простейших ситуациях проще использовать такие анонимные штучки. удобно.
А смысл? В Лиспе или OCaml это будет более к месту.
Программу на OCaml кстати, можно статически скомпилировать в машинный код, и язык этот строго типизирован.
Там, кстати, нет уборки мусора, но управление памятью там сделано более по уму.
Я, конечно, не агитирую за OcaML, но для общего развития полезно посмотреть этот язык. Чтобы сравнить.
dwl
уже запутался в длинных и мелких ПРИДИРКАХ к С++ от поклонника ИДЕАЛЬНОГО ЯЗЫК ЛИШЕННОГО НЕДОСТАТОКОВ.

А чего - адвокаты в судах свято верят в невиновность своих подзащитых? Я не поклонник Джавы.
Я просто знаю, что когда я пишу на Джаве, я встречаю намного меньше препятствий.

dwl
Сергей ИльичПридется вестимо. А как буст будет мне сигналить об ошибках?
А зачем вам надо было отключать исключения? Вы спросили я ответил.
Вы еще спросите, а можно что-то записать на нулевой адрес? и что тогда будет?

Потому что исключения в С++ сделаны через жопу.
...
Рейтинг: 0 / 0
C++ & Java
    #32851744
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sie
авторНО кстати, в Яве грид для контролов сделан более по уму.
В яве в стандартных контролах нету грида.
А как же GridBagLayout, SpringLayout etc? Кстати, почему в С++ нет дефолтовой GUI библиотеки?
...
Рейтинг: 0 / 0
C++ & Java
    #32851759
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а есть хоть одна операционная система, написанная на Java?
...
Рейтинг: 0 / 0
C++ & Java
    #32851774
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gardenmanа есть хоть одна операционная система, написанная на Java?
Не знаю. Может Symbian. Кстати, на С++ - тоже нет. Линукс написан на С, Винда написана на ASM + C + MS vision of C++.
Кстати, из постов видно, что я не ненавистник С++, просто я к этому языку реалистично отношусь.
Я придерживаюсь того стиля, который мне библиотеки навязывают. Я библитеки в основном от MS
...
Рейтинг: 0 / 0
C++ & Java
    #32851845
J--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
J--
Гость
а JavaOS разве не на Java была написана?
...
Рейтинг: 0 / 0
C++ & Java
    #32852636
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Сергей ИльичТы его в стеке, а не в куче создаешь.
Во-первых не вижу необходимости лишний раз создавать объекты в куче - это вам не Ява. Но раз уж дело пошло на принцип...
Код: 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.
class One{
	int i_;
public:
	One() : i_( 0 ) { printf("construct One;\n"); }
	~One() { printf("destruct One;\n"); }
};

class Two{
	int i_;
public:
	Two() : i_( 0 ) { printf("raise Two;\n"); *static_cast<char*>( 0 )= 0 ; }
};

struct Three1{
	One one_;
	Two two_;

	Three1() : one_(), two_() {}
};

struct Three2{
	std::auto_ptr<One> one_;
	std::auto_ptr<Two> two_;

	Three2() : one_(new One), two_(new Two) {}
};

int main()
{
  // нужное раскоментарить
  //Three1* t1( new Three1 );
  //Three2 *t2( new Three2 );
    
  return  0 ;
}
Вот ведь! во всех случаях вызывается нужная последовательность конструктор-деструктор. Кстати, в случае с Three2 я бы ваще написал const auto_ptr, тогда все попытки присовить этот указатель пресекались бы компилером. Если это канеш надо разработчику.

Сергей ИльичКогда он начнет компилировать другой cpp файл, он забудет про реализацию из первого cpp.
не вижу смысла размазывать реализацию ОДНОГО класса по нескольким CPP модулям - это плохой стиль.

Сергей ИльичВышеприведенный пример с Notification Broadcaster вполне можно запихать в класс, и повторно использовать сколько угодно раз, воспользовавшись агрегированием и Decorator design pattern.
вряд ли. Вернее так:
1) класс, как я неоднократно говорил создавался для списка callback функций. Ты оный кстати так и не представил нашему вниманию
2) в крайнем случае я просил показать как ты будешь сравнивать два объекта одного класса в твоем случае.
3) твой нотификатор работает только для одного типа методов. Для статической функции или просто функции тебе придется объявлять новый тип.
4) декоратор декоратором, один хрен - ПЛЮС новый тип, ПЛЮС преобразование типов, лио явное, либо через полиморфизм. Т.е. опять познее связывание.

Вобчем как не крути все равно проигрышь.

Сергей ИльичПро большую безопасность не надо - уж сколько слез я вижу в нашей столовой "Ой, у нас Protection fault выскакивает раз в 4 часа, и повторить условия мы не можем". Хотя, нам наверное dwl'а не хватает, чтобы он пришел и все разрулил.
ну теперь ясна природа твоей ненависти к С++. Ты смотришь, как на нем неправильно пишут другие. ясненько. Это весьма типично.

Сергей ИльичВ Java проверка соответствию типов осуществляется в процессе компиляции.
замучился я повторять. Напиши контейнер для любого типа данных и ты увидишь, КОГДА ЯВА НЕ ПРОВЕРЯТ БЕЗОПАСНОСТЬ ТИПОВ. Эти случаи достаточно часты в больших проектах. Это по моему опыту.

Сергей ИльичКстати, давно хотел спросить - спецификации исключений (throw) являются в С++ частью сигнатуры функции или не являются?
дома у меня нет стандарта, на память - ИМХОт не является. Это что каверзный вопрос из разряда - АГА ОН НЕ ЗНАЕТ С++ настолько чтобы о нем судить? Да я и не говорил что я знаю С++ хорошо. Мне приятно перечитывать книги по нему(некоторые) и узнавать каждый раз что-то новое.

Сергей ИльичЯ просто знаю, что когда я пишу на Джаве, я встречаю намного меньше препятствий.
Это бессмыслено обсуждать. Я уже говорил, что у каждого специалиста в своей области выработаны свои привычки и технологии. Это как например взять посадить программиста MSSQL на ORACLE. ОН достаточно скоро его обругает и скажет что ORACLE плохая система. И это будет НЕВЕРНО.

Сергей ИльичПотому что исключения в С++ сделаны через жопу.
Опять обощения можно по конкретней?
...
Рейтинг: 0 / 0
C++ & Java
    #32853135
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl Сергей ИльичТы его в стеке, а не в куче создаешь.
Во-первых не вижу необходимости лишний раз создавать объекты в куче - это вам не Ява.

Как в Яве, так и в С++ надо отдавать предпочтение долгоживущим объектам.
Неплохо использовать Singleton, или какой-нибудь пул объектов.
А создать долгоживущий объект в стеке несколько проблематично.

dwl
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
// {--SKIP--}
int main()
{
  // нужное раскоментарить
  //Three1* t1( new Three1 );
  //Three2 *t2( new Three2 );
    
  return  0 ;
}
Вот ведь! во всех случаях вызывается нужная последовательность конструктор-деструктор.

Меня интересует не факт вызова деструкторов, а факт вызова ::operator delete(...) под адрес,
который вернул ::operator new(...), когда его попросили выделить память для помещения туда Three1 / Three2.

MSDN
Throwing an exception in a constructor is tricky, however, because the memory for the object
itself has already been allocated by the time the constructor is called. There is no simple
way to deallocate the memory occupied by the object from within the constructor for that object.
Thus, you will find that throwing an exception in a constructor will result in the object remaining
allocated. For a discussion of how to detect objects in your program that have not been deallocated,
see the article Diagnostics: Detecting Memory Leaks.


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

dwl
Сергей ИльичКогда он начнет компилировать другой cpp файл, он забудет про реализацию из первого cpp.
не вижу смысла размазывать реализацию ОДНОГО класса по нескольким CPP модулям - это плохой стиль.

Я не о размазывании реализации класса, а о том, что эта реализация может понадобиться для компиляции
других модулей проекта. НО компилятор ее не будет иметь, поскольку он про нее забыл, когда взял другой cpp файл.

dwl
1) класс, как я неоднократно говорил создавался для списка callback функций. Ты оный кстати так и не представил нашему вниманию

Поразительная твердолобость. Нету в Java callback функций, ибо не нужны они.
Есть java.lang.reflect.Method, который можно использовать для вызова любого метода из любого класса,
но он используется только для системного программирование под JVM.
И в С++ они не нужны, я лично использую интерфейсы + (множественное наследование или внутренние классы),
то есть тот же подход.
std::vector<INotificationHandler*> в сто раз гибче и понятней.
И не требует буст. И не требует небезопасного приведения типов.
И такой сущности, как "Указатель на виртуальный метод класса"
нету в С++ (может к счастью? напридумывали бы извратов с этим).
dwl
2) в крайнем случае я просил показать как ты будешь сравнивать два объекта одного класса в твоем случае.

Что такое "сравнивание двух объектов одного класса в моем случае"?
Любой класс в Яве наследует от Object метод equals, который можно перегрузить. Ты про это?
dwl
3) твой нотификатор работает только для одного типа методов. Для статической функции или просто функции тебе придется объявлять новый тип.

Это я вообще не понял. Ты видишь сложности там, где их нет.

dwl
Сергей ИльичПро большую безопасность не надо - уж сколько слез я вижу в нашей столовой "Ой, у нас Protection fault выскакивает раз в 4 часа, и повторить условия мы не можем". Хотя, нам наверное dwl'а не хватает, чтобы он пришел и все разрулил.
ну теперь ясна природа твоей ненависти к С++. Ты смотришь, как на нем неправильно пишут другие. ясненько. Это весьма типично.

Я не люблю апеллировать к чужим авторитетам, как попы или моралисты.
Скажу лишь, что во-первых стоимость специалиста - это очень немаловажный фактор.
А у нас многие ребята - выпускники ИТМО и СПбГУ.
А во-вторых, если какой-то человек может видеть многомерную структуру ньюансов С++,
но при этом проект-лидер и коллеги по бригаде никак не могут достучаться до внутреннего
мира такого человека, это очень плохо.

Если по-твоему "реалистичное отношение к С++" это ненависть, то ненавистник - это как раз ты.
По - моему реалистичное отношение к С++ это "Самый распространенный компилируемый язык программирования,
доступный на Win и UNIX, доступно много библиотек из первоисточника, требует колоссальных усилий для
написания даже простой программы, но выбора зачастую нет."

dwl
Сергей ИльичВ Java проверка соответствию типов осуществляется в процессе компиляции.
замучился я повторять. Напиши контейнер для любого типа данных и ты увидишь,
КОГДА ЯВА НЕ ПРОВЕРЯТ БЕЗОПАСНОСТЬ ТИПОВ. Эти случаи достаточно часты в больших проектах. Это по моему опыту.

А я замучался отвечать, что в Яве никто не выставляет внутренние коллекции класса в public - доступ.
А public API классов не дает права передавать в качестве параметров объекты любых типов.
Тут кто-то заявил, что NullPointerException - это bane Ява - программирования.
Он на 3-5% прав, поскольку такие ошибки иногда бывают во врема билдов, когда какие-то
модули не срастаются.
С BadCastException мне почему-то не приходилось сталкиваться. Ни разу.

dwl
Сергей ИльичКстати, давно хотел спросить - спецификации исключений (throw) являются в С++ частью сигнатуры функции или не являются?
Это что каверзный вопрос из разряда - АГА ОН НЕ ЗНАЕТ С++ настолько чтобы о нем судить? Да я и не говорил что я знаю С++ хорошо. Мне приятно перечитывать книги по нему(некоторые) и узнавать каждый раз что-то новое.

Вообще это твой стиль - сыпать какими-то терминами типа "мультиметод, функтор, абстрактная фабрика, политика etc"
и чего-то ждать.
Я лишь интересовался безопасностью типов в коллекции callback функций.
надо ли каждый вызов метода из этой коллекции оборачивать в
Код: plaintext
1.
2.
3.
4.
5.
try {
  //...
} catch (...) {

}

чтобы не словить unexpected()

dwl
Сергей ИльичЯ просто знаю, что когда я пишу на Джаве, я встречаю намного меньше препятствий.
Это бессмыслено обсуждать. Я уже говорил, что у каждого специалиста в своей области выработаны свои привычки и технологии. Это как например взять посадить программиста MSSQL на ORACLE. ОН достаточно скоро его обругает и скажет что ORACLE плохая система. И это будет НЕВЕРНО.

Ситуация обратная. Полгода назад перешел на Яву, и до сих пор не могу привыкнуть к отсутствию непонятных глюков
и к удобочитаемым сообщениям компилятора. И что программа ведет себя сразу так, как я задумывал.

dwl
Сергей ИльичПотому что исключения в С++ сделаны через жопу.
Опять обощения можно по конкретней?
Посмотри, как экзепшены сделаны в Java и сравни. Там есть checked и uncheсked исключения.
Про finally я вообще не вижу смысла с тобой разговаривать: у тебя наверное один критерий
- если Строуструп сказал, что finally - это зло, значит это зло.
...
Рейтинг: 0 / 0
C++ & Java
    #32853224
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Сергей ИльичКак в Яве, так и в С++ надо отдавать предпочтение долгоживущим объектам.
Не во всех ситуациях. Например, локальные переменные. Все зависит от контекста. Не стоит думать, что во всех случаях можно обойтись только стековым размещением или только "кучным". Каждому свое.

Сергей ИльичМеня интересует не факт вызова деструкторов, а факт вызова ::operator delete(...) под адрес, который вернул ::operator new(...), когда его попросили выделить память для помещения туда Three1 / Three2.
Освобождение памяти в этом случае гарантируется. Оно не гарантируется только в двух случаях:
1) буфирезированные оператор размещения new (buf) A;
2) и если перекрыт оператор new, но не перекрыт оператор delete
Во всех остальных случаях происходит освобождение памяти.

Сергей Ильичstd::vector<INotificationHandler*> в сто раз гибче и понятней. Это ваше ИМХО. Речь идет о том, что в этом случае идет проверка типов на этапе выполнения, а не на этапе компиляции. Например вы захотите присвоит в этот контейнер объект другого типа. ТО в этом случае будет либо неявное(если они родственники) либо явное преобразование типов. Которое не может быть выполнено на этапе компиляции.

Просто посмотрите на generic programming как на еще один прием повторного использования кода. Однотипные дествия над типами объединяются в функции или структуры, которые связываются с конркетными типами на этапе компиляции. Проверка производится компилятором. Это лучше чем преобразование типов.

Сергей ИльичЛюбой класс в Яве наследует от Object метод equals, который можно перегрузить. Ты про это?
да я про это. Допустим у тебя есть контейнер или просто два объекта которые по сути являются ну например пользовательскими обработчиками событий. Тебе надо их сравнить. Например, мы имеем некоторый список "обработчиков", которые заполняет программа для этого объекта, чтобы потом их вызвать. Чуть позже один из обработчиков надо удалить.

Сергей ИльичЭто я вообще не понял. Ты видишь сложности там, где их нет.Я не говорю что это сложно. Я лишь хотел показать, что имея тип Функтор, в котором реализованы все необходимые действия, нам не надо его переписывать для разных типов функций, которых он оборачивает. нам не надо копировать код. И нам не надо прибегать к преобразованиям типов или другим седствам познего связывания.


Сергей ИльичПо - моему реалистичное отношение к С++ это "Самый распространенный компилируемый язык программирования, доступный на Win и UNIX, доступно много библиотек из первоисточника, требует колоссальных усилий для написания даже простой программы, но выбора зачастую нет." я так не считаю. Хотя это канеш мое ИМХО. Здесь все упирается в наличие той или иной билиотеки для написания какой-то конркетной задачи. Например, мне жутко не нравится подход MFC. Поэтому приходилось юзать что-то другое. Наличие готовых решений - это сильное преимущество и большой плюс в выборе какого-либо инструмента разработки.

Сергей ИльичА public API классов не дает права передавать в качестве параметров объекты любых типов.Еще раз хочу проевить свою твердолобость. Все дело в повторном использовании кода. Допустим нам надо написать некий класс, например, контейнер. У него есть ряд стандартных действий по динамическому распределению объектов и управлению доступом к ним. И я, например, хочу, чтобы мне не приходилось писать каждый раз код этого класса для разных типов хранимых объектов. Если я не использую шаблоны, то мне придется указатель на некий базовый объект, и путем преобразования типов получать доступ к его членам или методам. В случае шаблонов не надо ни копировать исходники, не нужны преобразования типов. Я просто подставляю нужный тип и все. Это просто безопасное повторное использование кода.

Сергей ИльичЯ лишь интересовался безопасностью типов в коллекции callback функций. надо ли каждый вызов метода из этой коллекции оборачивать в нет не надо. Насчет терминов. Извини что не дал определения этих понятий. Просто я подумал, что человек, который прочел книгу Александреску и сказал что она фуфло знает смысл этих терминов. Именно в ней дается определение этих понятий, а точнее приемов программирования. И упомянул я их только в качестве вопроса тебе, как прочитавшему книгу Александреску.

Сергей ИльичСитуация обратная. Полгода назад перешел на Яву, и до сих пор не могу привыкнуть к отсутствию непонятных глюков и к удобочитаемым сообщениям компилятора. И что программа ведет себя сразу так, как я задумывал.
ну и отлично. У меня есть друг, который разработал свою систему распознования почерка на С++. Сейчас ее собирается продавать. У него тоже все работает без проблем. Никаких утечек памяти. А у него там очень большие структуры данных, которые часто реорганизуются тем или иным способом.

Ничего не имею против Явы, о чем постоянно говорил в постах. Я лишь ПОПЫТАЛСЯ упомянуть о разнице в приемах разработки generic programming и ООП (т.к. вопрос изначально был почти именно про это). О том, что дает первое. И что оптимально использовать их вместе. И я не являюсь единственным аппологетом того, что эта технология имеет право на жизнь. Это стали понимать и разработчики компиляторов. И шаблоны стали появляться и в Яве и в C#.
...
Рейтинг: 0 / 0
C++ & Java
    #32853264
Lepsik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей Ильич
Как в Яве, так и в С++ надо отдавать предпочтение долгоживущим объектам.
Неплохо использовать Singleton, или какой-нибудь пул объектов.
А создать долгоживущий объект в стеке несколько проблематично.

Вообще это твой стиль - сыпать какими-то терминами типа "мультиметод, функтор, абстрактная фабрика, политика etc"



почитав ваши диалоги у меня большие сомнения в том что вы писали что-то серьезнее чем Hello world на С++. Извините, вы просто не владеете предметом.

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


Не ошибусь, если скажу что 90% софта на вашем компьютере написано на С++. Все серьезные и большие компании коробочный софт делают только на С++. Купить что-то на Java приактически не возможно - потому как почти всегда требуется тех саппорт.
Производительность вообще смех какой-то.
Поставил Office написанный на Java - Copy/Paste из IE в редактор на P4 заняло 2 минуты !

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


вы о чем ? что такое конструирование ?

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


мы занимаемся моделирование и расчеты ведутся сутками с трехмерными кубами со стороной 10000 элементов. Даже и мысли не было сделать на JAva потому как производительность будет мама не горюй.

dwl
не вижу смысла размазывать реализацию ОДНОГО класса по нескольким CPP модулям - это плохой стиль.


иногда бывает нужно. Когда реализация класса превышает 1-1.5 тыс. строк - стараюсь разделить функциональность. Скажем класс основного приложения у меня в текущем проекте превышает 10 тыс. строк.

Сергей ИльичПро большую безопасность не надо - уж сколько слез я вижу в нашей столовой "Ой, у нас Protection fault выскакивает раз в 4 часа, и повторить условия мы не можем". Хотя, нам наверное dwl'а не хватает, чтобы он пришел и все разрулил.

вам просто нужно найти профессионалов.

---А у нас многие ребята - выпускники ИТМО и СПбГУ.

дилетанты бывают в любой среде

Сергей Ильич
А во-вторых, если какой-то человек может видеть многомерную структуру ньюансов С++, но при этом проект-лидер и коллеги по бригаде никак не могут достучаться до внутреннего мира такого человека, это очень плохо.


для этого есть корпоративное полиси написания кода


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

может не умеете ими пользоваться ?
...
Рейтинг: 0 / 0
C++ & Java
    #32854472
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl
Сергей ИльичМеня интересует не факт вызова деструкторов, а факт вызова ::operator delete(...) под адрес, который вернул ::operator new(...), когда его попросили выделить память для помещения туда Three1 / Three2.
Освобождение памяти в этом случае гарантируется. Оно не гарантируется только в двух случаях:
1) буфирезированные оператор размещения new (buf) A;
2) и если перекрыт оператор new, но не перекрыт оператор delete
Во всех остальных случаях происходит освобождение памяти.

Кем гарантируется ? Стандартом или конкретным компилятором ?

dwl
Сергей Ильичstd::vector<INotificationHandler*> в сто раз гибче и понятней.
Это ваше ИМХО. Речь идет о том, что в этом случае идет проверка типов на этапе выполнения,
а не на этапе компиляции. Например вы захотите присвоит в этот контейнер объект другого типа.
ТО в этом случае будет либо неявное(если они родственники) либо явное преобразование типов.
Которое не может быть выполнено на этапе компиляции.

Никто не сможет поместить в этот контейнер объект другого типа.
Для этого понадобился бы С-Style cast или reinterpret_cast. А против лома не приема.

dwl
Просто посмотрите на generic programming как на еще один прием повторного использования кода.
Однотипные дествия над типами объединяются в функции или структуры, которые связываются с
конркетными типами на этапе компиляции. Проверка производится компилятором.
Это лучше чем преобразование типов.

Нету никакого generic programming. Есть functional programming и lambda + high order functions.
И есть нечто бледное, чего пытаются изобразить в С++.

dwl
Сергей ИльичЛюбой класс в Яве наследует от Object метод equals, который можно перегрузить. Ты про это?
да я про это. Допустим у тебя есть контейнер или просто два объекта которые по сути являются ну например
пользовательскими обработчиками событий. Тебе надо их сравнить. Например, мы имеем некоторый список
"обработчиков", которые заполняет программа для этого объекта, чтобы потом их вызвать. Чуть позже один
из обработчиков надо удалить.

По умолчанию каждый объект к Яве равен только самому себе (дефолтовая реализация eqals в java.lang.Object
сравнивает указатели на объекты). Можно его перегрузить, чтобы сравнивать тождество содержимого объектов.
Но в объектах - хандлерах лучше этот метод не трогать.

dwl
Сергей ИльичЭто я вообще не понял. Ты видишь сложности там, где их нет.
Я не говорю что это сложно. Я лишь хотел показать, что имея тип Функтор, в котором реализованы
все необходимые действия, нам не надо его переписывать для разных типов функций, которых он оборачивает.
нам не надо копировать код. И нам не надо прибегать к преобразованиям типов
или другим седствам познего связывания.

Статический метод Collections.sort(...) может отсортировать любую последовательность содержащую
объекты любых типов. И там не надо ничего переписывать. Не вижу никаких проблем с поздним связыванием
(он делает downcasting к типу Comparable). В любом случае, пространства для нетривиального бага тут нет.
В конце концов, operator< тоже можно неправильно перегрузить.

dwl
Сергей ИльичА public API классов не дает права передавать в качестве параметров объекты любых типов.
Еще раз хочу проевить свою твердолобость. Все дело в повторном использовании кода.
Допустим нам надо написать некий класс, например, контейнер.
У него есть ряд стандартных действий по динамическому распределению объектов и управлению доступом к ним.
И я, например, хочу, чтобы мне не приходилось писать каждый раз код этого класса для разных типов хранимых
объектов. Если я не использую шаблоны, то мне придется указатель на некий базовый объект, и путем
преобразования типов получать доступ к его членам или методам. В случае шаблонов не надо ни копировать
исходники, не нужны преобразования типов. Я просто подставляю нужный тип и все. Это просто безопасное
повторное использование кода.

какие функциональные кирпичи программы кроме контейнеров ты можешь себе представить?
В конце концов, каждый кандидат на роль содержимого контейнера STL должен быть assignable и copy constructable.
Если подумать, на эти обязательства довольно сложно подписаться в случае нетривиальных объектов.
А указатели всегда assignable и copy constructable (кроме auto_ptr конечно).

dwl
Сергей ИльичЯ лишь интересовался безопасностью типов в коллекции callback функций. надо ли каждый вызов метода из этой коллекции оборачивать в
нет не надо. Насчет терминов. Извини что не дал определения этих понятий. Просто я подумал, что человек, который прочел книгу Александреску и сказал что она
фуфло знает смысл этих терминов. Именно в ней дается определение этих понятий, а точнее приемов программирования. И упомянул я их только в качестве вопроса
тебе, как прочитавшему книгу Александреску.

Почему не надо? кто-то заявил, что он кидает только SomeException (throw SomeException), он вызал мой метод,
мой метод вызвал какой-то калбэк из внутренней коллекции. А этот калбэк кинул SomeOtherException.
По идее, соглашение о кидании только SomeException нарушено, поэтому должен быть вызван unexpected(),
который по умолчанию сводится к terminate().

Я знаю значение этих терминов, но они были упомянуты явно не к месту.
Паттерны проектирования типа абстрактной фабрики лучше раскрыты в других книжках.
К тому же абстрактную фабрику в Яве можно сделать намного лучше - например чтобы она выбирала
нужный DAO плугин к базе данных, основываясь только на конфиге. Причем, при написании нового плугина
не надо было добавлять ни строчки ни эту фабрику ни вообще в основной код.
Мультиметоды - это методы, поведение которых зависит не только от динамического типа
объекта - сервера, но и от динамического типа объекта - клиента, в отличие от простых виртуальных функций,
поведение которых зависит только от динамического типа объекта - сервера.
Наверное, с помошью шаблонов можно проэмулировать наличие таких вещей в С++, но тогда придется
отказаться от раздельной компиляции. Ну не собрать шаблонный класс в *.obj. Никак.
Я говорил об этом. В ответ мне было заявлено, что я абсолютно не понял книгу Александреску.
Тогда, очевидно, я чего-то не понял. В этом случае мне нужно объяснение, как класс с мультиметодом
можно поместить в *.obj.
...
Рейтинг: 0 / 0
C++ & Java
    #32854512
Guest?
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cергей Ильич
я прочел твои тут умные фразы ;) про джава и с ++ ;)

или ты в практике ничем не сталкивался ;) или сталкивался кривыми программерами на с ++

согласис что с ++ намного быстрее работает ;) (имеется на виду написанные на с ++)

а что то делать .. как ни как с ++ более близок системе самой ;) так что тут про функциональности не надо говорить .. просто это может быть не так легко будеть как ты думаеш. просто перетаскал с помощю мышки и готово ;) так скорое всего не будет .. но в умелых руках повер мне (или не повер - дело твое ;)) с с ++ сравнить джава даже не стоит ;)

а то что думаеш прежде чем написать и упорно стоять на своем - хотя бы имей совесть работат с с ++ столько сколько работаеш с джава. освой как надо и потом сам посмотри ;)
...
Рейтинг: 0 / 0
C++ & Java
    #32854535
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
О, Лепрозорик! Привет, проказник!

Lepsik Сергей Ильич
Как в Яве, так и в С++ надо отдавать предпочтение долгоживущим объектам.
Неплохо использовать Singleton, или какой-нибудь пул объектов.
А создать долгоживущий объект в стеке несколько проблематично.

Вообще это твой стиль - сыпать какими-то терминами типа "мультиметод, функтор, абстрактная фабрика, политика etc"

почитав ваши диалоги у меня большие сомнения в том что вы писали что-то серьезнее чем Hello world на С++.
Извините, вы просто не владеете предметом.

Ну, пусть будет так. Устами дилетантов глаголет истина.

Lepsik
Не ошибусь, если скажу что 90% софта на вашем компьютере написано на С++.

Мои рабочие тулзы - IDEA и Together - написаны на Java.

Lepsik
Производительность вообще смех какой-то.
Поставил Office написанный на Java - Copy/Paste из IE в редактор на P4 заняло 2 минуты !


Навеяло тут ...

Эдмон Ростан

.. из Сирано де Бражерак

Ваш нос... Hy, в общем... крупноват...
Сирано.
Да. Он крупней, чем красноречье ваше,
А я бы о таком, заметьте,
О выдающемся предмете
Острот набрал бы целые тома,
Меняя жесты и топа...
Вот, например, из не особо острых --
Тон описательный -- так шутит новичок:
Как называете вы этот полуостров,
Который вырос между ваших щек?
Развязный тон, каким острят друзья:
Вам из стакана пить нельзя --
Побьет ваш нос посуду вашу!
Позвольте подарить вам чашу?
Или почтительно-умильный;
Вы этой башнею фамильной
Давно владеете? Наивный: С дальних мест
Вы этот монумент везли для дам столичных?
Любезный: Сударь любит птичек?
Он приготовил им вместительный насест!
Ехидный: Это что? Крючок для шляп? Удобный!
Платить не надо в гардеробной!
Тон нежный: Боже мой! От дождичка и ветра
Вы заказали зонтичек ему?
Тон удивленный: Извините, это --
Вам одному?
Доброжелательный: В пылу житейских гроз,
Фиаско потерпев в каком-нибудь вопросе,
Вам нелегко повесить нос,
Зато легко повеситься на носе!
Язвительный, чуть в сторону и косо:
Но, сударь, вам решительно везет:
Не видя дальше собственного носа,
Вы все же видите широкий горизонт!
Практический: Советовать вам смею
Для носа вашего устроить лотерею;
Я вам скажу с открытою душой,
Что получивший вещь такую
Имел бы выигрыш большой,
Имея радость небольшую.
Вот так острить могли б вы наобум,
Когда бы знания имели или ум.



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


вы о чем ? что такое конструирование ?

Чего - не скомпилировалась мысль в голове ? С чем поведешься, оттого и наберешься.

Я вообще о работе конструктора (конструирование == работа конструктора). Понял?

Lepsik
Сергей Ильич
Ты видел, сколько памяти может вытечь даже очень маленькими и редкими капельками, если работа
идет десятками часов?

мы занимаемся моделирование и расчеты ведутся сутками с трехмерными кубами со стороной 10000 элементов.
Даже и мысли не было сделать на JAva потому как производительность будет мама не горюй.

Когда я был на курсах по Джаве, мой руководитель мне дал задание - сделать два потока - один будет
точечки на экран выводить, другой будет факториал считать.
Мне приходилось замедлять цикл вычисления факториала, чтобы хотя бы 6-7 точечечек на экран успевали выскочить.
Причем вычисление факториала было по рекурсивному алгоритму, и в качестве аргумента я
подобрал такое число, чтобы если чуть больше - все вылетало с переполнением стека.
Раньше классы BigDecimal и BigInteger были реализованы через native. в jre 1.3 их переписали на чистый java,
и их скорость даже немного возросла. Игра chrome (3d fps с открытыми пространствами) написана на джава
+ native связка с Direct3d.
Библиотека fftw (Fatest Furier Transform in the West) была написана вовсе даже не на c/С++,
а на ML, функциональном языке.

Lepsik
---А у нас многие ребята - выпускники ИТМО и СПбГУ.

дилетанты бывают в любой среде

Показал отделу кадров - вместе посмеялись.
Они помнят, как по всему Питеру было не найти человека подходящего уровня. Искали год.
А компания у нас большая. Специализация - IT.
Видимо могучий Лепсик пишет вообше без ошибок.

Lepsik
Сергей ИльичПотому что исключения в С++ сделаны через жопу.
может не умеете ими пользоваться ?
В прошлый раз благодаря такому аргументу мы пришли к выводу, что чтобы пользоваться
произведением бездушной системы документирования javadoc не нужно умение, в противоположность
документации от Борланд. Видимо, Борланд очень много души вкладывает в свою документацию.
...
Рейтинг: 0 / 0
C++ & Java
    #32854690
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
всегда приятно почитать, что пишут люди с фантазией :)
...
Рейтинг: 0 / 0
C++ & Java
    #32854843
Lepsik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей ИльичО, Лепрозорик! Привет, проказник!


мы вроде бы не пили на брудершафт

Сергей Ильич
Ну, пусть будет так. Устами дилетантов глаголет истина.

Вообще это твой стиль - сыпать какими-то терминами типа "мультиметод, функтор, абстрактная фабрика, политика etc"


Это термины видимо дилетанты типа Алескандруску придумали, чтобы профессионалов мучать


Lepsik
Не ошибусь, если скажу что 90% софта на вашем компьютере написано на С++.

--Мои рабочие тулзы - IDEA и Together - написаны на Java.

а остальные 95% программ на вашем компьютере ?


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


вы о чем ? что такое конструирование ?

Чего - не скомпилировалась мысль в голове ? С чем поведешься, оттого и наберешься.

--Я вообще о работе конструктора (конструирование == работа конструктора). Понял?

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


--Когда я был на курсах по Джаве, мой руководитель мне дал задание - сделать два потока - один будет

С++ я так понял тоже на уровне курсов остался ?
дожились - программирование на курсах изучают. После вождения грузовиков надо полагать ?

Сергей Ильич
Показал отделу кадров - вместе посмеялись.
Они помнят, как по всему Питеру было не найти человека подходящего уровня. Искали год.
А компания у нас большая. Специализация - IT.


а вы как в IT сектор попали ? я так понял судя по курсам из другой отрасли ?

--Видимо могучий Лепсик пишет вообше без ошибок.

конечно бывают, как же без них ?

Сергей ИльичПотому что исключения в С++ сделаны через жопу.
может не умеете ими пользоваться ?[/quot]
В прошлый раз благодаря такому аргументу мы пришли к выводу, что чтобы пользоваться
произведением бездушной системы документирования javadoc не нужно умение, в противоположность
документации от Борланд. Видимо, Борланд очень много души вкладывает в свою документацию.[/quot]



Код: plaintext
1.
2.
3.
Syntax
catch (exception-declaration) compound-statement
Description
The exception handler is indicated by the catch keyword. The handler must be used immediately after the statements marked by the try keyword. The keyword catch can also occur immediately after another catch. Each handler will only evaluate an exception that matches, or can be converted to, the type specified in its argument list.

честно говоря даже не знаю чего можно добавить к этим трем явно избыточным предложениям, чтобы понять как правильно исключениями пользоваться .
...
Рейтинг: 0 / 0
C++ & Java
    #32854913
c127
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сергей Ильич> О, Лепрозорик! Привет, проказник!
NotGonnaGetUs> всегда приятно почитать, что пишут люди с фантазией :)

Эт точно, полет фантазии высок, а мысли глубоки.
...
Рейтинг: 0 / 0
C++ & Java
    #32855565
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Сергей ИльичКем гарантируется ? Стандартом или конкретным компилятором ? гарантируется стандартом. вот вам пример из MSVC
Код: 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.
67.
68.
69.
70.
class One{
	int i_;
public:
	One() : i_( 0 ) { printf("construct One;\n"); }
	~One() { printf("destruct One;\n"); }

	void* operator new( std::size_t Count ) { 
		printf("One operator new\n");
		return ::operator new(Count); 
	}
	void operator delete( void* ptr ){
		printf("One operator delete\n");
		::operator delete( ptr );
	}
};

class Two{
	int i_;
public:
	Two() : i_( 0 ) { printf("raise Two;\n"); *static_cast<char*>( 0 )= 0 ; }

	void* operator new( std::size_t Count ) { 
		printf("Two operator new\n");
		return ::operator new(Count); 
	}
	void operator delete( void* ptr ){
		printf("Two operator delete\n");
		::operator delete( ptr );
	}
};

struct Three1{
	One one_;
	Two two_;

	Three1() : one_(), two_() {}

	void* operator new( std::size_t Count ) { 
		printf("Three1 operator new\n");
		return ::operator new(Count); 
	}
	void operator delete( void* ptr ){
		printf("Three1 operator delete\n");
		::operator delete( ptr );
	}
};

struct Three2{
	std::auto_ptr<One> one_;
	std::auto_ptr<Two> two_;

	Three2() : one_(new One), two_(new Two) {}

	void* operator new( std::size_t Count ) { 
		printf("Three2 operator new\n");
		return ::operator new(Count); 
	}
	void operator delete( void* ptr ){
		printf("Three2 operator delete\n");
		::operator delete( ptr );
	}
};

int main()
{
    //Three1* t1( new Three1 );
	Three2 *t2( new Three2 );
    
	return  0 ;
}
все замечательно работает.


Сергей ИльичНикто не сможет поместить в этот контейнер объект другого типа. Для этого понадобился бы С-Style cast или reinterpret_cast. А против лома не приема.
В некоторых языках программирования, в которых нет generic programming, т.е. шаблонов и иже с ними, реализовывались классы контейнеров содержащие либо нетипизированные указатели, либо некий TObject от которого наследуются ВСЕ другие классы в языке, либо используют variant или что-то на него похожее. Итак, я беру в таком языке контейнер и хочу разместить в нем свой тип например TPoint. Ну и всякий раз чтобы к обращаться к членам этого класса в контейнере мне надо прибегать к преобразованиям типов. Уже постов 10 наверное я вам об этом говорю, но вы упорно игнорируете это и пытаетесь впарить мне что-то другое.

В случае с шаблонами мне не придется прибегать к преобразованиям типов. Такой вариант будет намного безопасней, чем вариант с контейнером нетипизированных указателей или с элементами типа TObject. Написание же своих контейнеров для каждого класса - очень неблагодарное занятие.

Сергей ИльичНету никакого generic programming.Бредит бедняга. Лишь бы несогласится во всем. Это как люди которые не признают что есть ООП. Понимаешь ява-фан, мне пофиг какой термин зреет у тебя в голове при виде шаблонов и приемов их использования. Для меня и для многих других программистов это значит generic programming. Пусть он будет синонимом того словосочетания, который ты так яростно предложил. Но спор о терминах непродуктивен. Обычно на него сбевается человек, у которого кончились аргументы.

И вообще разговор с тобой стал беспредментым. Он перешел с обсуждения того, что есть другие парадигмы программирования кроме ООП, на флейм о сравнении языков. Он бессмысленен, потому что технологии использования инструментов (языков) разные. Использовать подход ЯВЫ к С++ глупо, как и наоборот. Если возвращаться к частностям, то аргументы которые вы выдвинули против generic programming оказались лживыми, связанные с непониманием этого вопроса лично вами. А окончательный ваш аргумент - generic programming не существует. Следующим вашим шагом будет - шаблонов тоже нет, это макросы Си. И ваще весь мир иллюзия, ну и т.д. Очень продуктивно...

Сергей ИльичПо умолчанию каждый объект к Яве равен только самому себе (дефолтовая реализация eqals в java.lang.Object сравнивает указатели на объекты). Можно его перегрузить, чтобы сравнивать тождество содержимого объектов. Но в объектах - хандлерах лучше этот метод не трогать.
ставим галочку сравнить функторы в Яве нельзя. ясно. ваш ответ понятен.

Сергей ИльичСтатический метод Collections.sort(...) может отсортировать любую последовательность содержащую объекты любых типов. И там не надо ничего переписывать. Не вижу никаких проблем с поздним связыванием (он делает downcasting к типу Comparable). В любом случае, пространства для нетривиального бага тут нет. В конце концов, operator< тоже можно неправильно перегрузить.
оооо, какая маленькая частность!!! какие чудеса. и это доказывает что? что шаблоны не нужны. Ну вы сделали революцию. А теперь попробуйте сделать еще один шаг дальше. С тем же подходом напишите контейнер для любых классов. Ну я имею ввиду, что элементы однотипны, но могут быть объектами разных классов.

Сергей Ильичкакие функциональные кирпичи программы кроме контейнеров ты можешь себе представить? понимаешь, я так часто повторяю о реализации контейнеров, как наглядном примере использования generic programming. Ты это упорно пропускаешь мимо ушей. Говоря о чем-то своем. Но изначально речь зашла о шаблонах и ты высказался что они есть очень-очень плохо и не нужны вовсе. Я попросил аргументировать. На выдвигаемые тобой аргументы я ответил. Твои аргументы кончились, теперь ты обвиняешь меня в зациклинности, хотя сам ингорировал, то что я тебе говорил о преимуществах generic programming. О том что у любого решения есть плюсы и минусы, и что надо выбирать нечто оптимальное. Это можно сделать только в условиях КОНКРЕТНОЙ ЗАДАЧИ, а не с философской точки зрения. ВОТ Я ТЕБЕ ОПЯТЬ предлагаю конретную задачу - контейнер объектов любого класса. Забудем про контейнер функторов для реализации делегатов. Вернемся просто к контейнерам.

Сергей ИльичВ конце концов, каждый кандидат на роль содержимого контейнера STL должен быть assignable и copy constructable. Если подумать, на эти обязательства довольно сложно подписаться в случае нетривиальных объектов. Не вижу ничего сложного, абсолютно! приведите ваш пример, а пока приведу свой.
Код: plaintext
1.
2.
struct TPoint{
 int x,y;
}
все - этот объект готов к размещению в контейнере. ну давайте посложней
Код: plaintext
1.
2.
3.
4.
class TCircle{
 TPoint center_;
 float radius_;
}
тоже самое. Это объект можно размещать в контейнере. Сложно? да нет.

Сергей ИльичПочему не надо? кто-то заявил, что он кидает только SomeException (throw SomeException), он вызал мой метод, мой метод вызвал какой-то калбэк из внутренней коллекции. А этот калбэк кинул SomeOtherException. По идее, соглашение о кидании только SomeException нарушено, поэтому должен быть вызван unexpected(), который по умолчанию сводится к terminate().
Ты знаешь, не боюсь повторится - на те приемы, которые использует специалист в своей работе, накладывает отпечаток опыт применения какого-либо инструмента. о чем я? да о специализации исключений. Оно уже убрано в новом черновом стандарте С++. В 4 современных компиляторах, на него компилеры выдают варнинг. ДОстаточно опытный программист С++ знает те минусы их использования. Это определенный стиль программирования. Ниже я приведу реализацию СТЕКА без единого try catch, но который работает корректно, не разрушая себя или то что в нем хранится, если генерируется исключение. приведу пример, только чтобы показать, что есть другой подход в обработке исключений.

Сергей ИльичЯ знаю значение этих терминов, но они были упомянуты явно не к месту. они были упомянуты к месту. ПОВТОРЮ. Тобой было сказано, что книга Александреску не имеет практического применения, в ответ я упомянул о реализации фабрик, мультиметодов и прочего. И то что они как раз имеют практическое применение. Я не сравнивал это с друнгими реализациями, и не говорил что книга Александреску является единственной книгой о паттернах программирования. Вы передергиваете и переиначиваете мои слова. Я ВЫСКАЗАЛ СВОЙ АРГУМЕНТ в ответ на ваше поспешную фразу. Так же я сказал, что это книга является хорошим примером ЭФФЕКТИВНОГО использования шаблонов в применении к паттернам проектирования. Вы не стали ничего говорить в ответ, а лишь сыпали высказываниями что я бросаюсь какими-то терминами и чего-то жду. Что я их говорю не к месту. Ну и т.д. и т.п. Т.е. обычные общие эмоциональные фразы. Если хотите продуктивного разговора - давайте возьмем у Александреску реализацию визитера и разберем его по полочкам, что там плохого, и что хорошего. (боюсь мне этого от вас никогда не дождаться). Чтобы вы востержроствовали в плане доказательств бесперспективности использования шаблонов. Вы же читали эту книгу, значит помните все, ну или основные минусы, той реализации которую встретили. Мне очень интересно их услышать. я весь внимание.

Сергей ИльичНаверное, с помошью шаблонов можно проэмулировать наличие таких вещей в С++, но тогда придется отказаться от раздельной компиляции. Ну не собрать шаблонный класс в *.obj. Никак. Я говорил об этом. Да для шаблонов нельзя сделать закрытую реализацию. Только ответ на непонимание книги Александреску прозвучал совсем в другом месте. Эти вопросы никак не связаны. Только я хочу сделать мааааленькую оговорочку.

ДОпустим вы имеете несколько классов и вам надо реализовать несколько мультиметодов для них. Или построить везетера. Вам не надо открывать реализацию этих классов. Открыта всего лишь реализация класса шаблона везетера. Если вы хотите считать это минусом - считайте. Переубеждать вас не буду. Еще раз повторюсь - любое решение содержит плюсы и минусы. Надо выбирать оптимальное.

Существует масса библиотек шаблонов, которые используются большим кол-вом программистов. Просто потому, что есть ситуации, когда выбор шаблонов оптимален. Одна из причин - СТРОГАЯ ЗАЩИТА ТИПОВ. Более строгая чем вызов виртуальных методов интерфейсов или преобразование типов от какого-то базового класса. Есть и еще аргументы. я их не называю потому, что вы не признаете даже такой очевидный как этот.

Мое предложение, либо давайте говорить о КОНКРЕТНЫХ ВЕЩАХ - фрагменты кода с указанием плюсов и минусов( показав на примере более более оптимального решения). Либо оставьте эту тему в покое.

(а пока напишу реализацию стека)
...
Рейтинг: 0 / 0
C++ & Java
    #32855570
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
насчет Exception Specifications рекомендую пока ознакомится здесь .
...
Рейтинг: 0 / 0
C++ & Java
    #32855635
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Итак, цитируя Саттера, в 1994 году Том Каргилл опубликовал статью "Exception Handling: A False Sense of Security" (кажется в журнале C++ Report). Он убидительно показал, что в то время программисты С++ не совсем хорошо понимали как следует писать безопасный в смысле исключений код...

Каргилл предложил всем читателям найти полное решение поставленной им задачи. Хотя изначально речь шла не о шаблонах, а просто некий класс widget. Ну не важно...
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
    
    template <class T>
    // T must have default ctor and copy assignment
    class Stack
    {
    public:
        Stack();
        ~Stack();
        Stack(const Stack&);
        Stack& operator=(const Stack&);

        unsigned Count();   // returns # of T's in the stack
        void     Push(const T&);
        T        Pop();     // if empty, returns default-
                            // constructed T

    private:
        T*       v_;        // pointer to a memory area big
                            //  enough for 'vsize_' T objects
        unsigned vsize_;    // the size of the 'v_' area
        unsigned vused_;    // the number of T's actually
                            //  used in the 'v_' area
    };
Надо было предоставить реализацию этого класса со "строгой гарантией" ,безопасности исключений (сформулированную Дейвом Абрахомсом). Через три года решение было предоставлено и были внесены соответсвующие изминения в стандарт языка. Вот решение
Код: 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.
template<class T1, class T2>
void construct( T1* p, const T2& value ){
 new(p) T1( value );
}

template<class T>
void destroy( T* p ){
  p->~T();
}

template<class FwdIter>
void destroy( FwdIter first, FwdIter last ){
 while( first != last ){
   destroy( &*first);
   ++first;
 }
}

// идеома pimpl
template<class T>
class StackImpl{
protected:
 StackImpl(size_t size =  0 );
 ~StackImpl();
 void Swap( StackImpl& other );
 T* v_;
 size_t vsize_;
 size_t vused_;
private:
 StackImpl( const StackImpl& );
 StackImpl& operator = ( const StackImpl& );
};


template<class T>
StackImpl<T>::StackImpl( size_t size )
// запрещаем вызов конструкторов по умолчанию
     : v_( static_cast<T*>(size== 0 ?  0  : operator new( sizeof(T)*size ) ) ),
       vsize_(size),
       vused_( 0 )
{
}

template<class T>
StackImpl<T>::~StackImpl(){
 destroy( v_, v_ + vused_ );
 operator delete( v_ );
}

template<class T>
void StackImpl<T>::Swap( StackImpl &other ){
  std::swap( v_, other.v_ );
  std::swap( vsize_, other.vsize_ );
  std::swap( vused_, other.vused_ );
}

тут возможны две реализации идеомы pimpl:
1) указатель на реализацию, тогда члены реализации стека должны быть public
2) наследование, тогда ничего менять не надо

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

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
template<class T>
class Stack : private StackImpl<T>
{
 public:
   Stack( size_t size =  0  ) : StackImpl<T>(size) {};
   // деструктор не нужен
  Stack( const Stack& );
  Stack& operator = (const Stack temp ) { Swap(temp); return *this; }
  size_t Count() const { return vused_; }
  void Push( const T& );
  T& Top();
  void Pop();
}

вобче-то дальше ужо можно не приводить методы, потому что идея понятна уже по реализации оператора присваивания. Но дальше процитирую кратко остальные методы, для краткости без проверки границ и размеров стека. просто для краткости
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
Stack( const Stack& other )
       : StackImpl<T>(other.vused_)
{
   while( vused_ < other.vused_ ){
         construct( v_ + vused_, other.v_[vused_] );
         ++vused_;
   }
}

void Push(const T& t )
{
   if( vused_ == vsize_ ){
       Stack temp( vsize_* 2  +  1  );

       while( temp.Count() < vused_ ) temp.Push( v_[temp.Count()] );
       temp.Push( t );
       Swap( temp );
   } else {
       construct( v_ + vused_, t );
       ++vused_;
   }
}
остальные методы не вижу смысла приводить здесь. Суть уловили? Мы обошлись без блоков try catch, но это не значит что они не нужны. Важно уловить суть написания безопасных классов.

Далее о спецификациях исключений.
...
Рейтинг: 0 / 0
C++ & Java
    #32855643
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cорри, что вмешиваюсь :)
dwl
Сергей Ильич
Никто не сможет поместить в этот контейнер объект другого типа. Для этого понадобился бы С-Style cast или reinterpret_cast. А против лома не приема.

В некоторых языках программирования, в которых нет generic programming, т.е. шаблонов и иже с ними, реализовывались классы контейнеров содержащие либо нетипизированные указатели, либо некий TObject от которого наследуются ВСЕ другие классы в языке, либо используют variant или что-то на него похожее. Итак, я беру в таком языке контейнер и хочу разместить в нем свой тип например TPoint. Ну и всякий раз чтобы к обращаться к членам этого класса в контейнере мне надо прибегать к преобразованиям типов. Уже постов 10 наверное я вам об этом говорю, но вы упорно игнорируете это и пытаетесь впарить мне что-то другое.


1. С.Ильич говорит об этом:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
   class  MyCollection {
        Vector v =  new  Vector();
         void  add(MyObj o){
              v.add(o);
        }
        MyObj get( int  i) {
               return  (MyObj)v.get(i);
        }
  }
Поместить объект не того типа - не получится.
Каст - безопасен, если MyCollection реализован корректно.

2. А начиная с java1.5.
Можно писать
Код: plaintext
1.
2.
3.
Vector<MyObj> v = ... ;
  ... 
MyObj obj = v.get(i);
Т.е. нет никаких проблем с помещение однотипных объектов в коллекции.
Проверка типов гарантируется на этапе написания кода.

3. В чём на самом деле плюсы С++ generetics, если это новая технология програминга? :)
...
Рейтинг: 0 / 0
C++ & Java
    #32855649
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
т.е. генерик програминг.
...
Рейтинг: 0 / 0
C++ & Java
    #32855655
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Более подробно о гадости спецификации исключений для функций можно прочесть в еще одной интересной статье Саттера - ТУТ .

Если кратко пересказывать то получится вот что:
- Указание throw() ограничит в будущем ваши возможности по изминению кода этих функций - вы не будете иметь права генерировать исключения. Изминение спецификации исключений несет риск нанесения вреда клиенту который юзает эту функцию и расчитывает что она не выпускает исключений.
- Спецификации исключений могут привести к повышенным накладным расходам независимо от того, генерируется ли на самом деле исеключение или нет. Например такой оператор перестанет быть инлайновым:
Код: plaintext
T& operator*() const throw()  { return *ptr; }

Более придирчивые могут заметить, что весь тот класс стека, что я процитировал, основан на одном допущении что деструкторы не генерят исключений. Да. Есть такое соглашение. И я не вижу ничего плохого в нем. Если класс нельзя безопасно разрушить, тогда раскрутка стека станет невозможной. И никакой try catch здесь не поможет. Если кому интересно можно об этом рассказать.

PS: кстати, задача Каргилла была решена при помощи указателя на клас-реализацию. Указатель был одет в std::auto_ptr
...
Рейтинг: 0 / 0
C++ & Java
    #32855676
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Очень рад что "вдруг" начали подтягиваться силы с Ява форума, чтобы закопать гадких С++ программеров. Еще раз повторю мысль высказанную на первой страничке темы - сравнение языков - флейм и тему надо закрывать. Лично я потерял к ней всякий интерес.

NotGonnaGetUs1. С.Ильич говорит об этом: А я об этом
Код: plaintext
 return (MyObj)v.get(i);
о том, что шаблоны позволяют избегать преобразований типов. Т.е. познего(динамического) связывания. Динамическое связывание переносит проверку ошибок на момент отладки, т.е. рантайм. В случае использования шаблонов подобные ошибки обнаруживаются на этапе компиляции. Далее в таком контейнере могут лежать только классы с виртульаным деструктором. Хотя в случае если за вами приберает машина - это не имеет значение. Это первое. Второе у меня есть ОДИН КЛАСС контейнер и мне не надо переписывать что либо, т.е. писать MyCollection, чтобы получить доступ к елементам контейнера. Это улучшает повтороное использование кода и ускоряет написание программ. Третье шаблоны позволяют расширять возможности языка без добавления новых фич и принятия новых стандартов. Хотя это не значит, что фичи не нужны.

Все эти вещи я писал в своих предыдущих сообщениях. Если каждый посетитель форума Явы будет приходить в эту ветку не читая ее содержимого и задавать один и тот же вопрос - "чем же это лучше?". То мне вскоре надоест отвечать. Это будет результат 8-)

NotGonnaGetUs2. А начиная с java1.5. Можно писать... Об этом я тоже писал, сказав о том, что это лишний раз доказывает перпективность такого подхода в разарботке, который продемонстрировали шаблоны в С++.

NotGonnaGetUs3. В чём на самом деле плюсы С++ generetics, если это новая технология програминга? :)
Технология, парадигма, как хотите...
1) лучшая защита типов
2) статическое связывание типов, что позволяет повторно использовать большее кол-ва кода, нежели ТОЛЬКО при помощи ООП.
3) возможность написание алгоритмов без привязки к реализации того или иного типа. Пример алгоритмы STL. А также например умные указатели.
4) делает код более быстрым, потому что в случае со статическим связыванием типов, многие вещи инстанцируются инлайново плюс этим(инстанцированием) можно управлять. Пример я уже приводил, при помощи классов-шаблонов выражений была написана билиотека, которая реализует алгоритмы линейной алгебры быстрее чем аналогичная на Фортране. До этого никто не мог "побить" этот фортрановский рекорд. Он держался десятки лет. Подробне смотри std::valarray, boost::uBLASt, библиотеки biltz (вроде бы так) и MTL (matrix template library).


Это если вобчем.

Ну я понимаю, что контейнеры уже всем надоели - приведу другой пример. Пример совместного использования шаблонов и ООП. В яве такой(их) задач безусловно не возникнет:
Код: 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.
// пример с умными указателями пропущу. Но не представляю как ЛУЧШЕ это сделать в ООП
template<class T>
class SmartPrt{
  T* ptr_;
  
  // запретить преобразование типов
  template<class U>
  operator U();

  // запретить операцию присвоения
  template<class U>
  T& operator =( U& );
public:
  SmartPtr( T* other ) : ptr_( other ) {}
  ~SmartPtr() { ptr->~T(); } // вызываем дуструктор нужного типа
  T* operator ->() const { return ptr_; }
  T& operator *() const { return *ptr; }
}

// ну или - например хочу написать счетчик объектов того или иного класса
// для этого мне надо написать тоьлко один класс, в случае реализации ООП, она будет более громоздкой
template<class T>
class ObjectCounter{
private:
   static size_t count;
protected:
   ObjectCounter() { ++ObjectCounter<T>::count; }
   ObjectCounter( ObjectCounter<T> const& ) { ++ObjectCounter<T>::count; }
   ~ObjectCounter() { --ObjectCounter<T>::count; }
public:
   static size_t live() { return ObjectCounter<T>::count; }
}

template<class T>
size_t ObjectCounter<T>::count =  0 ;
далее для ЛЮБОГО класса можно сделать так и ничего при это не надо переписывать или добавлять новых структур данных, при этом сохранив строгую проверку типов.
Код: plaintext
 class MyType : public ObjectCounter<MyType> 
как видите объект даже не стал шаблоном. Для него можно сделать закрытую реализацию. И изминять почти ничего не пришлось.

Следующим постом другие примеры
...
Рейтинг: 0 / 0
C++ & Java
    #32855692
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Если кто-то предыдущие примеры считает не удобными или не наглядными приведу еще пару примеров (такие задачи могут и не возникнуть в рамках другого языка, что лишний раз доказывает что сравнивать языки глупо ). Эти примеры показывают как шаблоны раздвигают возможности КОНКРЕТНО ЯЗЫКА С++.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
//как сделать класс, который нельзя наследовать
// вот решение для любого класса
template <class T> class NotInherit; // форвардим чтобы друга объявить

template <class T> 
class NotInheritImpl
{
  friend class T;
  friend class NotInherit<T>;

private:
  NotInheritImpl() {}
};

template <class T> 
class NotInherit : private virtual NotInheritImpl<T> {};

// Пример 
class MyType : NotInherit<MyType>
{
  // этот класс нельзя наследовать
};

NotInherit можно применить к любому существующему классу проекта С++. Есть еще одна удобная штучка STATIC_ASSERT, можно заставить компилятор заткнуться в нужном месте СООБЩИВ определенный текст что вам нужен. Средствами ООП это ваще не реализуется.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
template<bool> struct CompilerTimeChecker{
  CompilerTimeChecker(...); // т.е. произвольное кол-во аргументов
};

template<> struct compileTimeChecker<false> {};

#define STATIC_CHECK(expr, msg)\
{\
class ERROR_##msg {};\
(void)sizeof(CompileTimeChecker<(expr) !=  0  >((ERROR_##msg())));\
}
ну кончено сообщения могут быть только на английском, типа того STATIC_CHECK( sizeof(From) <= sizeof(To), Destination_Type_Too_Narrow ) . Удобно. Кстати в BOOST пошли дальше. Одна из областей применения такого ассерта concept_check , когда класс или функция проверяет, а выполняются ли нудные требования для типа. Если не выполняются - генерить ошибку компиляции.

Например
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
#include <list>
#include <algorithm>

int main(int, char*[]) {
    std::list<int> v;
    std::stable_sort(v.begin(), v.end());
    return  0 ;
}
Если добавить в эту программу concept_check, тогда длинные и столь нелюбимые стандартные ошибки, например об отсуствии оператора меньше
Код: plaintext
1.
2.
3.
stl_algo.h: In function `void __merge_sort_loop<_List_iterator
  <int,int &,int *>, int *, int>(_List_iterator<int,int &,int *>,
  _List_iterator<int,int &,int *>, int *, int)':
превращаются в более удобный вид
Код: plaintext
1.
boost/concept_check.hpp: In method `void LessThanComparableConcept
  <_List_iterator<int,int &,int *> >::constraints()':

Используя шаблоны я могу сделать виртульаность метода класса ПАРАМЕТРИЗИРОВАННЫМ. Т.е. какие-то классы наследуют от родителя виртуальный класс, а какие-то нет. Используя шаблоны я могу определить какой тип передается шаблону. Причем сделать это можно на этапе компиляции без RTTI. Используя шаблоны можно определить есть ли нуный метод у класса или нет, и в зависимости от результата что-то предпринять. Например, так действует "определитель", что тип является POD, а не классом. При помощи шалонов можно реализовать такую замечательную вещь как списки типов. Используя их можно получить более элегантную реализацию Визитера, чем ЛЕС dynamic_cast ( ну или операторов T is MyType ). Перечислять можно долго.

Еще раз повторюсь, что в других языках возможно таких вопросов и не возникает. Такие задачи могут быть поставлены и решены в С++. Поэтому раз мы рассматриваем шаблоны С++, то я и говорю в ДАННЫЙ момент о пользе их для С++. О более общих плюсах я уже говорил в других постах.
...
Рейтинг: 0 / 0
C++ & Java
    #32855848
c127
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
2 NotGonnaGetUs

>Т.е. нет никаких проблем с помещение однотипных объектов в коллекции.
Проверка типов гарантируется на этапе написания кода.


Этап написания кода это хорошо сказано. А если код пишется на бумаге проверка типов тоже гарантируется?
...
Рейтинг: 0 / 0
C++ & Java
    #32856004
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
c1272 NotGonnaGetUs

>Т.е. нет никаких проблем с помещение однотипных объектов в коллекции.
Проверка типов гарантируется на этапе написания кода.


Этап написания кода это хорошо сказано. А если код пишется на бумаге проверка типов тоже гарантируется?

%)
Для самых остроумных поясню. Речь о том, что не обязательно компилировать приложение, что бы получить сообщения об ошибке. IDE 99% ошибок возникающих на этапе компиляции подсвечивают при наборе кода.

Разве в c++ не тоже самое? Или с-шный код на бумаге всегда пишется правильно? :)
...
Рейтинг: 0 / 0
C++ & Java
    #32856008
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
ну понеслась...
здесь уже стали IDE сравнивать - чистоганом флейм попер.

ЗЫЖ если кому интересно чисто в качестве эрудиции, лично у меня в MSVC 2003 ошибки "подсвечиваются". Хотя это не показатель. У меня есть подобные надстройки для делфи, для буилдера, для бейсика. и что теперь? что-то изменилась в ваших взглядах?
...
Рейтинг: 0 / 0
C++ & Java
    #32856030
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwlОчень рад что "вдруг" начали подтягиваться силы с Ява форума, чтобы закопать гадких С++ программеров.

Ну зачем так грубо :) Лично я, всех программеров люблю одинаково.
(Даже тех кто-пишет на php ^_^)


NotGonnaGetUs1. С.Ильич говорит об этом: А я об этом
Код: plaintext
 return (MyObj)v.get(i);
о том, что шаблоны позволяют избегать преобразований типов. Т.е. познего(динамического) связывания.

Пример Ильича как раз показывает, что можно обойтись без позднего динамического связывания введением подобных конструкций (MyCollection).
Я не спорю, generic удобен тем, что позволяет описать теже самые конструкции, только класс "MyObj" становится в них параметром, а не жестко заданным.
Да, это сокращает кол-во кода, который нужно написать.
С этим никто не спорил.
Я спросил какие ещё плюсы даёт С++ generic.
Если всё дело только в выше описанном - не понятно зачем "генерик" ставить на один уровень с "ооп".


Третье шаблоны позволяют расширять возможности языка без добавления новых фич и принятия новых стандартов. Хотя это не значит, что фичи не нужны.

Не много не понял о чём речь. Шаблоны позволяют вместо одного стандарта сделать десять разных и потом учить им каждого нового программиста в проекте? Тогда стронняя библиотека тоже является расширением стандарта языка? :)

Если каждый посетитель форума Явы будет приходить в эту ветку не читая ее содержимого и задавать один и тот же вопрос - "чем же это лучше?".

Я дня три регулярно перечитывал ветку :) Просто мне показалось что вы отвечаете друг другу одно и тоже из-за не допонимания и попытлся показать в чём оно :(

---

Ответ на свой вопрос я получил, спасибо :)

"Общие плюсы" от С++ generic = плюсы от java generic + interfaces.

Остальные проблемы решаемые шаблонами уникальны для языка С++, а не для программирования как такового.

Далее одна субъективность: что лучше учить язык пару лет и постоянно обнаруживать в нём новые тонкости или выучить его за пару месяцев и просто писать код? :) Тут конечно же на любителя.

з.ы. У меня тоже нет желания вести флейм :)
...
Рейтинг: 0 / 0
C++ & Java
    #32856034
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwlну понеслась...
здесь уже стали IDE сравнивать - чистоганом флейм попер.


Я тоже удивился реакции c127 :)
Речь не про IDE, а про ошибки на стадии компиляции.
...
Рейтинг: 0 / 0
C++ & Java
    #32856040
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
NotGonnaGetUsРечь не про IDE, а про ошибки на стадии компиляции.Ну и я о них. Сто раз уже говорил, что преобразования типов уменьшают кол-во таких ошибок откладывая их проверку на рантайм. Использование шаблонов наоборот увеличивает кол-во ситауция которых можно проверить на этапе компиляции.

Например, используя шаблоны я могу определить является ли тип встроенным, или является ли один класс наследником другого. На этапе компиляции а не рантайм. Попробуйте это сделать обычными средставми ООП.
...
Рейтинг: 0 / 0
C++ & Java
    #32856046
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwlНапример, используя шаблоны я могу определить является ли тип встроенным, или является ли один класс наследником другого. На этапе компиляции а не рантайм.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
 class  A {};
 class  B  extends  A{};
 class  C {};

...
B b =  new  B();
C c =  new  C();
...
A a =  b; //является наследником
A a =  c; // ошибка компиляции :)
...

Пойдёт? :)
...
Рейтинг: 0 / 0
C++ & Java
    #32856060
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
NotGonnaGetUsНу зачем так грубо :) Лично я, всех программеров люблю одинаково.Извини что не заметил здесь грубости. Не могу похватстать тем что люблю всех. До Христа мне ой как далеко... Но еще раз повторюсь что и я ничего не имею против других средств разработки. Встрял я в этот разговор сугубо из НЕВЕРНЫХ суждений о шаблонах которые выдвигал Ильич. Только поэтому а не из-за того чтобы оспорить право существование Явы или чего-то другого.

NotGonnaGetUsПример Ильича как раз показывает, что можно обойтись без позднего динамического связывания введением подобных конструкций (MyCollection). Тот пример что вы привели - это не статическая проверка типов - это классический пример преобразования типов, а точнее если говорить терминами С++ (в Яве может быть и по другому) - это ЛИБО вызов кнструктора одного класса с параметрами переменной типа другого класса. ЛИБО динамическое приведение полиморфно связанных типов ПРЕДОК-ПОТОМОК, но это рановсильно dynamic_cast - это опять динамическая проверка типов. Это будет все происходить только на этапе рантайм. ПРоверено временем и программами.


NotGonnaGetUsЯ спросил какие ещё плюсы даёт С++ generic.
Я ответил в общем смысле - назвав три пункта, Потому что переход на частности - это описание языка С++.

NotGonnaGetUsЕсли всё дело только в выше описанном - не понятно зачем "генерик" ставить на один уровень с "ооп".
не знаю что такое уровень ООП, и не знаю кто его ставил шаблоны на уровень ООП. ЭТО ГЛУПО!!! дажее еще глупее. Это две разные парадигмы программирования, предназаначеные для улучшения повторного использования кода. Только эта цель их и объеденяет. В миллионный раз повторяю, что их можно использовать вместе А НЕ ЗАМЕЩАТЬ ОДНУ ДРУГОЙ. Очень хороший эффект получается от взаимного использования. Например реккурентые шаблоны. Примеры я привел выше. (заколебался повторять одно и тоже. это уже третий раз)

NotGonnaGetUsНе много не понял о чём речь. Шаблоны позволяют вместо одного стандарта сделать десять разных и потом учить им каждого нового рограммиста в проекте? Тогда стронняя библиотека тоже является расширением стандарта языка? :)
Это называется понимать слышать одно а понимать то что УДОБНО. Я как раз говорил об обратном. Скажи создание библиотек позволяет раздивнуть функциональность языка программирования? мой ответ - да. Допустим C# достаточно простой язык являющийся подмножиством С++. Ничего особо сложного и нового из себя не представляет. Польза его в том, что есть всякие WinForms, WebForms и т.д. Как VCL в Делфи. ты используешь уже готовый и отлаженный код. Никто не говорит что это ДРУГОЙ ЯЗЫК. Тебе и многим другим программистам не надо писать одно и тоже и отлаживать это.

Теперь ПОВТОРЮ ТО ЧТО БЫЛО СКАЗАНО НА ТРЕТЕЙ СТРАНИЦЕ этого ФЛЕЙМА. Потрудитесь прочитать прежде чем ерничать. Берем С++, шаблоны и пишем контейнеры. Чудно. Великолепно. все работает. Берем другой язык, там такого сделать невозможно поэтому добавляют новый тип данных - динамические массивы. Это уже расширение языка, КОТОРОЕ НЕ ПОТРЕБОВАЛОСЬ в С++. Потому что эту фичу можно реализовать имеющимися средствами.

Беру еще пример, проперти. В других языках это потребует расширения языка. В С++ написание подобного типа занимает с десяток строк и не требует принятия новых стандартнов языка.

Еще пример, чтобы вам не было лень просматривать тексты ФЛЕЙМА, посмотрите на верх этой страницы, там я привел текст класса (5 строчек), который позволяет запретить наследование того или иного класса. Опять же например в C# для этого нащдо добавлять ключевое слово. Т.е. принимать другую спецификацию языка. С++ сделано имеющимися средствами.

Еще пример, сборщики мусора, счетчики ссылок и прочее. В С++ достаточно использования умных указателей или таких ссылок как я привел выше - в начале этой странички. ОПЯТЬ ЖЕ НЕ ПРИШЛОСЬ МЕНЯТЬ ЯЗЫК.

Еще пример, делегаты. Т.е. контейнеры callback функций, а точнее функторов. Которые обильно используются в C# например, но привязаны к this того класса, на который ссылаются. В С++ можно это реализовать имеющимися средствами без принятия новых стандартов и фич языка. Причем с большими функциональными возможностями.

Другие примеры которые так сильно нервируют Ильича. Мультиметоды, анонимные методы(функции) их опять же можно (и они реализованы) средствами языка С++. Без принятия стандартов.

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


NotGonnaGetUsЯ дня три регулярно перечитывал ветку :) Просто мне показалось что вы отвечаете друг другу одно и тоже из-за не допонимания и попытлся показать в чём оно :(
ну я то точно отвечаю одно и тоже. недопонимание есть точно. тут я согласен. Это одна из черт ФЛЕЙМА. мне просто непонятно почему люди считают что некоторые преобразования типов выполняются на этапе компиляции - это не так. Тот пример, что вы приводили - он неверен. я уже об этом говорил. Это преобразование на деле будет осуществлять проверку в рантайме.
...
Рейтинг: 0 / 0
C++ & Java
    #32856062
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
NotGonnaGetUs
Код: plaintext
1.
2.
A a =  b; //является наследником
A a =  c; // ошибка компиляции :)
Пойдет?

нет. представим что у вас есть класс у которого надо определить две релизации какого-то метода, один для тех классов которым он предок, другой для остальных классов. Т.е. ошибок компиляции нет, мы просто получаем два варианта инстанцирования класса(или метода).
...
Рейтинг: 0 / 0
C++ & Java
    #32856068
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
NotGonnaGetUsОстальные проблемы решаемые шаблонами уникальны для языка С++, а не для программирования как такового.
В часностях некотрых вы правы. Но есть парочка показательных примеров. Давайте сделаем это на практике. Допустим у вас есть некая графическая среда и пока в ней реализованы только три класса Bitmap, VectorGraphics, textArea . Реализация этой среды закрыта. Ну допустим это некая внешняя программа, к который вы пишете свой плагин.

Реализуем паттерн Визитер, т.е. добавим еще одну операцию в иерархию классов, которую не можем изменить. Полчаса у меня сегодня еще есть - я подожду вашей реализации.
...
Рейтинг: 0 / 0
C++ & Java
    #32856076
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl NotGonnaGetUsНу зачем так грубо :) Лично я, всех программеров люблю одинаково.Извини что не заметил здесь грубости. Не могу похватстать тем что люблю всех. До

...

мне просто непонятно почему люди считают что некоторые преобразования типов выполняются на этапе компиляции - это не так. Тот пример, что вы приводили - он неверен. я уже об этом говорил. Это преобразование на деле будет осуществлять проверку в рантайме.

Не переживайте вы так! Читал я третью страницу :)

В муКоллекшин каст безопасен, поскольку в вектор не может в принципе ничего попасть, кроме муОбж. С этим нужно просто смириться.
Хотя вести флейм по этому поводу у вас получается :)
...
Рейтинг: 0 / 0
C++ & Java
    #32856077
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl NotGonnaGetUs
Код: plaintext
1.
2.
A a =  b; //является наследником
A a =  c; // ошибка компиляции :)
Пойдет?

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

Можно на пальцах? Я могу вас не верно истолковать :)
Код: plaintext
1.
2.
3.
4.
сlass A {
   void method(A a) {} //для детей
   void method(Object o) {} //для остальных классов.
}
Об этом речь?
...
Рейтинг: 0 / 0
C++ & Java
    #32856080
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl NotGonnaGetUsОстальные проблемы решаемые шаблонами уникальны для языка С++, а не для программирования как такового.
В часностях некотрых вы правы. Но есть парочка показательных примеров. Давайте сделаем это на практике. Допустим у вас есть некая графическая среда и пока в ней реализованы только три класса Bitmap, VectorGraphics, textArea . Реализация этой среды закрыта. Ну допустим это некая внешняя программа, к который вы пишете свой плагин.

Реализуем паттерн Визитер, т.е. добавим еще одну операцию в иерархию классов, которую не можем изменить. Полчаса у меня сегодня еще есть - я подожду вашей реализации.

Слишком обще поставленна задача, без наглядной иллюстрации мне с вашими терминами не разобраться.

А кто будет этой "операцией" пользоваться?
Что представляет собой плагин?
Визитёр уже реализован в "трёх классах" или нет?
...
Рейтинг: 0 / 0
C++ & Java
    #32856099
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
NotGonnaGetUsВ муКоллекшин каст безопасен, поскольку в вектор не может в принципе ничего попасть, кроме муОбж. С этим нужно просто смириться Ага и чтобы обезопасить каждый хранимый тип вам надо писать "оболочку" вокруг вектора. а попасть туда могут еще и наследники MyObj. А если вы закроете эту реализацию коллекции, тогда какой-нить другой программист поленится писать свою коллекцию и будет преобразовывать в MyObj какой-то другой класс. Или я не прав? Тогда попадать туда может черте что. Или я опять флеймю по вашему?

NotGonnaGetUsМожно на пальцах? Я могу вас не верно истолковать :) можно. Фишка в том, что опять надо писать меньше кода. Вам так придется добавлять методы для каждого типа аргументов. Иногда это нереально. несколько примеров. Пример типизированный буффер. Ему могут передаваться типы для которых проканает обычное бинарное копирование, а могут передаваться и те для которых это не верно. Получется приблизительно такая картина.
Код: 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.
template<T>
struct isCopiable{
  enum { value = typelist::indexOf<PrimitiveTypes, const T>::value >  0  };
};

template<T>
struct isCopiable<T*>{
  enum { value = true };
};

template<int v>
struct Int2Type{
  enum{ value = v };
};

template<T>
class buffer{
  enum{ Copiable = isCopybale<T>::value !=  0  };

  // далее два метода которые покрывает ВСЕ ситуации
  // для любого типа буфферной переменной
  void Init( size_t n, const T& value, Int2Type<false> )
  {
    ....
  }

  void Init( size_t n, const T& value, Int2Type<true> )
  {
   ...
  }
public:
  explicit buffer( size_t n, const T& value = T() )
  {
    Init( n, value, Int2Type<Copiable> );
  }
}

прием достаточно просто, при подстановке типа скомпилируется только нужный в данной ситации метод. Нам не надо переписывать интерфейс этого класса для всех типов которые могут встретиться. Понимаешь? Вот еще примерчик
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
// допустим есть некий контейнер, членами которго могут быть как полиморфные типы так и нет
// нам надо иметь методы как для полиморфных, так и других типов
template<class T, bool isPolymorphic>
class Container
{
private:
  void DoSomething(T* pObj, Int2Type<true>)
  {
    T* temp = pObj->Clone();
    ....
  }

  void DoSomething(T* pObj, Int2Type<false>)
  {
    T* temp = new T(*pObj);
    ....
  }
public:
  void DoSomething(T* pObj)
  {
     DoSomething( pObj, Int2Type<isPolymorphic> );
  }
}
опять для каждого из классов которые будут передаваться шаблону, будет генерироваться нужный ему метод вызова. Идея понятна? Мы управляем процессом компиляции, это как RTTI только в статике. Инкапсулируя реализацию в шаблонные методы или классы мы можем сделать программу независящей от того какой тип используется. Более того мы можем использовать особенности того или иного типа, компилятор подставит нужную реализацию метода. Или создаст нудный метод или тип.

NotGonnaGetUsСлишком обще поставленна задача, без наглядной иллюстрации мне с вашими терминами не разобраться.

А кто будет этой "операцией" пользоваться?
Что представляет собой плагин?
Визитёр уже реализован в "трёх классах" или нет?
простите, я думал вы знаете что такое паттерн проектирования Визитер. Задача показалась вам общей. Вы смотрите совсем не на те условия. Я не злобный препод который стремится поставить в любом случае вам плохую оценку.

Основную суть я сказал. Повторю. Есть три класса Bitmap, VectorGraphics, textArea . Вы не можете менять их реализацию и структуру этих классов. Но вам позарез надо добавить еще одну функуиональность, например сохранение объектов этих классов в XML. В этих случаях, когда надо добавить функциональность во всю иерархию классов, а она закрыта (нельзя определить в базовом классе виртуальный метод), используется паттерн Визитер. Пусть доупстим это будет некая функция или метод класса, котору передается экземпляр этой иерархии и нудно для каждого реализовать что свое. Забыл самое главное - базовый класс этой закрытой иерархии Graphics. Таких условий достаточно?

реализацию самой функции мне не надо главное суть. что-то вроде этого
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
void SomeOperation(Graphics* p)
{
    if (TextArea* pTextArea = dynamic_cast<TextArea*>(p))
    {
        ... делаем что-то для TextArea ...
    }
    else if (VectorGraphics* pVectorGraphics =
        dynamic_cast<VectorGraphics*>(p))
    {
        ... VectorGraphics ...
    }
    else if (Bitmap* pBitmap = dynamic_cast<Bitmap*>(p))
    {
        ... Bitmap ...
    }
    else
    {
        throw "Unknown type passed";
    }
}
согласны с такой реализацией? что вы можете к этому добавить? какие в этой реализации недостатки? какие возможны улучшения? Завтра посмотрю на вашу реализацию и покажу как можно сделать при помощи шаблонов - пока!
...
Рейтинг: 0 / 0
C++ & Java
    #32856172
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl Сергей ИльичКем гарантируется ? Стандартом или конкретным компилятором ? гарантируется стандартом. вот вам пример из MSVC
Код: plaintext
1.
//{--SKIP--}
все замечательно работает.

Да, я видимо основывался на устаревших сведениях.

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 на удаленное хранилище данных,
дать ему там поработать, опять сериализовать и послать обратно с результатами.
...
Рейтинг: 0 / 0
C++ & Java
    #32856180
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwlОсновную суть я сказал. Повторю. Есть три класса Bitmap, VectorGraphics, textArea. Вы не можете менять их реализацию и структуру этих классов. Но вам позарез надо добавить еще одну функуиональность, например сохранение объектов этих классов в XML.

Конкретно для этого случая (Скинуть дамп объекта в виде XML) можно использовать reflection API. В иных случаях для добавления функциональности можно использовать wpapper.
...
Рейтинг: 0 / 0
C++ & Java
    #32856187
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lepsik Сергей ИльичО, Лепрозорик! Привет, проказник!

мы вроде бы не пили на брудершафт

А чего с лепросником на брудершафт пить - потом всю жизнь придется на бацилл проверятся.

Lepsik
Сергей Ильич
Ну, пусть будет так. Устами дилетантов глаголет истина.

Вообще это твой стиль - сыпать какими-то терминами типа "мультиметод, функтор, абстрактная фабрика, политика etc"

Это термины видимо дилетанты типа Алескандруску придумали, чтобы профессионалов мучать

Нет, наверное, чтобы кто-то восхищался своей элитарностью.

Lepsik
Не ошибусь, если скажу что 90% софта на вашем компьютере написано на С++.

--Мои рабочие тулзы - IDEA и Together - написаны на Java.

а остальные 95% программ на вашем компьютере ?

Там везде MS, COM и late binding, который суть корень всего зла.

Lepsik
только сначало надо сеть в песочницу с вами тыкать в каждый предмет и спрашивать как он называется на вашем языке.

Бедняга... Это ты так со всеми разговариваешь?

Lepsik
--Когда я был на курсах по Джаве, мой руководитель мне дал задание - сделать два потока - один будет

С++ я так понял тоже на уровне курсов остался ?
дожились - программирование на курсах изучают. После вождения грузовиков надо полагать ?

Могучий ЭпиLepsik никогда не ходил на курсы повышения квалификации - он и так крут.

Lepsik
Сергей Ильич
Показал отделу кадров - вместе посмеялись.
Они помнят, как по всему Питеру было не найти человека подходящего уровня. Искали год.
А компания у нас большая. Специализация - IT.

а вы как в IT сектор попали ? я так понял судя по курсам из другой отрасли ?

А у вас контора когда-нибудь подготавливает план развития сотрудника, оплачивает курсы?
Или вы там русиш рабы?

Lepsik
--Видимо могучий Лепсик пишет вообше без ошибок.

конечно бывают, как же без них ?

А может ты просто писать не умеешь?

Lepsik
честно говоря даже не знаю чего можно добавить к этим трем явно избыточным предложениям,
чтобы понять как правильно исключениями пользоваться.

В Java ты обязан либо ловить исключение, либо пихать его в сигнатуру метода.
Есть там и Фаталы, которые наследуются от RuntimeException. Их можно не ловить.
В C++ по ходу есть только фаталы.
...
Рейтинг: 0 / 0
C++ & Java
    #32856217
Lepsik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
---А чего с лепросником на брудершафт пить - потом всю жизнь придется на бацилл проверятся.

культура так и брыжжет. работать сразу после ПТУ пошли работать ?

Сергей Ильич
Ну, пусть будет так. Устами дилетантов глаголет истина.

Вообще это твой стиль - сыпать какими-то терминами типа "мультиметод, функтор, абстрактная фабрика, политика etc"
--Это термины видимо дилетанты типа Алескандруску придумали, чтобы профессионалов мучать

Нет, наверное, чтобы кто-то восхищался своей элитарностью.


то-то некоего Сергея Ильича в песочницу тыкают еще другом форуме по поводу "великих" знаний в теории баз данных. Из этих людей бы гвозди делать.

Сергей Ильич
--Не ошибусь, если скажу что 90% софта на вашем компьютере написано на С++.
--Мои рабочие тулзы - IDEA и Together - написаны на Java.
а остальные 95% программ на вашем компьютере ?
Там везде MS, COM и late binding, который суть корень всего зла.


типичный прием демагога - уход в стороны от темы. Ему про Фому а он про Еерму. Я про языки спрашивал, а не способы реализации. Очень похоже на линуксоидов - ненавидят виндовс, но пользуются только им.

Lepsik
только сначало надо сеть в песочницу с вами тыкать в каждый предмет и спрашивать как он называется на вашем языке.

--Бедняга... Это ты так со всеми разговариваешь?

да тут на форуме все с вами мучаются, отчаянно пытаясь понять ту свалку фраз что выплескиваются из вашей головы в форум.

--Могучий ЭпиLepsik никогда не ходил на курсы повышения квалификации - он и так крут.

как это громко звучит "курсы повышения квалификации". Я их в состоянии прослушать и сдать не вставая с компьютера.

--А у вас контора когда-нибудь подготавливает план развития сотрудника, оплачивает курсы?

да уже тонну прослушал и сдал.

---Или вы там русиш рабы?
Это что-то новое. Курсы для дилетантов стали признаком свободы.

--А может ты просто писать не умеешь?

Да уж за 20 лет научился поди.

--В Java ты обязан либо ловить исключение, либо пихать его в сигнатуру метода.

А вот в С++ я не обязан. Писать надо так, чтобы исключений не было.
Впрочем это проблемы жабы, там везде трахаться надо.
...
Рейтинг: 0 / 0
C++ & Java
    #32856244
c127
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
2 NotGonnaGetUs

>Для самых остроумных поясню. Речь о том, что не обязательно компилировать приложение, что бы получить сообщения об ошибке. IDE 99% ошибок возникающих на этапе компиляции подсвечивают при наборе кода.

Разве в c++ не тоже самое? Или с-шный код на бумаге всегда пишется правильно? :)


В том то и дело, что и сишный и джавовский код, написанный на бумаге не гарантирован от ошибок в соответсвии типов и пр. Итак имеем: этап написания кода завершен в полном объеме, а ошибки в соответсвии типов есть. Где же обещанные гарантии? (NotGonnaGetUs> Проверка типов гарантируется на этапе написания кода.)

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

К тому же это не аргумент, подозреваю в паскале, например, такие проверки можно осуществить в гораздо большем объеме, так что, теперь все переключаемся на паскаль?

>Речь не про IDE, а про ошибки на стадии компиляции.

Тут я уже не понял, раньше вроде речь шла об стадии написания кода (Проверка типов гарантируется на этапе написания кода ).
...
Рейтинг: 0 / 0
C++ & Java
    #32856362
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Многоуважаемый си127!
c127
NotGonnaGetUs
Для самых остроумных поясню. Речь о том, что не обязательно компилировать приложение, что бы получить сообщения об ошибке. IDE 99% ошибок возникающих на этапе компиляции подсвечивают при наборе кода.

В том то и дело, что и сишный и джавовский код, написанный на бумаге не гарантирован от ошибок в соответсвии типов и пр. Итак имеем: этап написания кода завершен в полном объеме, а ошибки в соответсвии типов есть. Где же обещанные гарантии? (NotGonnaGetUs> Проверка типов гарантируется на этапе написания кода.)

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

99.99% программистов пишут код не на бумаге, а в IDE. Возможно отдельные оригиналы набирают мегабайты кода в ноутпаде.
Вероятно вы решили, что являетесь оплотом этой могучей кучки... Всё проще! :)


Я понимаю, Вы хотели сказать, что в принципе возможна проверка некоторых правил до этапа компиляции, я с этим в принципе согласен (хотя есть проблема, теперь непонятно, что называть компиляцией).
Не некоторых - а практически всех. Это означает, что ни разу не возникло ситуации, когда IDE не отметила бы ошибку, а компилятор отметил.

Я потому и спросил как дела обстоят в C++. Мне кажется, что там действительно только "некоторые" правила проверяются из-за их сложности :)
Опровергните если это не так...


К тому же это не аргумент, подозреваю в паскале, например, такие проверки можно осуществить в гораздо большем объеме, так что, теперь все переключаемся на паскаль?

Задачи переключаться куда-либо не ставилось :)
Если вы ещё не припоминаете контекст из которого вытащили данное предложение, напомню.
Речь шла о generic в java и generic c++ - какие возможности у первого и второго: в чём разница, кроме проверки типов до/на этапе компиляции...


>Речь не про IDE, а про ошибки на стадии компиляции.

Тут я уже не понял, раньше вроде речь шла об стадии написания кода (Проверка типов гарантируется на этапе написания кода ).
[/quot]
Печально, что не поняли.
Речь всё время шла об ошибках выявляемых на стадии компиляции, что в случае java равносильно ошибкам выявляемым при написании/отладке кода в IDE.
...
Рейтинг: 0 / 0
C++ & Java
    #32856363
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Сергей ИльичА если в классе есть мандат на пользованием чем-то? Как его копировать? А если там какой-то хендл открытого ресурса? А если я пользуюсь статическими фабриками, чтобы кэшировать экземпляры объектов, и у меня все конструкторы находятся в закрытой секции класса?
Это вы приводите примеры классов которые нельзя хранить в динамическом массиве? Ну замечательно. Кстати, если у вас есть "мандатные" объекты, и только чтобы вовремя их разрушать все разрешается счетчиком ссылок - пример 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) реализация этой иерархии классов закрыта

Я даже дал определенный вариант реализации этой "задачки" и до сих пор жду ваших вариантов, чтобы потом показать как можно сделать при помощи шаблонов. Но вы упорн этого избегаете. Жаль. Значит я по умолчанию признаю, что тут вы признали свое поражение.
...
Рейтинг: 0 / 0
C++ & Java
    #32856365
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Сергей ИльичЕсли же зацепить какую-то хрень из std:: или boost::, начинает как снежный ком накапливаться огромное количество bullshit'a. Это потребует включения исключений. Т.е. исключение по вашему это зло? Насчет прочих обощений я пропущу мимо ушей потому что это просто ничего не значащие слова не подкрепленные практическими примерами.
...
Рейтинг: 0 / 0
C++ & Java
    #32856367
Фотография www.fun4me.narod.ru
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Far лучше любого IDE.
...
Рейтинг: 0 / 0
C++ & Java
    #32856397
alex_k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
www.fun4me.narod.ruFar лучше любого IDE.
подписался :-)
...
Рейтинг: 0 / 0
C++ & Java
    #32856541
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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.
 interface  Strategy<E> { 
     void  doSmth(E t);
}
 class  Container <E, S  extends  Strategy<E>> {
    Strategy s;

    Container(S s){
        this .s = s;
    }

     public   void  doSmth(E e) {
         if  (s!= null ) 
            s.doSmth(e);
         else  
            doDefaultSmth(e);
    }

     private   void  doDefaultSmth(E e){
        System.out.println("Default for all objects.");
    };

}

 class  StringImpl  implements  Strategy<String>{ //concrete impl
     public   void  doSmth(String s) {
        System.out.println("String");
    }
}
 class  IntegerImpl  implements  Strategy<Integer>{  //concrete impl
     public   void  doSmth(Integer i) {
        System.out.println("Integer");
    }
}
/**
 * Usage example.
 */
 public   class  Test { 
     public   static   void  main(String[] args) {
        Container<String, StringImpl> cString =   new  Container<String, StringImpl>( new  StringImpl());
        cString.doSmth("String");
       Container<Integer, IntegerImpl> cInteger =   new  Container<Integer, IntegerImpl>( new  IntegerImpl());
        cInteger.doSmth( 45 );
    }
}

В java generic является своего рода "инструкциями" для компилятора и отслужив своё они убираются из кода.
Т.е. С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.
void SomeOperation(Graphics* p)
{
    if (TextArea* pTextArea = dynamic_cast<TextArea*>(p))
    {
        ... делаем что-то для TextArea ...
    }
    else if (VectorGraphics* pVectorGraphics =
        dynamic_cast<VectorGraphics*>(p))
    {
        ... VectorGraphics ...
    }
    else if (Bitmap* pBitmap = dynamic_cast<Bitmap*>(p))
    {
        ... Bitmap ...
    }
    else
    {
        throw "Unknown type passed";
    }
}
согласны с такой реализацией? что вы можете к этому добавить? какие в этой реализации недостатки? какие возможны улучшения? Завтра посмотрю на вашу реализацию и покажу как можно сделать при помощи шаблонов - пока!
Если абстрактный визитор был таким:
[src java]
abstract class Visitor {
abstract void visit(Graphics g);
}[/src java], то придётся повторить ваш код, коль скоро изменить код Visitor'a мы не можем. Без проверки типа g в рантайм не обойтись.
Особенно если инстансы визитора создаются в рантайм, после считывания конфигурационного файла.

Будет интересно почитать, как вы хотели это сделать при помощи шаблонов.
...
Рейтинг: 0 / 0
C++ & Java
    #32856545
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex_k www.fun4me.narod.ruFar лучше любого IDE.
подписался :-)
Удачи обоим :)
...
Рейтинг: 0 / 0
C++ & Java
    #32856550
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NotGonnaGetUs
Если абстрактный визитор был таким:
Код: plaintext
1.
2.
 abstract   class  Visitor {    
     abstract   void  visit(Graphics g);
}
, то придётся повторить ваш код, коль скоро изменить код Visitor'a мы не можем. Без проверки типа g в рантайм не обойтись.
Особенно если инстансы визитора создаются в рантайм, после считывания конфигурационного файла.


"повторить ваш код", т.е. тем или иным образом вызывать нужный метод в зависимости от реального класса объекта g передаваемого в метод visit (который можно определить только в runtime). А как делать проверку в рантайм и переходить к нужному методу - это уже не принципиальный вопрос, или вы именно его задаёте?

Я сужу только со стороны java. Надеюсь на этой почве не доразумений не возникнет :)
...
Рейтинг: 0 / 0
C++ & Java
    #32856656
с127
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
2 NotGonnaGetUs

>99.99% программистов пишут код не на бумаге, а в IDE

Тут уже 2 человека заявили, что пишут программы в фаре. Я тоже пишу в фаре, плюс чингиз, итого 4 человека как минимум. Если исходить из Вашей оценки, что 4 посетителя форума это 0.01%, то на форуме должно тусоваться 40000 человек. Многовато получается. Тут необходимо предположить либо что форум аномально популярен среди любителей фара, либо что у Вас неадекватное восприятие действительности. Второе мне почему-то представляется более вероятным.

>Возможно отдельные оригиналы набирают мегабайты кода в ноутпаде.
Вероятно вы решили, что являетесь оплотом этой могучей кучки... Всё проще! :)


И сколько же мегабайтов кода Вы набрали за свою жизнь? Или Вы cut-paste интенсивно используете вместо вызова подпрограмм? И такая техника тоже есть.

>Не некоторых - а практически всех. Это означает, что ни разу не возникло ситуации, когда IDE не отметила бы ошибку, а компилятор отметил.

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

>Речь шла о generic в java и generic c++ - какие возможности у первого и второго: в чём разница, кроме проверки типов до/на этапе компиляции...

Не бывает этапа ДО компиляции. Компиляция первый этап обработки программы компьютером. То, что делает IDE, проверяя типы и выдавая Вам ошибки это и есть использование куска компилятора, встроенного в IDE.

В С++ и других языках такое тоже можно сделать, в каких-то IDE наверняка сделано, только ИМХО это бесполезное свойство. Как я уже говорил, в Паскале в этом смысле можно наворотить гораздо больше чем в джаве, потому что паскаль проще и строже, но это ничего не доказывает.
...
Рейтинг: 0 / 0
C++ & Java
    #32856750
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
NotGonnaGetUsпро флейм: мой вопрос был об отличиях generic С++ и java. Ващет изначально вопрос был про то (грубо говоря), а нужны ли ваще шаблоны. Было высказано мнение что они нафиг не нужны. О сравнении generic Java и шаблонов С++ я давал ссылку выше - посмотрите внимательно. Может почерпнете что ли бо инетересное. Что же касается обсждения вообще, то я старался придерживаться рамок аргументации использования generic programming, сторонники же Явы и Ильич в частности, чаще сводили разговор в сравнении языков (что считаю не уместным), теперь вот вы хотите сравнить шаблоны С++ и generic в Яве. Т.е. косвенно признаете ТУ МЫСЛЬ что я отстаивал - generic programming существует и во некоторых ситуациях эффективнее, чем ООП.

NotGonnaGetUsВ java generic является своего рода "инструкциями" для компилятора и отслужив своё они убираются из кода. Шаблоны С++ это тоже средство управление компиляцией, в часности созданием типов и функций на этапе компиляции.

NotGonnaGetUsВаш или мой код проще в дальнейшем модифицировать и использовать? :) не понимаю о чем речь. Что сравнивать то?

NotGonnaGetUsБез проверки типа g в рантайм не обойтись. Да полностью от нее не избавиться( хотя существуют и такие решения ). Но есть еще одно. Впервые предложенное Александреску.

Чтобы немного разобраться в сути этого решения, я позволю себе упомянуть, что благодаря комбинаторному подходу при сборке шаблонов, возможно создание такой штуки как список типов. Впервые идея создания списка типов пришла к нему при написании реализации фабрики. Обычное самое простое решение без регистрации типов:
Код: plaintext
1.
2.
3.
4.
5.
6.
class WidgetFactory{
public:
  virtual Window* CreateWindow() =  0 ;
  virtual Button*  CreateButton() =  0 ;
  virtual Scroller* CreateScroller() =  0 ;
};

Т.е. в данном кнкретном случае мы не смогли обощить тип Фабрика, и при реализации того или иного ПО, нам приходится писать различные фабрики. Спорить внутри проекта о соглашениях в интерфейсе, в написании имен методо и классов и прочее. Напрашивалось такое ОБОЩЕННОЕ решение
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
typedef Abstractactory<Window, Button, ScrollBar> WidgetFactory;

template<class T>
T* MakeWidget( WidgetFactory& factory )
{
  T* pW = Factory.Create<T>();
  pW->SetColor( RED );
  return pW;
}

Но вирутальные функции не могут быть шаблонными, потому что нельзя под одним типом(функцией) сочетать динамическое и статическое связывание. Однако списки типов придуманные Александреску сумели обойти эти ограничения (там еще были ограничения в указании аргументов шаблона ).

Код: plaintext
1.
2.
3.
4.
5.
6.
//  а вот и он список типов
template<class T, class U>
struct TypeList{
  typedef T head;
  typedef U tail;
};

Чтобы избежать таких записей
Код: plaintext
1.
2.
typedef typelist<float, typelist<double, long double> >
    floating_point_types;
Сначала былиз созданы макросы, а затем небольшие вспомогательные типы, в библиотеке boost они известны как boost::mpl::vector , у самого Алексанреску это струтура cons . Благодаря им можно делать так
Код: plaintext
1.
2.
typedef cons<float, double, long double>::type
    floating_point_types;

Теперь перейдем непосредственно к Визитеру, как я и говорил, полностью избавиться от рантайм проверки не получится (для этого есть решение 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.
template <class tlist> class AdHocVisitor;

template <class H, class T>
class AdHocVisitor< typelist<H, T> > 
    : public AdHocVisitor<T> // рекурсия
{
public:
    using AdHocVisitor<T>::Visit;
    virtual void Visit(H*) =  0 ;
    template <class SomeClass>
    void StartVisit(SomeClass* p)
    {
        if (H* pFound = dynamic_cast<H*>(p))
        {
            Visit(pFound);
        }
        else
        {
            AdHocVisitor<T>::StartVisit(p);
        }
    }
};

// остановка рекурсии
template <class H>
class AdHocVisitor< typelist<H, null_typelist> > 
{
public:
    virtual void Visit(H*) =  0 ;
    template <class SomeClass>
    void StartVisit(SomeClass* p)
    {
        if (H* pFound = dynamic_cast<H*>(p))
        {
            Visit(pFound);
        }
        else
        {
            throw "Unknown type passed";
        }
    }
};
Абстрактный визитер представляет из себя рекурсивный шаблон, с одно специализацией для последнего элемента списка типов. Чтобы вы поняли дальней ший ход мыслей выделю жирным помните я говорил о статической проверке наследования? так вот тут уместно ее использовать вместо DYNAMIC_CAST Для этого лучше передавать шаблону абстрактного визитера второй параметер Effector , который будет инстанцировать метод Visit для нужного типа. Приведу фрагмент чуть позже, пока пример использования того что написано.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
int main()
{
    typedef cons<TextArea, VectorGraphics,
        Bitmap>::type MyHierarchy;
    Graphics *p = new Bitmap;
    struct ConcreteVisitor : AdHocVisitor<MyHierarchy>
    {
        void Visit(TextArea* p) 
        {
            ... 
        }
        void Visit(VectorGraphics* p) 
        {
            ... 
        }
        void Visit(Bitmap* p) 
        {
            ... 
        }
    };
    ConcreteVisitor visitor;
    visitor.StartVisit(p);
}

Роберт Мартин в 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.
// отрывок из билиотеки LOKI
    template <class TList, typename R>
    class BaseVisitorImpl
        : public Visitor<typename TList::Head, R>
        
        , public Private::BaseVisitorImplHelper
          <
            typename TL::is_Typelist<typename TList::Tail>::type_tag
          >
          ::template In<typename TList::Tail, R>::Result
    {
        ASSERT_TYPELIST(TList);

    public:
        // using BaseVisitorImpl<Tail, R>::Visit;

        virtual R Visit(typename TList::Head&)
        { return R(); }
    };
Используя список типов можно сгенерировать класс внутри которого будет находится нужное кол-во методов Visit. Преобразование типов там остается, но онон применяется для внутренних классов визитеров. Фишка в чем, когда мы юзаем решение с множественным if else - его трудно сопровождать, существует вероятность ошибки с указанием более "старшего" класса раньше чем младшего. И многое другое. Генерация визитеров для каждого типа, позволяет "отвелься" о последовательность в указании типов

Код: plaintext
1.
typedef cons<TextArea,VectorGraphics,Bitmap>::type MyHierarchy;
все что нужно это добавить в typedef твой тип и написать функцию с этим типом. Об остальном позаботится компилятор управляемый шаблонами абстрактного визитера.

Лично МНЕ это решение кажется более гибким, чем решение содержащие кучу
if else . Более подробно решение Цикилического Везетера разбирается в книге Александреску, которую вы так обильно ругаете.
...
Рейтинг: 0 / 0
C++ & Java
    #32856756
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
с127Я тоже пишу в фаре, плюс чингиз, итого 4 человека как минимум.
Вам тоже удачи :)


И сколько же мегабайтов кода Вы набрали за свою жизнь? Или Вы cut-paste интенсивно используете вместо вызова подпрограмм? И такая техника тоже есть.

^_^


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

Конечно. Абсолютно всё.
В том числе автокомплит, переход на реализацию методов и т.п. очевидные вещи.


Не бывает этапа ДО компиляции. Компиляция первый этап обработки программы компьютером. То, что делает IDE, проверяя типы и выдавая Вам ошибки это и есть использование куска компилятора, встроенного в IDE.

У вас не бывает. А у нас бывает :) Отличается от компиляции тем - что ничего некопилируется, а проверятся синтаксис и существование классов/методов и т.д., происходит в online режиме.


В С++ и других языках такое тоже можно сделать, в каких-то IDE наверняка сделано, только ИМХО это бесполезное свойство. Как я уже говорил, в Паскале в этом смысле можно наворотить гораздо больше чем в джаве, потому что паскаль проще и строже, но это ничего не доказывает.
А это и не должно ничего доказывать.
Если что-то можно сделать, но этого не сделали - значит этого ещё нет.
Тем не мнее, очень рад за паскаль, только никак не могу понять причём он тут.
Но если вам интересно поговорить, то пожалйста. Можно завести отдельный топик на эту тему.
...
Рейтинг: 0 / 0
C++ & Java
    #32856766
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
списки типов вообще удивительная вещь. Хотя на мой взгляд проще их использование показать не на Визитерах, а на фабриках объектов. Точнее асбтрактных фабриках.
Код: 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.
//вот обычная обощенная фабрика
template
<
  class AbstractProduct, // базовый класс иерархии
  typename IdentifierType, // GUID имеет отношение порядка для std::map
  typename ProductCreator //  функтор создающий AbstractProduct
>
class Factory
{
public:
  bool Register( const IdentifierType& id, ProductCreator creator )
  {
    return asociations_.insert(
              AssocMap::value_type( id, creator)
                                      ).second;
  }
  bool Unregistered( const IdentifierType& id )
  {
    return asociations_.erase( id ) ==  1 ;
  }
  AbstractProduct* CreateObject( const IdentifierType& id )
  {
    typename AssocMap::const_iterator i = asociations_.find(id);
    if( i != asociations_.end() )
    {
      return ( i->second )();
    }
    // обработка ошибок пропущена
  }
private:
  typedef std::map< IdentifierType, AbstractProduct > AssocMap;
  AssocMap asociations_;
}
ничего особенно обощенный пример фабрики. В случае с Абстрактно фабрикой нам можно сгенерировать иерархию классов. Их связывание в иерархию фабрики и будет аналогом регистрации в обычной фабрике. Хотя сравнивать их нельзя

Код: 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.
template <typename T>
struct Type2Type
{
  typedef T OriginalType;
};

template < class T >
class AbstractFactoryUnit
{
public:
  virtual T* DoCreate( Type2Type<T> =  0  );
  virtual ~AbstractFactoryUnit() {};
};

template
<
  class TList, // список типов из которых генерируется иерархия
  template <class> class Unit = AbstractFactoryUnit
>
class AbstractFactory : public GenScatterHierarchy<TList, Unit>
{
public:
  typedef TList ProductList;
  template <class T> T* Create()
  {
    Unit<T>& unit = *this;
    return unit.DoCreate( Type2Type<T>() );
  }
};

Вопрос - что в ней такого плохого в этой реализации. (Я вырезал из ней классы стретегий отвечающие за обработку ошибок, за размещение в памяти и т.д.). Но что тут плохого, что вызвалорвотную реакцию у поклонник Явы? можно по пунктам?
...
Рейтинг: 0 / 0
C++ & Java
    #32856787
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Ну а для сравнения возможностей generic Явы и шаблонов С++, я уже предлагал задачку - создание УНИВЕРСАЛЬНОГО типа Функтор. Поясняю (цитируя Г.Саттера, недословно):

Функции или что-то ведущее себя как функции есть почти в любом языке программирования. В С++ это функции-члены, статические функции-члены, обычные функции (находящиеся в пространстве имен), и функторы (классы у которых перекрыт вызов оператора () ).

Когда дело доходит до простого обращения к ним все просто
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
// Example 1(a): Calling a nonmember function
//
string AppendA( string s ) { return s + 'a'; }
 
string test = "test";

// Making an immediate call is easy:
//
cout << AppendA( test ) << endl;             // immediate call

Однако, когда нам неизветсно либо ЧТО либо КОГДА вызывать, в дело вступают указатели, простейшим примером их использования является реализация callback функций (которых для Ильича почему-то не существует, как и generic programming):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
// Making a delayed call involves storing a pointer
// (or reference) to the function:
//
typedef string (*F)( string ); 
F f = &AppendA;                               // select function...
// ... later...
cout << f( test ) << endl;                    // ... make delayed call

Все вроде чудненько, однако 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.
// Example 1(b): Calling a member function
//
class B {
public:
  virtual string AppendB( string s ) { return s + 'b'; }
};

class Derived : public B {
  string AppendB( string s ) { return s + "bDerived"; }
};
 
string test = "test";
B b;
Derived der;

// Making an immediate call is easy:
//
cout << b.AppendB( test ) << endl;            // immediate call

// Making a delayed call involves storing a pointer
// (or reference) to the member function, and requires
// some appropriate object to call it on:
//
typedef string (B::*F)( string );
F f = &B::AppendB;                            // select function...
// ... later...
cout << (b.*f)( test ) << endl;               // ... make delayed call
cout << (der.*f)( test ) << endl;             // ... another delayed call,
                                              //   virtual dispatch works
Это решение обладает теми же недостатками, что и предыдущее, только в обратную сторону. Хотя нет вру. Здесь еще более жесткие ограничения - вызываться могут только члены класса B и его потомков. Кстати еще одна небольшая разница, в этом случае размер класса будет не один указатель, а три - адрес функции, адрес объекта, адрес виртаульной таблицы. Запомним это - нам оно пригодится.

Есть еще одно решение при помощи STL
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
/ Example  1 (b), continued: Alternative, using binders
//
typedef binder1st<mem_fun1_t<string,B,string> > F2;
F2 f2 = bind1st( mem_fun( &B::AppendB ), &b ); 
// ... later...
cout << f2( test ) << endl;                   // ... make delayed call

f2 = bind1st( mem_fun( &B::AppendB ), &der );
// ... later...
cout << f2( test ) << endl;                   // ... another delayed call,
                                              //  virtual dispatch works
Выглядит ОЧЕНЬ УРОДЛИВО, хотя мы избаивились от привязки к классу B , но не избавились от привязки к сигнатуре. Но есть еще одна "яма".

Код: 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.
// определим функтор, который будет "конфликтовать" с нашим решением
class C {
public:
  string operator()( string s ) { return s + 'c'; }
};
 
string test = "test";
C c;

// Making an immediate call is easy:
//
cout << c( test ) << endl;                    // immediate call

// Making a delayed call is trickier. There's no easy way without
// fixing the type of the object as a C, such as by taking a C&...:
//
typedef C& F;
F f = c;                                      // select functor...
// ... later...
cout << f( test ) << endl;                    // ... make delayed call

...

// пример конфликта
class Name {
public:
  Name( string s ) : s_( s ) { }
  string Get() const { return s_; }

private:
  string s_;
};

// Stubbed-in function to demonstrate varying
// parameter and return types:
const char* AppendD( const Name& s ) {
  static string x;
  x = s.Get() + 'd';
  return x.c_str();
}
 
string test = "test";

// Making an immediate call is still easy:
//
cout << AppendD( test ) << endl;              // immediate call

// But the typedef from Example 1(a) no longer works,
// even though the rest of the call is unchanged:
//
typedef string (*F)( string ); 
F f = &AppendD;                               // error: type mismatch
// ... later (in our dreams)...
cout << f( test ) << endl;                    // ... never get here
вот они вторые грабли связанные с допустимым неявным преобразованием типов аргумента.

Итак, вот вам ЗАДАЧА - определить тип, который может содержать в себе ссылку(указатель) на ЛЮБОЙ функциональный объект или функцию, или функцию-член, или статическую функцию. Этот тип не должен иметь перечисленных выше недостатков и уметь хранить в себе любые сигнатуры функций или функторов. Я уже предлагал такую задачку на первых страничках этого флейма.

Но Ильич очень умело ушел от первичной постановки задачи на конкретику удобную ему. Поэтому я просто повторяю свой вопрос - насколько возможно создание такого типа в Яве.

В С++ такая задача была решена в типа 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.
// Example 1(e): One function<> to bring them all,
// and flexibly to bind them
//
// This code uses the same class and function definitions
// from Examples 1(a) through (d)
//
string test = "test";
B b;
Derived der;
C c;

function<string (string)> f;                  // can bind to anything that
                                              // takes and returns a string
f = &AppendA;                                 // bind to a free function
cout << f( test ) << endl;

f = bind1st( mem_fun( &B::AppendB ), &b );
cout << f( test ) << endl;// bind to a member function
f = bind1st( mem_fun( &B::AppendB ), &der );
cout << f( test ) << endl;                    // with virtual dispatch

f = c;                                        // bind to a functor
cout << f( test ) << endl;

f = &AppendD;                                 // bind to a function with a
cout << f( test ) << endl;                    // different but compatible signature

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

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
function<int (int x, int y)> arithmetic_operation(char k)
{
  switch (k) {
    case '+': return plus<int>();
    case '-': return minus<int>();
    case '*': return multiplies<int>();
    case '/': return divides<int>();
    case '%': return modulus<int>();
    default: assert( 0 );
  }
}

привести шаблон Observer для демонстрации ?

ЗЫЖ жду ответа - реализацию function в Яве.
...
Рейтинг: 0 / 0
C++ & Java
    #32856863
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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.
 import  java.lang.reflect.Method;
 import  java.lang.reflect.InvocationTargetException;

 class  Visitor{
     final   public   void  visit(Graphics graphics) {
         Class  clazz = graphics.getClass();
        Method visitClazz;
         try  {
            visitClazz =  this .getClass().getMethod("visit",  new   Class []{clazz});
        }  catch  (NoSuchMethodException e) {
            //use default behaviour
            visitUnkown(graphics);
             return ;
        }
         try  {
            visitClazz.invoke( this , graphics);
        }  catch  (IllegalAccessException e) {
            e.printStackTrace(); //unreachable code, access for method deny. 
            visitUnkown(graphics);
        }  catch  (InvocationTargetException e) {
            e.printStackTrace(); //exception inside visitClazz method.
        }
    }

     protected   void  visitUnkown(Graphics graphics) {
        //default realization
    }
}

//graphics hierarchy
 class  Graphics {
     void  accept(Visitor v){
        v.visit( this );
    }
}

 class  Bitmap  extends  Graphics{}
 class  TextArea  extends  Graphics{}
 class  TextField  extends  TextArea{}
 class  Button  extends  Graphics{}

//visitors hierarchy
 class  AVisitor  extends  Visitor{
     public   void  visit(Bitmap g){
        System.out.println("A-Visitor: " + g.getClass() + ".");
    }
     public   void  visit(TextArea g){
        System.out.println("A-Visitor: " + g.getClass() + ".");
    }
}

 class  BVisitor  extends  AVisitor{
     public   void  visit(Bitmap g){
        System.out.println("B-Visitor: " + g.getClass() + ".");
    }
}
/**
 * Usage example
 */             
 public   class  VisitorTest {
     public   static   void  main(String[] args){
        Visitor v =  new  BVisitor();
         new  Bitmap().accept(v);
         new  TextArea().accept(v);
    }
}

Вот если често, что вы глядит проще в данном случае, ваши темплейты или код java? :)
Или может быть в итоге получилась разная функциональность?
...
Рейтинг: 0 / 0
C++ & Java
    #32856870
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwlИтак, вот вам ЗАДАЧА - определить тип, который может содержать в себе ссылку(указатель) на ЛЮБОЙ функциональный объект или функцию, или функцию-член, или статическую функцию. Этот тип не должен иметь перечисленных выше недостатков и уметь хранить в себе любые сигнатуры функций или функторов. Я уже предлагал такую задачку на первых страничках этого флейма.

ЗЫЖ жду ответа - реализацию function в Яве.

Для java это не задача :) Рефлекшин (стандартная библиотека) позволяет выдрать любой метод класса, как объект java.lang.reflect.Method.
...
Рейтинг: 0 / 0
C++ & Java
    #32856886
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
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
typedef cons<Graphics, Bitmap, TextArea> MyIerarhy; 
. Можно узнать без привязки к флейму о языках, что вы видете тут сложного?

Далее определение конркетного списка типов позволяет определить множество только тех объектов из иерархии, которые подлежат визитированию. Например, если появится тип TLine , то мы можем не определять для него визитера а просто игнорировать. в вашем случае придется делать пустышку, потому как вы написали в базовом классе метод accept, то есть он будет(ну или должен быть) у всех потомков. ПРедставим что там иерархия из 25 классов, а нам нужно провизитировать только ТРИ.

Вобчем повторю главное - иерархия закрыта.

Ну если она открыта, то конечно я ничего не имею против циклического визитера что вы написали. за исключением тех оговорок о более слабой защите типов (сигнатуры метода) и т.д., которые я привел выше.


NotGonnaGetUsДля java это не задача :) Рефлекшин (стандартная библиотека) позволяет выдрать любой метод класса, как объект java.lang.reflect.Method Это не решение.
1) переменной типа Method можно присвоить функции разных сигнатур. Тип function не даст этого сделать.
2) переменная Method - это rtti (ничего не имею против), т.е. динамическое связывание. в случае с function мы имеем статическую проверку типов.
3) я не знаю как вы будете сравнивать две переменные Method, потому что существует возможность что одна из них показывает на функцию совсем с другой сигнатурой.
...
Рейтинг: 0 / 0
C++ & Java
    #32857009
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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.
//base visitor
 class  Visitor <E> {
     private  HashMap< Class <?  extends  E>, IVisitor<?  extends  E>> map =
             new  HashMap< Class <?  extends  E>, IVisitor<?  extends  E>>();

     final   protected  <T  extends  E>  void  add( Class <T> clazz, IVisitor<T> visitor) {
        map.put(clazz, visitor);
    }

     final   protected  <T  extends  E>  void  remove( Class <T> clazz) {
        map.remove(clazz);
    }

     final   public  <T  extends  E>  void  visit(T t) {
        IVisitor visitor = map.get(t.getClass());
         if  (visitor !=  null ) visitor.visit(t);
    }

     protected   interface  IVisitor <T> {
         void  visit(T g);
    }
}

//concrete visitor for Graphics hierarchy.
 class  SomeVisitor  extends  Visitor<Graphics> {
    {
        add(Bitmap. class ,  new  IVisitor<Bitmap>() {
             public   void  visit(Bitmap bitmap) {
                System.out.println("for-Bitmap  : " + bitmap.getClass() + ".");
            }
        });
        add(TextArea. class ,  new  IVisitor<TextArea>() {
             public   void  visit(TextArea textArea) {
                System.out.println("for-TextArea: " + textArea.getClass() + ".");
            }
        });
    }
}
//grapgics hierarchy
 class  Graphics {}
 class  Bitmap  extends  Graphics {}
 class  TextArea  extends  Graphics {}
 class  TextField  extends  TextArea {}
/**
 * Usage example
 */
 public   class  VisitorTest {
     public   static   void  main(String[] args) {
        Visitor<Graphics> visitor =  new  SomeVisitor();
        visitor.visit( new  Bitmap());
        visitor.visit( new  TextArea());
        visitor.visit( new  TextField());
    }
}

С вашей помощью, я получил ответ на интересовавший меня вопрос.
Спасибо :)
Думаю можно смело прекрщать наш "флейм" на тему 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.И., а теперь опять превращаюсь в читателя :)
...
Рейтинг: 0 / 0
C++ & Java
    #32857244
awson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сергей ИльичПрограмму на 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 сойдет).
...
Рейтинг: 0 / 0
C++ & Java
    #32857316
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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) реализация этой иерархии классов закрыта

Если не доступен корень, то функциональность не добавить никак. Ни в Яве, ни в С++.
Если мне, как руководителю проекта С++, кто - нибудь принесет такое извращение, я заставлю переписать.
Если я буду рядовым участником комманды, я напишу враппер, как бы я это сделал на Джаве. И никто не заметит.
...
Рейтинг: 0 / 0
C++ & Java
    #32857428
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
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 и изящества указателей на функции - признаки восторженного неофита. Вряд ли я ошибаюсь.
Вот глупый человек! Просто непроглядно! Я показал код, рассказал аргументы в пользу такого подхода. все по полочкам. попрошу и вас дорогой пустомеля привести примеры (аргументы вашего бреда).

Насчет писания кипятком - вы навероне рядом с туалетом работаете. вам показалось. сто раз говорил, что любое решение обладает плюсами и минусами. и что как не крути существуют ситуации, когда шаблоны жффективно дополняют парадигму ООП. примеры я устал уже приводить. а ваши голословные бредни мне уже надоели.
...
Рейтинг: 0 / 0
C++ & Java
    #32857443
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
awson Сергей ИльичПрограмму на OCaml кстати, можно статически скомпилировать в машинный код, и язык этот строго типизирован.

Там, кстати, нет уборки мусора, но управление памятью там сделано более по уму.

У OCaml'а ЕСТЬ сборка мусора. Безо всяких "более по уму".

Библиотека fftw (FaStest FOurier Transform in the West) была написана не НА ML, а С ПОМОЩЬЮ ML (точнее, OCaml), который использовался для генерации специализированного исходного кода.


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

awson
Мне кажется, "ранний" C++ (до появления современной трактовки шаблонов как инструментов
метапрограммирования) произвел непоправимое повреждение в умах. Если ad hoc полиморфизм
(overloading) был вполне себе насущен и уместен, то реализация как бы true полиморфизма
(на самом деле - убогой пародии на него) с помощью механизма наследования и виртуальных
функций - породила целое поколение людей, которые, в определенном смысле, уже безнадежны.
Я это, отчасти, знаю по себе.


Хм, не знаю. Помню, в fido7.ru.c-cpp приходил некто Виталий Луговский, который говорил что
ООП - говно, поскольку нет никакой гарантии, что виртуальная функция будет делать то, что
она должна делать, исходя из требований к интерфейсу.

С такой проблемой Джависты сталкиваются и решают это с помощью JUnit-тестов.
Там мы пишем тесты, насколько поведение подсистемы соответствует требованиям.
Как такие проверки делаются в системах, построенных на статических правилах, я не видел.

awson
Все эти ужимки и прыжки с "делегатами" и бог знает чем еще - борьба с ветряными мельницами.
Выкиньте в помойку "объекты" с "наследованием" и проблемы исчезнут как утренний туман
(ВАЖНОЕ ЗАМЕЧАНИЕ - в современном C++ все это используется, но для совершенно других целей
- а именно, как инструмент реализации функционального языка шаблонов,
интерпретируемого во время компиляции; здесь не должно быть путаницы
- слова остались те же, но смысл изменился).

Если делегаты придумал Микрософт, то в них может быть есть смысл. В Микрософте работают
талантливые архитекторы.

По поводу ООП... Если писать программу по принципу
намазал кирпич раствором - положил в кладку - намазал кирпич раствором - положил в кладку - etc
то через некоторое время обнаруживаешь, что задача решена.

Если же иметь какой-то паззл, в котором все зависит от всего, то задачу можно и не решить.
Особенно, когда нет import'ов и приходится проектировать заодно топологию включений.

awson
Я жабц не знаю, никогда на ней ничего не писал, чтение исходников на нем вызывает у меня почти непреодолимое отвращение.

Очень легко читается. К тому же легко анализируется компьютером.

awson
Все это давно не новость в академической среде, но впервые это было (насильно) внедрено на промышленном уровне.
И это серьезный шаг вперед. Но САМ ЯЗЫК - худший из компонентов жабы как платформы.

В последнее время я почему-то стал сторонником разработки языков по административной команде и конкретному ТЗ.
Как, например была создана Ада. Идея должна быть целостной.
...
Рейтинг: 0 / 0
C++ & Java
    #32857449
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
awson Сергей ИльичПрограмму на OCaml кстати, можно статически скомпилировать в машинный код, и язык этот строго типизирован.

Там, кстати, нет уборки мусора, но управление памятью там сделано более по уму.

У OCaml'а ЕСТЬ сборка мусора. Безо всяких "более по уму".

Библиотека fftw (FaStest FOurier Transform in the West) была написана не НА ML, а С ПОМОЩЬЮ ML (точнее, OCaml), который использовался для генерации специализированного исходного кода.


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

awson
Мне кажется, "ранний" C++ (до появления современной трактовки шаблонов как инструментов
метапрограммирования) произвел непоправимое повреждение в умах. Если ad hoc полиморфизм
(overloading) был вполне себе насущен и уместен, то реализация как бы true полиморфизма
(на самом деле - убогой пародии на него) с помощью механизма наследования и виртуальных
функций - породила целое поколение людей, которые, в определенном смысле, уже безнадежны.
Я это, отчасти, знаю по себе.


Хм, не знаю. Помню, в fido7.ru.c-cpp приходил некто Виталий Луговский, который говорил что
ООП - говно, поскольку нет никакой гарантии, что виртуальная функция будет делать то, что
она должна делать, исходя из требований к интерфейсу.

С такой проблемой Джависты сталкиваются и решают это с помощью JUnit-тестов.
Там мы пишем тесты, насколько поведение подсистемы соответствует требованиям.
Как такие проверки делаются в системах, построенных на статических правилах, я не видел.

awson
Все эти ужимки и прыжки с "делегатами" и бог знает чем еще - борьба с ветряными мельницами.
Выкиньте в помойку "объекты" с "наследованием" и проблемы исчезнут как утренний туман
(ВАЖНОЕ ЗАМЕЧАНИЕ - в современном C++ все это используется, но для совершенно других целей
- а именно, как инструмент реализации функционального языка шаблонов,
интерпретируемого во время компиляции; здесь не должно быть путаницы
- слова остались те же, но смысл изменился).

Если делегаты придумал Микрософт, то в них может быть есть смысл. В Микрософте работают
талантливые архитекторы.

По поводу ООП... Если писать программу по принципу
намазал кирпич раствором - положил в кладку - намазал кирпич раствором - положил в кладку - etc
то через некоторое время обнаруживаешь, что задача решена.

Если же иметь какой-то паззл, в котором все зависит от всего, то задачу можно и не решить.
Особенно, когда нет import'ов и приходится проектировать заодно топологию включений.

awson
Я жабц не знаю, никогда на ней ничего не писал, чтение исходников на нем вызывает у меня почти непреодолимое отвращение.

Очень легко читается. К тому же легко анализируется компьютером.

awson
Все это давно не новость в академической среде, но впервые это было (насильно) внедрено на промышленном уровне.
И это серьезный шаг вперед. Но САМ ЯЗЫК - худший из компонентов жабы как платформы.

В последнее время я почему-то стал сторонником разработки языков по административной команде и конкретному ТЗ.
Как, например была создана Ада. Идея должна быть целостной.
...
Рейтинг: 0 / 0
C++ & Java
    #32857486
Фотография www.fun4me.narod.ru
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну шаблоны в Java вполне можно добавить. Вот, хотя бы, как здесь: ссылка .
...
Рейтинг: 0 / 0
C++ & Java
    #32857514
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
Да я и не спорю. Просто тут некототрые стари беспреколсовно и не аргументированно утверждать что шаблоны в программировании ваше не нужны и что это зло.

А вообще не думаю, что этот разговор получит нормальное продолжение вобчем-то я тоже для себя все выяснил. мало что поменялось что для меня в моем отношении к generic programming.

так что я умываю руки. пусть здесь сотрясают воздух другой.
...
Рейтинг: 0 / 0
C++ & Java
    #32857563
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
NotGonnaGetUs
Информация, которая может тебя заинтересовать почитай .

Относительно сравнения дженериков и шаблонов. Кстати интересный пример оттуда
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
Collection<A> c;
...
c.init().next() ...
becomes
Collection c;
...
(A)(c.init().next())...
т.е. по сути Ява дженерик не является statically type safe in the simplest form . Отсюда и ограничения, коротко и ясно
автор
- cannot inherit from a type parameter (no mixins)
- cannot cast to a type parameter
- cannot construct an object
- originally could not read member classes
from a type parameter
...
Рейтинг: 0 / 0
C++ & Java
    #32857565
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
NotGonnaGetUs
Кстати лично для себя хочу спросить насколько близко к правде это утверждение:
авторThe container library in Java was poorly designed. Just a few obvious example. Elements are copied into a temporary array from ArrayList in order to be sorted and then copied back -- this defeats the very intention of using array as the container.
...
Рейтинг: 0 / 0
C++ & Java
    #32857600
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwlThe container library in Java was poorly designed. Just a few obvious example. Elements are copied into a temporary array from ArrayList in order to be sorted and then copied back -- this defeats the very intention of using array as the container.
Он копирует во временный массив указатели, а не сами объекты.
Зато можно сортировать LinkedList, несмотря на то что он не поддерживает random-доступ. (n + 1) * log (n).
...
Рейтинг: 0 / 0
C++ & Java
    #32857605
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl NotGonnaGetUs
Кстати лично для себя хочу спросить насколько близко к правде это утверждение:
авторThe container library in Java was poorly designed. Just a few obvious example. Elements are copied into a temporary array from ArrayList in order to be sorted and then copied back -- this defeats the very intention of using array as the container.

Сортировка это o(n*logn) минимум.
Создание копии массива o(n) - елементы не копируются, копируются ссылки на них, причём для этого используется native реализация клонирования массивов, т.е. чертовски быстрая :)
В итоге, если что и тратится зря, то только n*8 байт памяти на временный массив.

Если вообще говорить про List, то это абстрактный интерфейс.
Он определят своего рода "динамический массив".
Существуют различные реализации этого интерфейса.
ArrayList реализует List как враппер над обычным массивом.
LinkedList - как двухсвязный список.
Есть синхранизрованный листы (безопасные при мультисрединг использовании), есть не модифицируемые листы и т.д.

Соответственно каждая из реализаций имеет свои плюсы/минусы по времени на добавление/поиск/изменение элементов и в зависимости от этого выбирается алгоритм сортировки (методом сортировки коллекций, а не программистом :)).
...
Рейтинг: 0 / 0
C++ & Java
    #32857608
awson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сергей Ильич
Если делегаты придумал Микрософт, то в них может быть есть смысл. В Микрософте работают талантливые архитекторы.

Ну да, если стоишь на голове даже для простых телодвижений требуются выдающиеся таланты.

STL потому и была революционна (с точки зрения кондового ООП), что отвинтила алгоритмы от данных, то бишь это самое ООП попросту похерила.

Сергей Ильич
По поводу ООП... Если писать программу по принципу
намазал кирпич раствором - положил в кладку - намазал кирпич раствором - положил в кладку - etc
то через некоторое время обнаруживаешь, что задача решена.

Если же иметь какой-то паззл, в котором все зависит от всего, то задачу можно и не решить.
Особенно, когда нет import'ов и приходится проектировать заодно топологию включений.

Аналогия с кирпичами, на мой взгляд, совершенно не подходит к ООП, где картина локально может быть абсолютно не понятна. Нужно лезть выяснять, кто где чего накурочил по иерархии.

А как раз для функционального программирования она работает на 100%. Я вижу функцию, и мне больше НИЧЕГО не нужно знать. ВООБЩЕ. По определению.

Сергей Ильич
Очень легко читается. К тому же легко анализируется компьютером.

Дико раздражает verbosity. На каждый чих - километры текста. Это при том, что, типа, язык более высокого уровня, чем, например, С.
...
Рейтинг: 0 / 0
C++ & Java
    #32857628
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl NotGonnaGetUs
Информация, которая может тебя заинтересовать почитай .

Относительно сравнения дженериков и шаблонов. Кстати интересный пример оттуда
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
Collection<A> c;
...
c.init().next() ...
becomes
Collection c;
...
(A)(c.init().next())...
[/quot]

Это не провакация, а не пример :)
Код: plaintext
1.
2.
3.
4.
      Collection<Integer> c =  new  ArrayList<Integer>();
      Integer i = c.iterator().next(); - ok
      String s = c.iterator().next(); - compile error;
      String s = (String)c.iterator().next(); - compile error;
...
Рейтинг: 0 / 0
C++ & Java
    #32857632
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NotGonnaGetUsЭто не провакация, а не пример :)

первое не лишнее :)
...
Рейтинг: 0 / 0
C++ & Java
    #32857660
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl NotGonnaGetUs
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
Collection<A> c;
...
c.init().next() ...
becomes
Collection c;
...
(A)(c.init().next())...

А, они о том, что в после компиляции код првращается в код с кастом.
А где тут проблема? :) Безопасность этого каста проверена на стадии компиляции.
...
Рейтинг: 0 / 0
C++ & Java
    #32857707
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
NotGonnaGetUsА где тут проблема? :) Безопасность этого каста проверена на стадии компиляции.
Нет. вот тут не соглашусь. и не только я, но и доки.

1) Т.к. все классы суть ссылки(указатели),
2) все они наследуются от "нетипизированного" указателя на базовый супер-класс

поэтому на этапе компиляции проверяется правомочность таких преобразований (ну например в С++ там всякие проверки размеров типов). А остальное будет происходить в рантайм. Для таких целей например в С++ было создано преобразование static_cast, которое полность выполняется на стадии компиляции.

в случае обычных C-style преобразований, не происходит полной провероки типов. Например в каком-то месте программы у тебя стоит
Код: plaintext
1.
2.
3.
4.
5.
Base *b;
//... что-то тут происходит заполняющее b например Derived2
Derived1 *d = (Derived*)(b);
//...далее опять программа живет своим путем
d->derived1method(); // однако указатель d как и b указавать будет в результате выполнения на совсем другой тип у которого этого метода быть не может
ясна проблема? поэтому на этапе компиляции происходит ПОЧТИ чисто синтаксическая проверка. и в описанном мной примере компилятор не ругнется но при выполнении программы будет исключение.

Это и есть механизм позднего связывания о котором я так долго талдычил. Выснилось вы его по разному понимаем. Так вот, все преобзразование типов, кроме POD и static_cast, это откладывание проверки типов на этап рантайм. я не буду говорить слово "поверьте", вы не поверите. 8-)))

жаль конечно, могу надеется что кто-нить проверит (а не подгонит результат).
...
Рейтинг: 0 / 0
C++ & Java
    #32857858
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl
1) Т.к. все классы суть ссылки(указатели),

Если мы говорим Java, то все классы - суть классы. А переменные - суть указатели классы.

2) все они наследуются от "нетипизированного" указателя на базовый супер-класс

Все классы наследники класса Object.


поэтому на этапе компиляции проверяется правомочность таких преобразований (ну например в С++ там всякие проверки размеров типов). А остальное будет происходить в рантайм.

Не надо путать поведение с реализацией. Компилятор не позволит написать код, который выкинит в рантайм классКастЭксепшин.


Например в каком-то месте программы у тебя стоит
Код: plaintext
1.
2.
3.
4.
5.
Base *b;
//... что-то тут происходит заполняющее b например Derived2
Derived1 *d = (Derived*)(b);
//...далее опять программа живет своим путем
d->derived1method(); // однако указатель d как и b указавать будет в результате выполнения на совсем другой тип у которого этого метода быть не может
ясна проблема? поэтому на этапе компиляции происходит ПОЧТИ чисто синтаксическая проверка. и в описанном мной примере компилятор не ругнется но при выполнении программы будет исключение.

Это С. В Java нет не типизированных переменных.
Вот код аналогичный вашему:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
 class  B{}
 class  SubB  extends  B {}
 class  D {
   void  method();
}
... 
B b =  new  SubB();
D d = (D)b; 
d.method();
Данный код скомпилируется только, если D - находится в одно иерархии с В (т.е. является наследником или предком В).
А в рантайм ошибка произойдёт на строчке (D)b, а не d.method().
Тем не менее к generic этот пример не имеет отношения.
Компилятор вставит добавит каст (D)b, только если будет 100% уверенность, что объект на который указывает b это инстанс D.
Сделать каст статическим, значит пересобирать исходный класс (объявленный с темплейтами) при каждом новом его использовании. В java этого нет.
В случае если есть РЕАЛЬНАЯ необхожимость генерить классы по шаблонам, нужно использовать механизм аннотаций. Они расширяют функциональность языка без усложнения синтаксиса языка и компилятора. Что на мой взгляд большой плюс.


жаль конечно, могу надеется что кто-нить проверит (а не подгонит результат).
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
        Collection<Integer> c =  new  ArrayList<Integer>();
        c.add( 4 );

        Collection bad = c;
        bad.add( new  Object());

         for (Integer i: c){
            System.out.println("i:" + i);
        }
Получим рантайм exception в цикле.
Прична - использования не параметризованной коллекции.
Отказ от параметризации сразу переносит ответственность с компилятора на разрабочика - ничего неожиданного.
Такова цена отказа от пересборки классов.
Было бы неожиданно, если прошла такая запись:
Collection<Object> bad = c;

Можно на это ругаться, можно этим гордиться. Зависит от желания :)
Истина заключена в том, что не нужно понимать инструмент, который используешь.
...
Рейтинг: 0 / 0
C++ & Java
    #32857866
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NotGonnaGetUsИстина заключена в том, что не нужно понимать инструмент, который используешь.

Что сегодня меня на лишнии "не" потянуло %) Это опечатка!
...
Рейтинг: 0 / 0
C++ & Java
    #32857916
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
NotGonnaGetUsДанный код скомпилируется только, если D
вы немного меня не поняли. Опишу подробней
1) есть базовый класс B
2) есть два наследника D1 и D2
3) у D1 есть method1() у D2 соответсвенно method2()
4) создаем в перемнной типа B объект типа D2
5) в переменную типа D1 преобразуем переменную B
6) вызываем method1

получается такой, что компилятор его пропустит, а рантайм сгенерит исключение. Этот пример я привел лишь к тому, чтобы сказать что преобразование типов - есть динамическое связывание. Т.е. это не строгая статическая проверка типов, как с шаблонами С++. Вот вам и еще разница.
...
Рейтинг: 0 / 0
C++ & Java
    #32857944
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl1) есть базовый класс B
2) есть два наследника D1 и D2
3) у D1 есть method1() у D2 соответсвенно method2()
4) создаем в перемнной типа B объект типа D2
5) в переменную типа D1 преобразуем переменную B
6) вызываем method1

получается такой, что компилятор его пропустит, а рантайм сгенерит исключение.

Вы смешиваете каст и шаблоны.
Generic java реализуется по средством "безопасного" runtime cast'a.
Но это не значит, что сравнивая generic и темплейты, нужно заменять generic на runtime каст. Это рантайм каст, но его допустимость проверена на этапе компиляции.


Этот пример я привел лишь к тому, чтобы сказать что преобразование типов - есть динамическое связывание. Т.е. это не строгая статическая проверка типов, как с шаблонами С++. Вот вам и еще разница.

Разница меджду чем и чем? Если между кастом и темплейтами, то вот пример.
Библиотечный класс. Некий его метод имеет тип возвращемого аргумента В.
На практике он возвращает одного из наследников - D1 или D2. Затем нужно вызывать метод1 или метод2.
Не меняя библиотечный класс замените динамический каст(или выяснение типа в runtime) на статический при помощи чего угодно.
Это не возможно. Потому что на этапе компиляции В ПРИНЦИПЕ нельзя узнать какой же объект будет возвращён (пусть это зависит от нажатия клиентом кнопки в веб браузере).
Шаблоны тоже не всемогущи :)
...
Рейтинг: 0 / 0
C++ & Java
    #32857960
dwl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
dwl
Гость
NotGonnaGetUsРазница меджду чем и чем?
то о чем вы спрашивали - между дженериками явы и шаблонами С++( кстати и дженериками C# ). Правда у последних нет специализации и они инстанцируются полностью для указанных типов. Хотя на уровне IL дружат с шаблонами С++. Вобчем то, что я упомянул плюс еще 4 различия (я их просто упоминаю чтобы подвести ИТОГ различий, а не чтобы выделить чьи-то преимущества или недостаки. пусть это вас не задевает)
- нельзя наследовать от аргумента шаблона
- нельзя кастовать от аргумента шаблона в другой тип
- нельзя контруировать класс
- нельзя читать членов класса аргумента шаблона

спасибо за дополнительную инфу. всегда рад подучиться. т.к. я известный неофит. 8-)))
...
Рейтинг: 0 / 0
C++ & Java
    #32857973
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
awson
STL потому и была революционна (с точки зрения кондового ООП), что отвинтила алгоритмы от данных, то бишь это самое ООП попросту похерила.

Сорри, я опять со своей java'ой влезу.

Возможно я не уловил что есть "кондовсое ОПП". Может его и правда надо похерить раз и навсегда, сути это всё равно неменяет.

Алгоритм нельзя отвинтить от данных, хотя бы потому, что он с этими данными работает.
Похоже революция для С-комунити была в том, что привязка к классу заменилась привязкой к сигнатуре метод(а/ов) которые в этом классе реализованны.
Мощно!
И cмешнo, если смотреть на это со стороны java, где существует такое понятие как интерфейсы.
Со стороны, как вы вырзились, "монстрообразного промышленного воплощения идей ООП", которые должны быть убиты "алгоритмами, отвязанными от данных"! :)


Аналогия с кирпичами, на мой взгляд, совершенно не подходит к ООП, где картина локально может быть абсолютно не понятна. Нужно лезть выяснять, кто где чего накурочил по иерархии.

Если кирпичи кладутся как попало, и дом строится на песке, а не надёжном фундаменте - то дома не получится - вы правы.
Что бы называть себя строителем, не достаточно знать, что существуют кирпичи, нужно уметь их класть %)
Такому строителю, лучше продолжить рыть землянки новым савочком :)


Дико раздражает verbosity. На каждый чих - километры текста. Это при том, что, типа, язык более высокого уровня, чем, например, С.
Если для вас программа это огромное число чихов, которые никак не соотносятся друг с другом - тогда да, ещё то verbosity.
В остальных случаях это компактное изложение мыслей программиста.

---

В этой связи хочется вспомнить "Преступление и наказание".
Есть системные программисты и есть прикладные программисты.
А есть системные программисты, которые думают, что они прикладные и прикладыне программисты, которые думают, что они системные...

Там где ООП не эффективно - оно не нужно, там где оно эффективно, теплейты его не заменят.

з.ы. флуд, флуд, флуд... ! :)
...
Рейтинг: 0 / 0
C++ & Java
    #32857987
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dwl NotGonnaGetUsРазница меджду чем и чем?

Не хватает только пунктиков:
- не нужно пересобирать классы.
- "нельзя" превращются в "можно", если при инициализации класса передавать ему Class класса, которым он инициируется и совмещать технику генерик с интерфейсами :)

По поводу чистого генерика - согласен со всеми пунктами нельзя :)
...
Рейтинг: 0 / 0
C++ & Java
    #32858075
awson
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
NotGonnaGetUs
Алгоритм нельзя отвинтить от данных, хотя бы потому, что он с этими данными работает.
Похоже революция для С-комунити была в том, что привязка к классу заменилась привязкой к сигнатуре метод(а/ов) которые в этом классе реализованны.
Мощно!
И cмешнo, если смотреть на это со стороны java, где существует такое понятие как интерфейсы.


Если я не путаю, интерфейсы в java == pure virtual функциям в С++. В С++ это было со времен, когда Гослинг под стол пешком ходил. Ну и что? Раз они объявлены в классе и, в конечном итоге, ссылаются на экземпляр класса, то что это вообще меняет?

В STL к классам, представляющим данные, может ВООБЩЕ НЕ ПРЕДЪЯВЛЯТЬСЯ НИКАКИХ требований и не требоваться наличия никаких специфических методов. Если нужных вам "интерфейсов" нет, вы пишете функтор и скармливаете алгоритму. Вуаля.
...
Рейтинг: 0 / 0
C++ & Java
    #32858207
с127
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
2 NotGonnaGetUs

> А это и не должно ничего доказывать.

В таком случае незачем было вспоминать это свойство, раз оно все равно ничего не доказывает.

>У вас не бывает. А у нас бывает :)

У вас много чего бывает, только все без толку.
...
Рейтинг: 0 / 0
C++ & Java
    #32858971
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
с1272 NotGonnaGetUs

> А это и не должно ничего доказывать.

В таком случае незачем было вспоминать это свойство, раз оно все равно ничего не доказывает.

Не стал лениться, нашёл откуда вытащена фраза.
NotGonnaGetUs
c127
В С++ и других языках такое тоже можно сделать, в каких-то IDE наверняка сделано, только ИМХО это бесполезное свойство. Как я уже говорил, в Паскале в этом смысле можно наворотить гораздо больше чем в джаве, потому что паскаль проще и строже, но это ничего не доказывает.

А это и не должно ничего доказывать.
Если что-то можно сделать, но этого не сделали - значит этого ещё нет.
Тем не мнее, очень рад за паскаль, только никак не могу понять причём он тут.
Но если вам интересно поговорить, то пожалйста. Можно завести отдельный топик на эту тему.


Я всего-навсего растолковал вам смысл фразы "на стадии написания",
ничего при этом не доказывая :)
Что-то доказывать стали вы, вспомнив о паскале.

А что до полезности тех или иных свойств хорошей IDE - в отдельный топик :)


>У вас не бывает. А у нас бывает :)

У вас много чего бывает, только все без толку.
[/quot]
Чувствуется глубокая аргументация. Respect.
...
Рейтинг: 0 / 0
C++ & Java
    #32859231
NotGonnaGetUs
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
awsonЕсли я не путаю, интерфейсы в java == pure virtual функциям в С++. В С++ это было со времен, когда Гослинг под стол пешком ходил. Ну и что? Раз они объявлены в классе и, в конечном итоге, ссылаются на экземпляр класса, то что это вообще меняет?

В STL к классам, представляющим данные, может ВООБЩЕ НЕ ПРЕДЪЯВЛЯТЬСЯ НИКАКИХ требований и не требоваться наличия никаких специфических методов. Если нужных вам "интерфейсов" нет, вы пишете функтор и скармливаете алгоритму. Вуаля.

Наверное путаете.
Interface отвязан от какого-либо класса. Но классы реализовывают интерфейсы.
Если с равнивать с С++, то интерфейс - это набор связанных функций.

"может ВООБЩЕ НЕ ПРЕДЪЯВЛЯТЬСЯ" это значит, что их предъявит не известно кто и не известно в каком месте.

Любой класс реализующий те или иные действия над реализациями интерфейсов - ни что иное как ваш "алгоритм отвязанный от данных", но лишённый проблем возникающих из-за прямого вытаскивания методов классов в виде самостоятельных сущностей.
- не наружаются принципы ООП.
- проблемы связанные с тем, что одинаковые функторы для разных данных выполняют разные действия и хотя "алгоритм" применяется результат его не предсказуем.
- если данные не реализуют метод с нужной сигнатурой, но "алгоритм" нужно применить к ним алгоритм, придётся писать "каст" к нужной сигнатуре. Смысл этого "каста" потенциальная "смысловая дыра" в коде, посколько не понятно какому алгоритму может скармливаться это чудо, а если "каст" происходит "далеко" от данных - то это ещё и повод к дублированию кода.

Тут можно возразить: мы крутаны, мы не делаем ошибок, мы коментируем все неясные места в коде, мы супер-супер-супер и в машинных кодах писали бы так же хорошо, поскольку мы супер.
Против этого мне сказать будет нечего :)
Знаю только, что изучать полотна закорючек с не тривиальным поведением, на порядок сложнее, чем пробежаться глазами по коду, который сам говорит, что делает и требует минимум комменатриев.
...
Рейтинг: 0 / 0
C++ & Java
    #32859340
Фотография www.fun4me.narod.ru
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>> Interface отвязан от какого-либо класса. Но классы реализовывают >> интерфейсы.
>> Если с равнивать с С++, то интерфейс - это набор связанных функций.

Нет. Если сравнивать с С++, то интерфейс - это разновидность абстрактного класса. Не забывайте, что интерфейсы в Java есть только потому, что в Java нет множественного неследования.
...
Рейтинг: 0 / 0
C++ & Java
    #32859351
Фотография www.fun4me.narod.ru
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
неследования == наследования.
...
Рейтинг: 0 / 0
C++ & Java
    #32859870
Фотография Lelikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Полагаю, что и на SQL.RU стоит создать раздел "Религиозные войны"
________________________________________________________
Глюк - это высокоорганизованная система не поддающихся определению частиц
...
Рейтинг: 0 / 0
C++ & Java
    #32859894
alex_k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и банить всех кто туда напишет :-)
...
Рейтинг: 0 / 0
C++ & Java
    #32860168
c127
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
2 NotGonnaGetUs

>Не стал лениться, нашёл откуда вытащена фраза.

Плохо искали. Начало спора было таким:
NotGonnaGetUs> А начиная с java1.5.
Можно писать
...
Т.е. нет никаких проблем с помещение однотипных объектов в коллекции. Проверка типов гарантируется на этапе написания кода.


Именно этот аргумент и есть бесполезным, а если подходить более аккуратно, то фраза оказывается вообще бессмыселнна.

>Чувствуется глубокая аргументация. Respect.

Правильно, а вот настоящие аргУменты:
NotGonnaGetUs> 99.99% программистов пишут код не на бумаге, а в IDE. Возможно отдельные оригиналы набирают мегабайты кода в ноутпаде. Вероятно вы решили, что являетесь оплотом этой могучей кучки... Всё проще! :)
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
C++ & Java
    #34250265
Smak_86
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IHMO две крайности это машинный код и Java, а С++ (конечно много в нем хорошего) не для меня, это ,по-мойму, не язык а смемесь из нескольких; каждый из которых обладает своими плюсами и минусами а С++ всеми их минусами

ненравяться шаблоны? нужна высокая скорость выполнения программ? пишите для конкретной машины? пишите на ассемблере(а лучше машинными кодами)
...
Рейтинг: 0 / 0
C++ & Java
    #34250307
Фотография Ruslan.Isbarov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex_kи банить всех кто туда напишет :-)
Да ну :)... На многих форумах для этого создается специальный раздел, с сопутствующим названием типа "Сортир", "Мусорная Яма" и т.п. где разрешается все. В этих разделах не банят.
...
Рейтинг: 0 / 0
C++ & Java
    #34250314
Фотография Ruslan.Isbarov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я считаю что религиозные войны развязывают в первую очередь те, кому делать нечего. Один фиг, все при своих мнениях останутся и мир от этого не перевернется.
Вообще, лично мне нравится и C/C++ и Java. Знаю оба языка, увы, на работе в основном приходится иметь дело с Java.

Кто то выше говорил, что Java помесь всякой всячины? Предлагаю, например, взглянуть на недавно зарелизенный язык D.

Собственно, описание языка

Сравнение с C, C++, Java и C#

Кто знает, может когда нибудь придется на этом программить ;) ...
...
Рейтинг: 0 / 0
C++ & Java
    #34250682
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ruslan.IsbarovЯ считаю что религиозные войны развязывают в первую очередь те, кому делать нечего.

Скорее все-таки цели приследуют. Выбрать язык в который хочет углубиться, ... .

Ruslan.IsbarovОдин фиг, все при своих мнениях останутся и мир от этого не перевернется.
Вообще, лично мне нравится и C/C++ и Java. Знаю оба языка, увы, на работе в основном приходится иметь дело с Java.

Кто то выше говорил, что Java помесь всякой всячины? Предлагаю, например, взглянуть на недавно зарелизенный язык D.

Собственно, описание языка

Сравнение с C, C++, Java и C#

Кто знает, может когда нибудь придется на этом программить ;) ...

Посмотрел сравнение. Взял первый же пункт "Function delegates". Описание такое, что и в С++ оно есть, хотя в таблице стоит No. Окинув таблицу кажется что D просто мощнейшее стредство, а разбираясь окажется, что есть куча вопросов.
...
Рейтинг: 0 / 0
C++ & Java
    #34251031
maXmo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
просто в D много всего напихано, вот они и сравнивают, чего они напихали в D и чего не было напихано в другие языки.
...
Рейтинг: 0 / 0
C++ & Java
    #34251037
maXmo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
имхо, у D есть весьма занятные фичи.
...
Рейтинг: 0 / 0
160 сообщений из 160, показаны все 7 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / C++ & Java
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]