Каковы вредные привычки программистов на С, начинающих писать на С ++? [закрыто]

34
задан 4 revs, 3 users 64% 23 May 2017 в 12:07
поделиться

23 ответа

Недостаточно хорошо оставить в покое, а вместо этого использовать C.

0
ответ дан 27 November 2019 в 15:49
поделиться

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

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

Придерживаемся фрагмента кода из C, не думая, есть ли у C ++ лучший способ. (Есть причина, по которой у вас теперь есть class, private, public, const (расширенный за пределы C89), функции статического класса, ссылки.

Незнание библиотеки ввода-вывода C ++ (ее БОЛЬШАЯ, и вам нужно знать это ) и смешивание ввода-вывода C ++ и ввода-вывода C.

2
ответ дан 27 November 2019 в 15:49
поделиться

Он думает, что C ++ - это просто немного другой язык, отличный от C. Он продолжит программировать C, замаскированный C ++. Никакого расширенного использования классов, структуры считаются менее мощными, чем классы, пространство имен, новые заголовки, шаблоны, ничего из этих новых элементов не используется. Он продолжит объявлять целочисленные вары без int, не будет предоставлять прототипы функций. Он будет использовать malloc и бесплатные небезопасные указатели и препроцессор для определения встроенных функций. Это лишь небольшой список;)

2
ответ дан 27 November 2019 в 15:49
поделиться

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

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

4
ответ дан 27 November 2019 в 15:49
поделиться

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

7
ответ дан 27 November 2019 в 15:49
поделиться

Запись с использованием пространства имен std , потому что все это делают, а затем никогда не отражают по его значению. Или зная, что это значит, но фраза « std :: cout <<" Hello World "<< std :: endl; выглядит некрасиво».

8
ответ дан 27 November 2019 в 15:49
поделиться

Использование приведений в стиле C.

C ++ позволяет независимо выбирать, разрешать ли приведение типов между несвязанными типами и разрешать ли изменения в квалификаторах const и volatile , что значительно улучшает безопасность типов во время компиляции по сравнению с с C. Он также предлагает полностью безопасное приведение за счет проверки во время выполнения.

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

10
ответ дан 27 November 2019 в 15:49
поделиться

Одно слово: макросы. Я не говорю, что макросам вообще нет места в C ++, но бывшие программисты на C, как правило, слишком часто их используют после перехода на C ++.

13
ответ дан 27 November 2019 в 15:49
поделиться

Очень опытные разработчики, не понимающие кастинг или даже объектно-ориентированное программирование:

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

(Имена классов были изменены, чтобы защитить невиновных, и я не могу вспомнить точные имена) У него был код на C ++, который прослушивал классы входящих сообщений и читал их.Раньше это работало так, что ему передавался класс Message, и он вставлял в него переменную, чтобы узнать, что это за тип сообщения. Затем он в стиле C преобразовал Message в другой специализированный класс, который он написал, унаследованный от Message. В этом новом классе были функции, которые извлекали данные так, как он этого хотел. Теперь это работало для него нормально, но теперь нет.

После многих часов просмотра кода он не увидел проблемы, и я посмотрел через его плечо. Я сразу сказал ему, что преобразовывать сообщение в стиле C в производный класс - не лучшая идея, а это не так. Он не согласился со мной и сказал, что делал это годами, и если это было неправильно, то все, что он делает, неправильно, потому что он часто использует этот подход. Кроме того, его поддержал подрядчик, который сказал мне, что я был неправ. Они оба утверждали, что это всегда работает, и код не изменился, так что не этот подход, а что-то еще нарушило его код.

Я посмотрел немного дальше и обнаружил разницу. Последняя версия класса Message имела виртуальную функцию и ранее не использовала virtual. Я сказал им обоим, что теперь существует виртуальная таблица, функции просматриваются и т.д. и т.п. комментарий, который я никогда не забуду: «Виртуал полностью портит полиморфизм и объектно-ориентированное программирование».

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

14
ответ дан 27 November 2019 в 15:49
поделиться

Добавление с использованием в файлы заголовков, чтобы они могли избегать имен вроде std :: string в объявлениях типов.

17
ответ дан 27 November 2019 в 15:49
поделиться

Отсутствие использования STL, особенно std :: string,

и / или

, использование std :: strings и возврат к старым строковым функциям c в труднодоступных местах.

