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



|
159. Назначение исключений - не быть пойманными.
159. Назначение исключений - не быть пойманными. Как правило, исключение должно быть возбуждено, лишь если: Нет другого способа сообщить об ошибке (например, конструкторов, перегруженных...
158. Шаблоны не заменяют наследование; они его автоматизируют.
158. Шаблоны не заменяют наследование; они его автоматизируют. Главное, что нужно запомнить о шаблонах классов, - это то, что они порождают много определений классов. Как и всякий раз, когда у...
156. Всегда знайте размер шаблона после его расширения.
156. Всегда знайте размер шаблона после его расширения. Большинство книг демонстрирует шаблоны типа простого контейнера массива, подобного показанному на листинге 13. Вы не можете использовать...
155. Используйте встроенные шаблоны функций вместо параметризированных макросов.
155. Используйте встроенные шаблоны функций вместо параметризированных макросов. Приведенный ранее пример: #define SQUARE(x) ((x) * (x)) где: SQUARE(++x) расширяется до: ((++x)*(++x))...
Глава 8.З(H). Шаблоны
Глава 8.З(H). Шаблоны Многие проблемы с шаблонами в действительности вызваны учебниками, которые обычно настолько упрощенно рассматривают шаблоны, что вы заканчиваете чтение, не получив и...
154. Локальные перегрузки операторов new и delete опасны.
154. Локальные перегрузки операторов new и delete опасны. Здесь основной проблемой является то, что операторы new и delete, определенные в виде членов класса, следуют другим правилам, чем...
153. Вся память, выделенная в конструкторе, должна быть освобождена в деструкторе.
153. Вся память, выделенная в конструкторе, должна быть освобождена в деструкторе. Не выполнение этого обычно приводит к ошибке, но я видел программу, где это делалось намеренно. Упомянутая...
152. Используйте new/delete вместо malloc()/free().
152. Используйте new/delete вместо malloc()/free(). Нет гарантии, что оператор new() вызывает malloc() при запросе памяти для себя. Он может реализовывать свою собственную функцию управления...
151. Если можно, то делайте все преобразования типов с конструкторами.
151. Если можно, то делайте все преобразования типов с конструкторами. Распространенной ошибкой среди начинающих программистов на С++ является сумасбродство с преобразованием типов. Вы...
149. Перегруженной бинарной операции лучше всего быть встроенным (inline) псевдонимом операции приведения типа.
149. Перегруженной бинарной операции лучше всего быть встроенным (inline) псевдонимом операции приведения типа. Это правило относится к числу тех, которые будут изменены с улучшением качества...
148. Перегруженные операции должны работать точно так же, как они работают в С.
148. Перегруженные операции должны работать точно так же, как они работают в С. Главной новой проблемой здесь являются адресные типы lvalue и rvalue. Выражения типа lvalue легко описываются в...
147. Перегрузив одну операцию, вы должны перегрузить все сходные с ней операции.
147. Перегрузив одну операцию, вы должны перегрузить все сходные с ней операции. Это правило является продолжением предыдущего. После того, как вы сказали, что итератор работает совсем подобно...
146. Используйте перегрузку операций только для определения операций, имеющих аналог в С (без сюрпризов).
146. Используйте перегрузку операций только для определения операций, имеющих аналог в С (без сюрпризов). Перегрузка операций была реализована в языке прежде всего для того, чтобы вы могли...
145. Операция - это сокращение (без сюрпризов).
145. Операция - это сокращение (без сюрпризов). Операция - это не произвольный значок, означающий все, что вы ни пожелаете. Это аббревиатура англоязычного слова. Например, символ + значит...
144. Не вызывайте конструкторов из операции operator=( ).
144. Не вызывайте конструкторов из операции operator=( ). Хотя это правило говорит о перегруженном присваивании, на самом деле оно посвящено проблеме виртуальных функций. Соблазнительно...
143. Опасайтесь приведения типов (спорные вопросы С++).
143. Опасайтесь приведения типов (спорные вопросы С++). Приведение типов в С рассмотрено ранее, но и в С++ приведение вызывает проблемы. В С++ у вас также существует проблема нисходящего...
142. Защищенные функции обычно должны быть виртуальными.
142. Защищенные функции обычно должны быть виртуальными. Одним из смягчающих факторов в ранее описанной ситуации со сцеплением базового и производного классов является то, что объекту...
141. Не делайте функцию виртуальной, если вы не желаете, чтобы производный класс получил контроль над ней.
141. Не делайте функцию виртуальной, если вы не желаете, чтобы производный класс получил контроль над ней. Я читал, что все функции-члены необходимо делать виртуальными просто на всякий случай...
140. Функции базового класса, имеющие то же имя, что и функции производного класса, обычно должны быть виртуальными.
140. Функции базового класса, имеющие то же имя, что и функции производного класса, обычно должны быть виртуальными. 140. Функции базового класса, имеющие то же имя, что и функции производного...
139. Деструкторы всегда должны быть виртуальными.
139. Деструкторы всегда должны быть виртуальными. Рассмотрим этот код: class base { char *p; ~base() { p = new char [SOME_SIZE]; } base() { delete p; } }; class derived : public base { char...
138. Не вызывайте чисто виртуальные функции из конструкторов.
138. Не вызывайте чисто виртуальные функции из конструкторов. Это правило вытекает из только что рассмотренной картины. Определение чисто виртуальной функции (у которой =0 вместо тела) приводит...
137. Виртуальная функция не является виртуальной, если вызывается из конструктора или деструктора.
137. Виртуальная функция не является виртуальной, если вызывается из конструктора или деструктора. Это не столько правило, сколько констатация факта, хотя она и будет для многих неожиданностью....
136. Виртуальные функции - это те функции, которые вы не можете написать на уровне базового класса.
136. Виртуальные функции - это те функции, которые вы не можете написать на уровне базового класса. Виртуальные функции существуют ради двух целей. Во-первых, виртуальные функции определяют...
Глава 8.Д(E). Виртуальные функции
Глава 8.Д(E). Виртуальные функции Виртуальные функции дают объекту производного класса способность модифицировать поведение, определенное на уровне базового класса (или предоставить какие-то...
135. Суперобложки на С++ для существующих интерфейсов редко хорошо работают.
135. Суперобложки на С++ для существующих интерфейсов редко хорошо работают. Как правило, переменная должна инициализироваться во время объявления. Разделение инициализации и объявления иногда...
133. Используйте счетчики экземпляров объектов для инициализации на уровне класса.
133. Используйте счетчики экземпляров объектов для инициализации на уровне класса. Несколько разделов назад я рассматривал использование счетчика статических глобальных объектов для управления...
132. Конструкторы, не предназначенные для преобразования типов, должны иметь два или более аргумента.
132. Конструкторы, не предназначенные для преобразования типов, должны иметь два или более аргумента. С++ использует конструкторы для преобразования типов. Например, конструктор char* в 9-ой...
131. Производные классы должны обычно определять конструктор копии и функцию operator=( ).
131. Производные классы должны обычно определять конструктор копии и функцию operator=( ). При наследовании есть и другая связанная с копированием проблема. В одном месте руководства10 по языку...
Введение
Название этой книги отражает то, что я считаю основной трудностью при работе как с С++, так и с С: эти языки дают вам столько гибкости, что если у вас нет желания и способности призвать себя к...
130. Конструкторы копий должны использовать списки инициализации членов.
130. Конструкторы копий должны использовать списки инициализации членов. У наследования тоже есть свои проблемы с копированием. Конструктор копии все же остается конструктором, поэтому здесь...
129. Исходите из того, что члены и базовые классы инициализируются в случайном порядке.
129. Исходите из того, что члены и базовые классы инициализируются в случайном порядке. Многие неопытные программисты на С++ избегают списков инициализации членов, как я полагаю, потому, что...
126. Классы, имеющие члены-указатели, должны всегда определять конструктор копии и функцию operator=().
126. Классы, имеющие члены-указатели, должны всегда определять конструктор копии и функцию operator=(). Если класс не определяет методы копирования - конструктор копии и функцию operator=(), то...
125. Присваивание самому себе должно работать.
125. Присваивание самому себе должно работать. Определение operator=( ) должно всегда иметь следующую форму: class class_name { const class_name operator=( const class_name r ); }; const...
Глава 8.Г(D). Конструкторы, деструкторы и operator=( )
Глава 8.Г(D). Конструкторы, деструкторы и operator=( ) Функции конструкторов, деструкторов и операций operator=() имеют ту особенность, что их создает компилятор в том случае, если не создаете...
123. Не возвращайте ссылки на память, выделенную оператором new.
123. Не возвращайте ссылки на память, выделенную оператором new. Каждый вызов new должен сопровождаться delete - подобно malloc() и free(). Я иногда видел людей, старающихся избежать накладных...
122. Не возвращайте ссылки (или указатели) на локальные переменные.
122. Не возвращайте ссылки (или указатели) на локальные переменные. Эта проблема проявляется и в С, где вы не можете вернуть указатель на локальную переменную. Не возвращайте ссылку на объект,...
121. Никогда не используйте ссылки в качестве результатов, пользуйтесь указателями.
121. Никогда не используйте ссылки в качестве результатов, пользуйтесь указателями. Использование ссылочных аргументов в языке программирования вызвано четырьмя причинами: Они нужны вам для...
119. Не портьте область глобальных имен: проблемы С++.
119. Не портьте область глобальных имен: проблемы С++. Определение класса обеспечивает отличный способ вывода идентификатора из области глобальных имен, потому что эти идентификаторы должны...
118. Наследование - это форма сцепления.
118. Наследование - это форма сцепления. Наследование - не панацея, потому что оно является, прежде всего, формой сцепления. Когда вы изменяете базовый класс, то изменение затрагивает все...
117. Избегайте дружественных классов.
117. Избегайте дружественных классов. Сцепление происходит лишь до определенной степени. Тесное сцепление между классами происходит, когда вы используете ключевое слово friend. В этом случае,...
Глава 8.Б(B). Проблемы сцепления
Глава 8.Б(B). Проблемы сцепления Концепция сцепления описана ранее в общем виде. Я также указал наиболее важное правило С++ для сокращения числа отношений сцепления: Все данные должны быть...
116. Избегайте перегрузки функций и аргументов, используемых по умолчанию.
116. Избегайте перегрузки функций и аргументов, используемых по умолчанию. Это правило не применяется к конструкторам и функциям перегрузки операций. Перегрузка функций, подобно многим другим...
115. Не размещайте тела функций в определениях классов.
115. Не размещайте тела функций в определениях классов. Здесь есть несколько проблем. Если вы действительно поместите тело функции в определение класса таким образом: class amanda { public:...
114. Используйте структуры только тогда, когда все данные открытые и нет функций-членов.
114. Используйте структуры только тогда, когда все данные открытые и нет функций-членов. Это правило является вариантом принципа если это похоже на С, то должно и действовать как С ....
113. Используйте константы.
113. Используйте константы. В программы на С класс памяти const часто не включается. На самом деле это просто небрежность, но она мало влияет на возможности в С. Так как С++ гораздо разборчивее...
112.1. Функция-член должна обычно использовать закрытые поля данных класса.
112.1. Функция-член должна обычно использовать закрытые поля данных класса. Так как все открытые функции-члены являются обработчиками сообщений, а все закрытые функции и поля данных просто...
112. Проектируйте с учетом наследования.
112. Проектируйте с учетом наследования. Никогда не надейтесь, что класс не будет использоваться в качестве базового класса. Сосредоточимся на случае с примером управляющего элемента-редактора...
111. Откажитесь от выражений языка С, когда программируете на С++.
111. Откажитесь от выражений языка С, когда программируете на С++. Многие из проблем, рассмотренных в предыдущих правилах, вызваны программистами на С, не желающими отказаться от знакомых...
110.1. Не пользуйтесь функциями типа get/set (чтения и присваивания значений).
110.1. Не пользуйтесь функциями типа get/set (чтения и присваивания значений). Это правило в действительности то же, что и предыдущее все данные должны быть закрытыми . Я выделил его, потому...
110. Никогда не допускайте открытого доступа к закрытым данным.
110. Никогда не допускайте открытого доступа к закрытым данным. Все данные в определении класса должны быть закрытыми. Точка. Никаких исключений. Проблема здесь заключается в тесном сцеплении...