Форум: "Прочее";
Текущий архив: 2008.10.26;
Скачать: [xml.tar.bz2];
ВнизЧем вам лично не нравится CPP? Найти похожие ветки
← →
GrayFace © (2008-08-28 23:39) [40]Обилием костылей, отсутствием базового класса, разношерстными строками, хидерами.
(а Дельфийский принцып объявления объектов в interface и initialization даже удобнее, чем объявление не отходя от кассы типа C#, т.к. все автоматизировано горячими клавишами)
Asteroid © (28.08.08 20:54) [31]
Отсутствием аналога "function of object",
В Managed c++, вроде, есть такое.
← →
oxffff © (2008-08-29 00:19) [41]
> GrayFace © (28.08.08 23:39) [40]
см. СBuilder.
← →
Германн © (2008-08-29 01:26) [42]
> Чем вам лично не нравится CPP?
> XentaAbsenta © (28.08.08 17:55) [4]
>
> тьфу блин... я рассчитывал увидеть конкретные вещи, а не
> начинать новую священную войну.
>
Вот это твоя главная ошибка. Такая формулировка сабжа подразумевает именно холивар.
Нравится/не нравится может какое-либо произведение. То бишь конечный продукт. А для инструмента создающего продукты есть только понятия умеешь/не умеешь пользоваться. Ну и если инструмент явно сделан "на коленке", то есть понятие "кривой". Но уж С++ сделан точно не на коленке.
← →
Anatoly Podgoretsky © (2008-08-29 08:42) [43]> Германн (29.08.2008 1:26:42) [42]
> есть понятие "кривой". Но уж С++ сделан точно не на коленке.
Но кривой.
← →
Alkid (2008-08-29 10:18) [44]
> oxffff © (28.08.08 23:32) [39]
:)
Фишка вот в чём - я, собственно, С++ программист. С++ сейчас - этой мой основной инструмент (в загашнике у меня ещё есть Дельфя и Шарп). Так что я могу долго распространяться о свойстах этого языка, его недостатках и достоинствах. Мастер должен знать свой инструмент :)
← →
Simpson © (2008-08-29 10:22) [45]XentaAbsenta © (28.08.08 18:43) [14]
#define abstract
#define TVariant
Так можно весь VCL переписать ))
subj
Непривычность, а так язык как язык.
← →
Игорь Шевченко © (2008-08-29 10:29) [46]Чем вам не нравится delphi ?
← →
Anatoly Podgoretsky © (2008-08-29 10:30) [47]Букв в название мало.
← →
han_malign © (2008-08-29 10:39) [48]
> Зависит от порядка вычисления выражений (аргументов при
> вызове функции), а он стандартом языка не регламентирован.
>
- это как это? Во первых соглашение о вызовах указывается в опциях командной строке(настройках проектах) - которые являются неотделимой частью проекта, во вторых явный квалификатор (Ms - __declspec())...
> 1. Вычисляется значение ВТОРОГО аргумента. Оно будет равно 1.
> 2. Переменная i УЖЕ использована (для вычисления значения второго аргумента) и поэтому будет инкрементирована СРАЗУ после вычисления выражения.
> 3. Первый аргумент получится равным 2.
> 4. Результат будет равен 1.
>
- а вот тут начинается бардак, потому как в Ms VC(как минимум с VC6) все пост..кременты - выносятся за выражение наглухо...j = (i++) + (i++);
- выродится вj = i+i; i+= 2;
долго я глюк ловил с подобной конструкцией:if((*str++=="a") && (*str++== "b"))
switch(*str){...}
только что проверил(MsVC 2008 Express):int f = func(i, i++);
c оптимизацией, вырождается вf = 0; i++;
← →
Alkid (2008-08-29 10:40) [49]
> Чем вам не нравится delphi ?
Говорю про семёрку, ибо более поздние не щупал:
1. Нет множественного наследования и шаблонов.
2. Нет статических и автоматических объектов. Идиома RAII не применима.
(Тончее применима, но через извраты с интервейсами).
3. Нет reflection.
4. Нет лямбд.
5. Нет метапрограммирования.
Синтаксис и прочее - фигня, дело привычки.
← →
Alkid © (2008-08-29 10:55) [50]
> han_malign © (29.08.08 10:39) [48]
Приводимые тобой выражения не корректны с точки зрения стандарта С++.
Легально только ОДНО изменение состояния объекта между двумя точками следования. А в простом выражении таких точки две - до и после.
Если же ты нарушаешь это правило, то можешь ловить UB и ругать злые компиляторы. Стандарт надо знать :)
← →
Игорь Шевченко © (2008-08-29 11:19) [51]
> 1. Нет множественного наследования и шаблонов.
> 2. Нет статических и автоматических объектов. Идиома RAII
> не применима.
> (Тончее применима, но через извраты с интервейсами).
> 3. Нет reflection.
> 4. Нет лямбд.
> 5. Нет метапрограммирования.
И нахрен это все простому народу надо ?
Желательно с показательным примером, чтобы те, у кого в их используемом языке нету лямбд и идиом RAII сразу могли посыпать голову пеплом и сожалеть о том, что всю жизнь жили напрасно.
Я серьезно - пример желателен из реальной жизни, с постановкой задачи и реализацией ее с помощью метапрограммирования, шаблонов, reflection всяких и т.п., причем, желательно, чтобы вся эта хрень использовалась так, чтобы было ясно, что без нее решение получается кривым и уродливым, а вот с ней - ну все кульно и рульно.
А то развели creeping featurism и пальцы гнут, панимаешь
← →
han_malign © (2008-08-29 11:44) [52]
> Приводимые тобой выражения не корректны с точки зрения стандарта С++.
> ... и ругать злые компиляторы.
- не корректные выражения должно быть зло обруганы злыми компиляторами... А если не обруганы - значит компиляторы не только злые, но и пакостно-коварные...
По начальному сабжу - до сих пор не могу понять какого хрена приоритет побитовых операции ниже логических - оно ж в таком порядке никуда, никак и никаким боком...
классика - (2 & dw == 2)
- хорошо хоть ругается...
← →
Mystic © (2008-08-29 11:55) [53]А вообще по поводу языков я склонен к той банальной мысли, что универсальных языков не только нет, но и быть не может.
Если на кону стоит производительность, то я предпочту либо delphi с inline-ами, либо чистый C, (точнее ограниченное подмножество, которое я называю C++ с классами). Тут сказывается тот факт, что C++ является наследником C. Почему я не использую высокоуровневые средства вроде перегрузки операций? Потому что потом приходится все равно выполнять работу компилятора и смотреть, а в состоянии ли компилятор раскрутить это выражение так, как я хочу. Получается что писать меньше, но проще написать лишние пару строчек чтобы ясно выразить свои намерения.
Если на кону стоит ООП архитектура, я выберу какой-нить скриптовый язык вроде Python. При этом если надо будет добавить новый атрибут, я не буду ломать себе голову над тем, в какое место в иерархии его надо воткнуть. Ну и вообще утиный полиморфизм гибче. Получение метаинформации про тип проще.
Если у меня будут математические вычисления, я возьму MATLAB. Никакая перегрузка операторов C++ не обеспечит мне настолько удобный синтаксис для операций с матрицами.
В случае, когда выполнить, проверить и протестировать большую части кода проблематично, я выберу что-нить вроде Delphi или Ada.
В случае особо специфичной предметной области возможно я предпочту разработать собственный язык, который бы наиболее удобным образом представлял базовые операции этого языка.
Вот, например, XML. Универсальное средство представления. Но текстовый DFM выглядит намного читабельнее. А если представить, как в XML будет представлена математическая формула, то волосы встают дыбом: TeX (LaTeX) намного приятнее в этом плане.
← →
Alkid (2008-08-29 11:56) [54]
> han_malign © (29.08.08 11:44) [52]
Спорить не буду. Чем больше компилятор выдаёт варнингов - тем лучше.
← →
Mystic © (2008-08-29 12:03) [55]> Чем больше компилятор выдаёт варнингов - тем лучше.
О! Тогда параноидальный режим выдачи предупреждений в gcc для тебя :)
← →
Alkid © (2008-08-29 12:14) [56]
> Игорь Шевченко © (29.08.08 11:19) [51]
> И нахрен это все простому народу надо ?
Простому народу это нужно.
Особенно учитывая, что я не занимаюсь чистым ООП, а больше склоняюсь к функциональному стилю с элементами ООП (или ООП с большой долей ФП).
> > 1. Нет множественного наследования и шаблонов.
Множественное наследование и шаблоны позволяют делать очень красивые с лаконичные решения.
Пример: недавно рефакторил большую бибилотеку в которой было дохрена функций вида "ConvertXIdToYId". Например, строковый идентификатор файловой системы в численный, да ещё в численный по двум разным системам идентификации. Плюс к этому ещё "GetReadableNameFor", а потом "GetMaxLabelLengthFor" и т.п.
Родилась идея - организовать справочные таблицы по этим данным. Таблицы на основе статических массивов. Фукнция выборки - 8 строк шаблонного кода.
Без шаблонов пришлось бы на КАЖДУЮ таблицу писать свои функции и смысла не было бы. А так - сократил код почти в 3 раза, да ещё убрал кучу несоответсвий между разнонаправленными функциями конверсии.
Это за шаблоны.
Потом навернул шаблонный класс-функтор, который умел бы трансформировать значения в контейнерах. В классе были предусмотрены trait`ы - это тебе множественное наследование. Пример из реального проекта.
> > 2. Нет статических и автоматических объектов. Идиома RAII
> > не применима.
В языках без GC подобная идиома РЕЗКО сокращает количество утечек памяти.
Очень удобно для управления примитивами синхронизации. Настолько распространено в реальной жизни, что конкретные примеры приводить не буду.
В C#, языке с GC, кстати, идиома RAII тоже никуда не делась, только она там реализуется через специальную конструкцию языка. Использование внешних ресурсов, которые требуют явного закрытия, не может быть привязано к времени жизни объектов, ибо сборщик мусора ничего не гарантирует. Для таких объектов ввели спец. интерфейс IDisposable с методом Dispose. Т.е. сборщик мусора - это хорошо, но ЭТОТ мусор уберите за собой сами. Уборка "самим" показалась неудобной и ввели конструкцию using() {} - частный случай RAII.
> > (Тончее применима, но через извраты с интервейсами).
> > 3. Нет reflection.
> > 5. Нет метапрограммирования.
Пример из реального проекта - пишут наши хлопцы сериализатор. Что бы данные между процессами кидать. А как сериализовать структуру, если нет доступа к её метаинформации? Ответ - писать код сериализации/десериализации ручками. Муторно, громоздко, подвержено ошибкам. Наши пошли по другому пути - забабахали свой вариант IDL с кодогенератором. Т.е. реализовали свой вариант метаданных и метапрограммирования. Тока вариант не очень хороший и завязанный на использование в сборке нестандартных тулзов. А это минус. И мучаемся мы сейчас с их решениями, поскольку вынуждены сами синхронизировать описания в IDL и объявления в заголовках. Было бы реализовано в самом языке - было бы гораздо лучше.
> > 4. Нет лямбд.
Лямбы + замыкания в С++ были бы ОЧЕНЬ ХОРОШИМ синтаксическим сахаром для написания классов-функторов, которые уже используются очень широко. Собственно, начиная с STL. Т.е. лямбы по сути уже используются, но как смоделированное программистом свойство, а не поддерживаемое языком напрямую.
Вот примеры из реальной жизни.
← →
Alkid © (2008-08-29 12:16) [57]
> О! Тогда параноидальный режим выдачи предупреждений в gcc
> для тебя :)
Типа того :)
← →
Игорь Шевченко © (2008-08-29 12:31) [58]Alkid © (29.08.08 12:14) [56]
Как я пишу на Delphi без всех этих синтаксических сахаров - ума не приложу. И вроде оно без ошибок получается.
← →
Mystic © (2008-08-29 12:35) [59]
> > > (Тончее применима, но через извраты с интервейсами).
>
> > > 3. Нет reflection.
> > > 5. Нет метапрограммирования.
> Пример из реального проекта - пишут наши хлопцы сериализатор.
> Что бы данные между процессами кидать. А как сериализовать
> структуру, если нет доступа к её метаинформации? ...
А зачем структуру? Наследуем класс от TPersistent и сериализуем. Есть RTTI. Сериализация уже есть в VCL.
← →
Alkid © (2008-08-29 13:01) [60]
> Mystic © (29.08.08 12:35) [59]
Я туту немного смешал рассуждения по С++ и Дельфи :)
Прошу прощения.
> Игорь Шевченко © (29.08.08 12:31) [58]
> Как я пишу на Delphi без всех этих синтаксических сахаров
> - ума не приложу. И вроде оно без ошибок получается.
Да кто же спорит :)
Я не утверждал, что без этих свойств язык обязательно превратится в непользуемое убожище. Я и сам на дельфи программировал без этих "излишеств". Я тут лишь излагаю свои взгляды на то, каким должен быть тот или иной язык, что бы я смог на нём работать более продуктивно.
А вообще прекрасная иллюстрация к этой дискуссии - парадокс Блаба.
← →
Mystic © (2008-08-29 13:12) [61]> Alkid © (29.08.08 13:01) [60]
Все ходы записаны:
> Alkid (29.08.08 10:40) [49]
> 1. Нет множественного наследования и шаблонов.
> 2. Нет статических и автоматических объектов. Идиома RAII
> не применима.
> (Тончее применима, но через извраты с интервейсами).
> 3. Нет reflection.
> 4. Нет лямбд.
> 5. Нет метапрограммирования.
Пункт 3 тогда можно вычеркнуть?
← →
Alkid © (2008-08-29 13:16) [62]
> Пункт 3 тогда можно вычеркнуть?
Да.
← →
palva © (2008-08-29 13:19) [63]
> Чем вам не нравится delphi ?
Плюсов нет.
← →
XentaAbsenta © (2008-08-29 13:20) [64]
> Alkid © (29.08.08 12:14) [56]
> Mystic © (29.08.08 12:35) [59]
Да, RTTI в CPP слабенький, весьма, могли бы и расширить. Но меня более всего бесит синтаксис.
Asteroid © (28.08.08 20:54) [31]
Asteroid © (28.08.08 20:54) [31]
> Отсутствием аналога "function of object"
согласен на все сто
Asteroid © (28.08.08 20:54) [31]
> , замороченностью с header-ами, отсутствием дельфийски-удобного
> редактора кода =)
>
хз..., а насчёт редактора кода - посмотри на VCPP + VisualAssist
------------------------------
я уже год не притрагивался ни к Delphi ни к CPP (до этого 6 лет с D. и 1.5 года с C++), пишу на C# (2.0). Меня не покидает мысль о другом языке, я его за пивом как-то даже начал проектировать :) даже "Hello world" написал
← →
Deep (2008-08-29 13:32) [65]мне не нравится двумя вещами
1)более сложный в изучении, много разных заморочек -- которые потом очень мало используются (например, многим можно счастливо жить без перегрузки операторов и т.п.), изучить язык по коду зная например только делфи -- довольно проблематично.
2)слишком много граблей, на которые может наступить начинающий программист (например, не зная о перегруженных операторах для разных типов). Паскаль в этом плане на порядок приятнее.
Странное дело, но например PHP (созданный по оброазу и подобию) мне нравится, а вот сам C++ как то не очень....
Для того, чтоб язык нравился -- он должен быть простым в изучении и использовании. Мне кажется С++ ни там, ни там не блещет.
← →
Mystic © (2008-08-29 13:40) [66]> Мне кажется С++ ни там, ни там не блещет.
Программировать на C++ не прочитав предварительно Страуструпа или что-нить такое нельзя. А паскаль и PHP легко изучаются на ходу по мере необходимости.
← →
clickmaker © (2008-08-29 13:41) [67]а мне нравится
← →
Игорь Шевченко © (2008-08-29 13:47) [68]
> Программировать на C++ не прочитав предварительно Страуструпа
> или что-нить такое нельзя
ох уж эти сказки...ох уж эти сказоцники...
← →
Palladin © (2008-08-29 14:09) [69]а что вернет функция new при создании объекта "пустого" класса? то есть, класса без аттрибутов :)
← →
Alkid © (2008-08-29 14:19) [70]
> а что вернет функция new при создании объекта "пустого"
> класса? то есть, класса без аттрибутов :)
Указатель на новый объект этого пустого класса. :)
← →
Palladin © (2008-08-29 14:27) [71]ну вроде бы как инстанцируемый размер - ноль. и по идее в результате Nil. или я ошибаюсь? мне просто интересно...
← →
PPC (2008-08-29 14:39) [72]В такие объекты автоматом включается фиктивная переменная, поэтому размер не нуль.
← →
Alkid © (2008-08-29 14:41) [73]
> ну вроде бы как инстанцируемый размер - ноль. и по идее
> в результате Nil. или я ошибаюсь? мне просто интересно..
По стандарту sizeof пустой структуры/класса == 1.
← →
@!!ex © (2008-08-29 14:52) [74]> 1)более сложный в изучении, много разных заморочек -- которые
> потом очень мало используются (например, многим можно счастливо
> жить без перегрузки операторов и т.п.), изучить язык по
> коду зная например только делфи -- довольно проблематично.
>
> 2)слишком много граблей, на которые может наступить начинающий
> программист (например, не зная о перегруженных операторах
> для разных типов). Паскаль в этом плане на порядок приятнее.
Не знаю как вы... А в моих работах последних двух лет нет ни одного проекта, где использование перегруженных операторов не давало бы ощутимых примуществ. Как я уже здесь говорил, шаблоны+перегрузка операторов позволяет сделать потоко независимые переменные.
Вот как вы без перегрузки будете организовывать работу с безопасными переменными?var
i_criticalSection:TCriticalSection;
i:integer;
begin
i_criticalSection.Enter();
i:=1;
i_criticalSection.Leave();
end;
begin
i_criticalSection.Enter();
Result:=i;
i_criticalSection.Leave();
end;
и т.д. каждое обращение к i - городои огород. Либо делаем класс, для каждого типа отдельный... Тоже проблему не решает...
На С++, с помощью шаблонов все сводится вот к такому виду:syncproperty<int> i;
{
i = 1;
}
{
return i;
}
Никаких огородов из критических секций. Никакий классов с функциями SetValue() GetValue().
Все чисто и красиво.
← →
Mystic © (2008-08-29 14:58) [75]> На С++, с помощью шаблонов все сводится вот к такому виду:
Правильно, а потом
1) Количество таких переменных плодится и размножается, в результате вся выгода от многопоточности теряется: потоки последовательно ждут когда прочитается эта переменная.
2) Затруднен доступ к interlocked операциям.
3) Кроме того, код
i = i + 1;
не является потокобезопасным, как хотелось бы и интуитивно чувствуется. Что приводит к багам.
← →
@!!ex © (2008-08-29 15:04) [76]> 1) Количество таких переменных плодится и размножается,
> в результате вся выгода от многопоточности теряется: потоки
> последовательно ждут когда прочитается эта переменная.
А как это связано с реализацией?
Типа: "Давайте сделаем через жопу, тогда прогер будет избегать использования"?
> 2) Затруднен доступ к interlocked операциям.
В чем затруднение?
> 3) Кроме того, код
> i = i + 1;
> не является потокобезопасным, как хотелось бы и интуитивно
> чувствуется. Что приводит к багам.
Ну это уж звиняйте. Для этого ++ есть.
← →
Tricky (2008-08-29 15:18) [77]СPP люблю, наверное т.к. больше всего с ним работал и работаю на данные момент.
Меня очень напрягает CaseSensetive (ну не по человечески это, - по машинному) и знаки { и } вместо begin . Каждый раз приходится напрягать зрение, и искать их. Система инклудов в минусе.
По сравнению с Delphi - сильно проигрывает в синтаксисе, если Delphi читаешь без напряга - как текст, то здесь иногда приходится приостанавливаться и делать микро паузы (сам синтаксис не логика работы).
← →
Mystic © (2008-08-29 15:20) [78]> Ну это уж звиняйте. Для этого ++ есть.
Ты не чувствуешь проблему? Поставь замени +1 на +2 :)
Дело в том, что очень часто потокобезопасные переменные меняют свое значение на основании старого значения. Т. е. мы получаем код вроде
static syncproperty<int> i;
i = some_func(i);
или рассмотрим такой:
static syncproperty<class_xxx> i;
temp.do_something();
И что мы получим? temp вернет ссылку на наш класс/структуру. В другом потоке произойдет аналогичная ситуация. И после этого оба класса вызовут функцию do_something. Но имеено сам этот вызов (а не обращение к переменной temp) и хочется сделать потокобезопасным.
Если пользоваться только ++ и --, то вообще непонятно, зачем нужна ненужная критическая секция при чтении. Использовать interlocked операции и делу с концом.
Видишь, чуть более сложный вариант, и эта абстракция сбоит. По крайней мере для меня, эта ситуация типична : да, код работает классно. Задумка прекрасная. Но... она не работает. Или работает, но с исключениями. И чтобы поймать эти исключения, надо после того, как код написан посмотреть и подумать: а во что компилятор его переведет? Все ли будет так, как я задумал? Нет ли где граблей? Возможно у меня недостаточно опыта в C++. Возможно я пролой проектировщик на C++.
В данном случае мне проще вручную вызывать Lock и Unkock (кстати, Unlock обычно идет в секции finally), чем пользоваться такой реализацией и постоянно вспоминать: ага, будет ли в этом конкретном случае это работать?
И в данном случае можно добавить метод modify, передавать туда модифицирующий функтор, тут бы пригодились lambda... И т. д. и т. п. Но это уже другие языки :)
← →
Mystic © (2008-08-29 15:22) [79]
static syncproperty<class_xxx> gopa;
gopa.do_something();
← →
Alkid © (2008-08-29 15:22) [80]
> Mystic © (29.08.08 14:58) [75]
> 1) Количество таких переменных плодится и размножается,
> в результате вся выгода от многопоточности теряется: потоки
> последовательно ждут когда прочитается эта переменная.
Дык. Проще исправить один шаблонный класс и внедрить в него более умную систему синхронизации, чем во всех пропертях потом код переписывать.
Страницы: 1 2 3 4 вся ветка
Форум: "Прочее";
Текущий архив: 2008.10.26;
Скачать: [xml.tar.bz2];
Память: 0.65 MB
Время: 0.008 c