19
ответ дан 27 November 2019 в 15:49
поделиться
  1. Запись определений классов, которые являются 2000 строк кода.
  2. Копирование и вставка этого определения класса в 12 разных мест.
  3. Использование операторов switch, когда подойдет простой виртуальный метод.
  4. Не удалось выделить память в конструкторе и освободить ее в деструкторе.
  5. Виртуальные методы, которые принимают необязательные аргументы.
  6. Написание циклов while для управления строками char *.
  7. Написание гигантских макросов длиной в страницу. (Вместо этого можно было использовать шаблоны).
18
ответ дан 27 November 2019 в 15:49
поделиться

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

30
ответ дан 27 November 2019 в 15:49
поделиться
  • с использованием char * вместо std :: string
  • с использованием массивов вместо std :: vector (или других контейнеров)
  • без использования других алгоритмов STL или библиотек, таких как boost, где это необходимо
  • , злоупотребление препроцессором, где константы , typedefs или шаблоны было бы лучше
  • написать код в стиле SESE (однократная запись, единичный выход)
38
ответ дан 27 November 2019 в 15:49
поделиться

Передача объектов с указателями вместо ссылок. Да, бывают случаи, когда вам нужны указатели в C ++, но ссылки более безопасны, поэтому вам следует использовать их, когда это возможно.

8
ответ дан 27 November 2019 в 15:49
поделиться

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

Особенно часто случается с локальными переменными, объявленными внутри функции.

1
ответ дан 27 November 2019 в 15:49
поделиться

Использование необработанных указателей и ресурсов вместо объектов RAII.

51
ответ дан 27 November 2019 в 15:49
поделиться

Непонятное использование структур по сравнению с классами, чрезмерное использование глобальных методов, которые принимают указатели объектов в качестве аргументов и глобально доступных указателей экземпляров, а-ля:

extern Application* g_pApp;
void RunApplication(Application* app, int flags);

Также (не говоря уже о том, что это совершенно бесполезно, но все же):

const void* buf;
1
ответ дан 27 November 2019 в 15:49
поделиться

с использованием указателей вместо ссылок

17
ответ дан 27 November 2019 в 15:49
поделиться

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

5
ответ дан 27 November 2019 в 15:49
поделиться

Предположим, что указанные программисты уже совершили ошибку, пытаясь изучить C ++:

Ошибки

  • Не использовать STL.
  • Пытаться обернуть все в классы.
  • Пытаться использовать шаблоны для всего.
  • Не используется Boost. (Я знаю, что Boost может быть настоящей PITA и кривой обучения, но C ++ - это просто C + без него. Boost дает C ++ немного батарей).
  • Без интеллектуальных указателей.
  • Без использования RAII.
  • Чрезмерное использование исключений.

Спорный

  • Переход на C ++. Не делай этого.
  • Попробуйте преобразовать C stdio в iostreams. Iostreams SUX. Не используйте это. Он изначально сломан. Посмотрите здесь .
  • Использование следующих частей библиотеки libstdc ++ :
    • строк (помимо их освобождения для меня, иди к черту)
    • локализация (какое, черт возьми, это имеет отношение к C ++, еще хуже, это ужасно)
    • ввод / вывод (64-битные смещения файлов? слышали о них?)
  • Наивно полагая, что вы все еще можете отлаживать из командной строки. Не используйте C ++ широко без средства разработки кода (IDE).
  • Читая блоги о C ++. Блоги C ++ придираются к тому, что по сути сводится к метаданным и сахару. Помимо хороших часто задаваемых вопросов и опыта, я еще не видел полезного блога о C ++. (Обратите внимание, что это сложная задача: я бы хотел прочитать хороший блог на C ++.)
8
ответ дан 27 November 2019 в 15:49
поделиться
  1. Решение проблемы вместо создания классового чудовища, гарантирующего вам медицинскую страховку и 401 тысячу льгот.

  2. Реализация lisp в одном файле и проектирование в нем.

  3. Написание обычных читаемых функций вместо замещающих операторов?

  4. Написание в стиле, понятном младшим программистам, которые считают хорошей практикой «не писать на C ++».

  5. Обращение к ОС на ее собственном языке.

1
ответ дан 27 November 2019 в 15:49
поделиться

Не использовать шаблоны при создании алгоритмов и структур данных (пример). Это делает вещи либо слишком локализованными, либо слишком общими

Например, писать

void qsort(MyStruct *begin, size_t length);  //too localized
void qsort(void *begin, size_t length, 
           size_t rec_size, int(compare*)(void*,void*));  //too generic

вместо

template <class RA_Iter>
void qsort(RA_Iter begin, size_t length);
  //uses RA_Iter::value_type::operator< for comparison
3
ответ дан 27 November 2019 в 15:49
поделиться