Программирование



|
108. Проектируйте структуры данных в последнюю очередь.
108. Проектируйте структуры данных в последнюю очередь. Добавление полей данных выполняется в процессе проектирования в последнюю очередь. Другими словами, после того, как вы разработали...
107. Используйте закрытые базовые классы лишь когда вы должны обеспечить виртуальные замещения.
107. Используйте закрытые базовые классы лишь когда вы должны обеспечить виртуальные замещения. Главная выгода от наследования состоит в том, что вы можете писать универсальный код,...
104. Инициализируйте виртуальные базовые классы при помощи конструктора, используемого по умолчанию.
104. Инициализируйте виртуальные базовые классы при помощи конструктора, используемого по умолчанию. Вы можете свести до минимума рассмотренные ранее проблемы, стараясь придерживаться следующих...
101. С++ - это не Smalltalk: избегайте общего класса object.
101. С++ - это не Smalltalk: избегайте общего класса object. Процесс разработки иерархии снизу вверх обычно дает вам лес из маленьких деревьев, скорее широких, чем высоких. Построение иерархии...
99.1. Базовые классы должны иметь более одного производного объекта.
99.1. Базовые классы должны иметь более одного производного объекта. Это просто другая точка зрения на предыдущее правило. Если базовый класс является способом концентрации сходных свойств в...
99. Затем проектируйте иерархию снизу вверх.
99. Затем проектируйте иерархию снизу вверх. После того, как вы спроектировали систему объектов и сообщений, вы можете приступать к иерархии. Откиньтесь на спинку кресла и взгляните на...
98. Сначала проектируйте объекты.
98. Сначала проектируйте объекты. Первым пунктом повестки дня всегда должно быть проектирование системы обмена сообщениями, обычно посредством диаграмм объектов типа описанных Бучем. Начиная с...
97. Наследование - это процесс добавления полей данных и методов-членов.
97. Наследование - это процесс добавления полей данных и методов-членов. В С++ производный класс может рассматриваться как механизм добавления полей данных и обработчиков сообщений к...
95. Вам обычно не удастся переделать имеющуюся структурную программу в объектно-ориентированную.
95. Вам обычно не удастся переделать имеющуюся структурную программу в объектно-ориентированную. Одним из побочных эффектов только что описанной организации является то, что обычно невозможно...
94. Сообщения должны выражать возможности, а не запрашивать (предлагать ?) информацию.
94. Сообщения должны выражать возможности, а не запрашивать (предлагать ?) информацию. Объектно-ориентированные и структурные системы склонны подходить к проблемам с диаметрально...
93. Пользуйтесь контрольными таблицами.
93. Пользуйтесь контрольными таблицами. Одной из причин того, что С++ имеет такую крутую кривую обучения, заключается в том, что вы должны отслеживать большое количество маленьких деталей,...
92. Библиотеки классов С++ обычно не могут быть использованы неискушенными пользователями.
92. Библиотеки классов С++ обычно не могут быть использованы неискушенными пользователями. Одна большая ложь о С++, которая распространяется продавцами с острыми зубами и зачесанными назад...
91. Рассчитывайте потратить больше времени на проектирование и меньше на разработку.
91. Рассчитывайте потратить больше времени на проектирование и меньше на разработку. Мой опыт свидетельствует, что, если исключить период изучения С++, объектно-ориентированные системы требуют...
90.1. Если проект не ориетирован на объекты, то используйте С.
90.1. Если проект не ориетирован на объекты, то используйте С. Позвольте мне начать, сказав, что нет абсолютно ничего дурного в хорошо выполненном структурном проектировании. Как то так...
Глава 8. Правила программирования на С++
Глава 8. Правила программирования на С++ Эта глава книги содержит правила, уникальные для программирования на С++. Как мной было сказано во Введении , эта книга не является учебником по С++,...
Избегайте goto, за исключением...
Избегайте goto , за исключением... Правила в этом разделе применяйте только к программам на С. Оператор goto не должен никогда использоваться в С++ по причинам, рассмотренным в правиле 54 -...
88. Используйте указатели вместо индексов массива.
88. Используйте указатели вместо индексов массива. Вообще, инкрементирование указателя - лучший способ перемещения по массиву, чем индекс массива. Например, простой цикл, подобный следующему,...
87. Указатели должны указывать на адрес, больший, чем базовый для массива.
87. Указатели должны указывать на адрес, больший, чем базовый для массива. Это правило подтверждено стандартом ANSI С, но многие программисты, похоже, не подозревают о том способе, которым язык...
86. Для битового поля размером 1 бит должен быть определен тип unsigned.
86. Для битового поля размером 1 бит должен быть определен тип unsigned. 86. Для битового поля размером 1 бит должен быть определен тип unsigned. После того, как ANSI С позволил назначать...
85.5. Не делайте вид, что С поддерживает булевый тип (#define TRUE).
85.5. Не делайте вид, что С поддерживает булевый тип (#define TRUE). Нижеследующее может скорее вызвать беду, чем нет: #define TRUE 1 #define FALSE 0 Любая отличная от нуля величина в С...
85.4. Рассчитывайте, что ваш читатель знает С.
85.4. Рассчитывайте, что ваш читатель знает С. Не делайте чего-то подобного этому: #define SHIFT_LEFT(x, bits) ((x) << (bits)) Программисты на С знают, что << означает сдвиг влево ....
85.3. Не используйте флагов завершения.
85.3. Не используйте флагов завершения. Флаг завершения типа готов едва ли нужен в С или С++. Его использование просто добавляет одну лишнюю переменную в процедуру. Не делайте так: BOOL готов =...
85.2. Избегайте битовых масок; используйте битовые поля.
85.2. Избегайте битовых масок; используйте битовые поля. Многие программисты, в особенности те, кто начинал жизнь с языком ассемблера, привыкли пользоваться битовыми масками, а не битовыми...
85.1. Устраняйте беспорядок.
85.1. Устраняйте беспорядок. Язык С предоставляет богатый набор операторов и, как следствие, предлагает множество способов ничего не делать, что и иллюстрируется примерами из таблицы 2. Таблица...
85. Подавляйте демонов запутанности (Часть 2).
85. Подавляйте демонов запутанности (Часть 2). Демоны запутанности особенно опасны в С. Кажется, что этот язык сам собой поощряет выбор неестественно усложненных решений для простых задач....
Глава 7. Правила, относящиеся к языку С
Глава 7. Правила, относящиеся к языку С В этой главе рассматриваются специфичные для С правила программирования, не встречавшиеся в предыдущих разделах. на главную книги правила...
84. Если все альтернативы отпали, то используйте препроцессор.
84. Если все альтернативы отпали, то используйте препроцессор. Мы увидим в главе, посвященной С++, что препроцессор С не играет большой роли в С++. Хотя есть немного мест, где он все еще...
83.1. Никогда не используйте макросы для символьных констант.
83.1. Никогда не используйте макросы для символьных констант. Например: #define SPACE ' ' имеет смысл, если только вы намерены использовать вместо пробела другой символ (как если бы вы...
83. Аргумент параметризированного макроса не должен появляться в правой части более одного раза.
83. Аргумент параметризированного макроса не должен появляться в правой части более одного раза. Макрос SQUARE() даже в своем модифицированном виде представил выше серьезную проблему. Дано:...
82. enum и const лучше, чем макрос.
82. enum и const лучше, чем макрос. Директива #define должна быть вашим последним средством при определении значения константы. Рассмотрим следующую рассмотренную ранее распространенную ошибку:...
81.2. Помещайте тело макроса и его аргументы в круглые скобки.
81.2. Помещайте тело макроса и его аргументы в круглые скобки. Это правило одно из основных, но я обнаружил, что множество людей, пользующихся С ежедневно, его забыли. Вот классическая задача:...
81.1. Операция ?: не то же самое, что и оператор if/else.
81.1. Операция ?: не то же самое, что и оператор if/else . Последняя строка в таблице 1 относится к другому спорному вопросу. Условная операция - это простой оператор. Она используется лишь в...
81. Вы должны быть всегда способны заменить макрос функцией.
81. Вы должны быть всегда способны заменить макрос функцией. Это вариант для макросов правила не нужно неожиданностей (без сюрпризов) . Что-то, похожее внешне на функцию, должно действовать...
80. Используйте вложенные директивы #include.
80. Используйте вложенные директивы #include . Хотя большинство из правил в этой главе говорят вам, как избежать использования препроцессора, механизм включения файлов директивой #include...
79. Все из одного .h файла должно быть использовано в по меньшей мере двух .c файлах.
79. Все из одного .h файла должно быть использовано в по меньшей мере двух .c файлах. Это правило говорит само за себя - не загромождайте область глобальных имен идентификаторами, которые не...
Глава 6. Препроцессор
Глава 6. Препроцессор Многие свойства языка С++ делают препроцессор С менее важным, чем он был по традиции. Тем не менее, препроцессор иногда нужен даже в программе на С++ и, естественно,...
78. Не используйте системно-зависимых функций для сообщений об ошибках.
78. Не используйте системно-зависимых функций для сообщений об ошибках. Многие среды с оконным интерфейсом не поддерживают понятия стандартного устройства для вывода или для сообщений об...
77. Не выводите сообщения об ошибке, если она исправима.
77. Не выводите сообщения об ошибке, если она исправима. Библиотечные подпрограммы (и большинство подпрограмм на языках низкого уровня) не должны выводить сообщений об ошибках. Они должны...
76. Сообщение об ошибке должно подсказывать пользователю, как ее исправить.
76. Сообщение об ошибке должно подсказывать пользователю, как ее исправить. Когда-то, во времена CP/M, отладчик DDT имел единственное сообщение об ошибке. Не имело значения, что вы натворили,...
75. Тестовые подпрограммы не должны быть интерактивными.
75. Тестовые подпрограммы не должны быть интерактивными. Мне часто показывают тестовые программы, имеющие усовершенствованный интерактивный интерфейс пользователя. Это не только является пустой...
74. Динамическая память - дорогое удовольствие.
74. Динамическая память - дорогое удовольствие. Следующей основной проблемой при использовании malloc()/ free() (или new/delete) является время, требуемое для управления памятью; оно может быть...
73. Помещайте код, динамически распределяющий и освобождающий память, в одном и том же месте.
73. Помещайте код, динамически распределяющий и освобождающий память, в одном и том же месте. Утечки памяти - выделенную память забыли освободить - являются большой проблемой в приложениях,...
72. Не старайтесь порадовать lint.
72. Не старайтесь порадовать lint. Lint является программой проверки синтаксиса для языка С. (Также имеется версия для С++ в среде MS-DOS/Windows. Она выпускается фирмой Gimple Software). Хотя...
71. Немедленно обрабатывайте особые случаи.
71. Немедленно обрабатывайте особые случаи. Пишите свои алгоритмы таким образом, чтобы они обрабатывали вырожденные случаи немедленно. Вот тривиальный пример того, как сделать это неправильно:...
70. Опасайтесь приведения типов (спорные вопросы С).
70. Опасайтесь приведения типов (спорные вопросы С). Оператор приведения типов часто понимается неправильно. Приведение типов не указывает компилятору считать эту переменную принадлежащей к...
69. Не делайте предположений о размерах.
69. Не делайте предположений о размерах. Классической проблемой является код, исходящий из того, что тип int имеет размер 32 бита. Следующий фрагмент не работает, если у вас 32-битный указатель...
68. Не нужно магических чисел.
68. Не нужно магических чисел. В основном тексте вашей программы не должно быть чисел в явном виде. Используйте перечислитель или константу для того, чтобы дать числу символическое имя. (Я уже...
67. Избегайте явно временных переменных.
67. Избегайте явно временных переменных. Большинство переменных, используемых лишь один раз, попадают в эту категорию. Например, вместо: int x = *p++; f( x ); должно быть: f( *p++ ); Редко...
66.2. Всегда проверяйте код, вызывающий ошибку.
66.2. Всегда проверяйте код, вызывающий ошибку. Это должно быть очевидно, но комитет ISO/ANSI по С++ потребовал, чтобы оператор new вызывал исключение, если он не смог выделить память, потому...
66.1. Рассчитывайте на невозможное.
66.1. Рассчитывайте на невозможное. Оператор switch всегда должен иметь предложение с ключевым словом default для ситуации по умолчанию, особенно если эта ситуация не должна возникать: f( int i...