• Разобраться со слабыми сторонами C++?

    @Mercury13
    Программист на «си с крестами» и не только
    Что я могу сказать про проблемы C++?
    1. Слишком слабая типизация. Например, int x = 0.0;
    2. Система хедерных файлов крайне медленна, «предкомпилированные хедеры» и extern template — полумеры.
    3. Запутано подключение чужого откомпилированного кода (DLL, к примеру). Мало написать хедер, надо ещё откомпилировать lib — в общем, интересного мало.
    4. Библиотека STL крайне жирна. Хотя и libc тоже «хороша» — минимальная программа на Паскале занимала несколько килобайт, в зависимости от компилятора, на Си — приближается к сотне килобайт. Я не говорю про Linux/MSVC, где libc динамически подключаемая.
    5. Строковый литерал на C++ — это та же нуль-терминированная строка. Когда эту строку приходится оборачивать в какой-нибудь std::string, уже при выполнении вычисляется её длина. Зачем? Почему бы не вкомпилировать её в exe'шник?
    6. Нет ключевых слов override/reintroduce. При изменении сигнатуры виртуального метода приходится вспоминать, где он переопределялся.
    7. Нет виртуальных конструкторов. «Фабрика» — полумера.
    8. Коряво реализовано право доступа «читай кто угодно, пишу только я».
    9. Явное определение методов как inline или не-inline в сочетании с шаблонами приводит к странным эффектам. Когда расшаблонивание приводит к сложному коду, inline вреден (сжирает кэш процессора), когда к простенькой операции с указателем — наоборот, нужен. В общем, это давно уже должно стать парафией оптимизатора.
    10. В разного рода callback'ах замыкание приходится реализовывать собственными силами. Что-то типа: typedef void (*ProcDoSomething)(int aParam, void* aClosure). То же самое в Delphi: type ProcDoSomething = procedure(int aParam) of object;
    11. Если вдруг случайно два разных модуля реализуют одно и то же, но один препроцессором, а второй — синтаксисом C++, будет ОЧЕНЬ много геморроя с поиском ошибки.
    12. В обычном цикле for счётчик упоминается трижды. В общем, место очень ошибкоопасное. Для самых простых циклов у меня вообще есть макрос FOR_S (i, 0, n); суффикс S означает size_t.
    13. Когда из-за рефакторинга «внутренней кухни» объекта меняется способ хранения ссылки, меняется и код, который этой ссылкой пользуется. Например: object.buddy.field, object->buddy.field, object.buddy().field — в зависимости от того, buddy реализовано как Buddy& buddy, Buddy* buddy или Buddy buddy().

    Пока, засиделся. Мне бежать.
    Ответ написан
    4 комментария
  • Разобраться со слабыми сторонами C++?

    wholeman
    @wholeman
    > множественное наследование сложно использовать
    Простой пhимер: А имеет два подкласса: B и C, от них происходит D.
    Если родительские классы имеют общего предка (A), то в потомке (D) будет несколько экземпляров этого предка. С каким будут работать унаследованные методы в общем случае неизвестно. При приведении указателя D* к A* также непонятно, на что он будет указывать.
    Это можно исправить, объявив наследование от A, как virtual в B и C, но работать это будет значительно медленнее и инициализацию такого предка придётся делать в каждом потомке (B, C, D и далее по иерархии), а не только в непосредственных B и C. Это не только неудобно, но и не вписывается в ООП. Кроме того, если A,B и C объявлены в сторонней библиотеке, такая операция вообще невозможна.
    > перегрузка через virtual неудобна
    Не могу обосновать. Я не считаю её неудобной. Мне всегда нравилось.
    > исключения трудно реализовать в компиляторе, поэтому если и речь идет о многоплатформенности, то лучше о них забыть
    Забыть о них не получится, т.к. они используются в языке (оператор new, например, их использует). Другое дело, что мне, например, они неудобны, но я вообще склонен избегать выходов управления и середины функции, как, извините за грубость, оператора goto. В ряде случаев, впрочем, использую.
    > шаблоны — не самый простой способ генеративного программирования
    По моему, он достаточно прост. Может быть, даже слишком: с помощью шаблонов очень легко раздуть программу массой однотипного кода.
    Ответ написан
    1 комментарий
  • Разобраться со слабыми сторонами C++?

    Gorthauer87
    @Gorthauer87
    Программист
    >Со временем стало ясно, что это не лучшее сочетание: небезопасная арифметика указателей и макросы хорошо подходили для низкоуровневого программирования, но на высоком уровне легко приводили к ошибкам.

    Кто вас просит ими пользоваться? Я вот не пользуюсь (точнее оно нужно в 1% случаев).

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

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

    И на чем вы изволите писать большие проги, типа MSOffice? Он между прочим на плюсах полностью написан и поэтому работает очень быстро. На чем писать софт для мобилок, где проблемы с ресурсами стоят остро?
    А многие проблемы с плюсами не столь серьезны, как любят многие говорить, а еще больше проблем возникает из за кривого проектирования фреймворков для плюсов. За примером ходить не надо — MFC, который и С++ фреймворком рука не поднимается назвать.
    Ответ написан
    5 комментариев
  • Разобраться со слабыми сторонами C++?

    tzlom
    @tzlom
    Слабая сторона С++ — ООП, потому что его нет
    всё остальное это множество граблей для людей не понимающих как работает компьютер и/или С++, я сомневаюсь что это действительно проблемы языка
    Ответ написан
    3 комментария