ВУЗ:
Составители:
Рубрика:
17
следует всегда явно определять конструктор копирования и опе-
рацию присваивания, выполняющие выделение памяти под динамиче-
ские поля объекта.
• Динамическая память, выделенная в конструкторе объекта, должна
освобождаться в его деструкторе. Невыполнение этого требования
приводит к утечкам памяти. Удаление нулевого указателя безо-
пасно (при этом ничего не происходит), поэтому если конструк-
торы, конструкторы копирования и операция присваивания написа-
ны правильно, любой указатель либо ссылается на выделенную об-
ласть памяти, либо равен нулю, и к нему можно применять delete
без проверки.
• Разница между конструктором копирования и операцией присваива-
ния заключается в том, что последняя работает в том случае,
когда объект-приемник уже существует, поэтому в ней перед вы-
делением динамической памяти следует освободить память занятую
ранее. Из этого следует, что при реализации операции при-
сваивания для классов, содержащих поля-указатели, необходимо
проводить проверку на самоприсваивание и в этом случае оста-
вить объект без изменений. Необходимо также помнить о том, что
операция присваивания должна возвращать ссылку на константу.
• В конструкторах для задания начальных значений полям рекомен-
дуется использовать инициализацию, а не присваивание. Инициа-
лизация более универсальна, так как может применяться в тех
случаях, когда присваиванием пользоваться нельзя (например,
при задании значений константным полям или ссылкам). Кроме то-
го, она выполняется более эффективно, потому что создание объ-
екта в C++ начинается с инициализации его полей конструктором
по умолчанию, после чего выполняется вызываемый конструктор.
Необходимо учитывать и тот факт, что поля инициализируются в
порядке их объявления, а не в порядке появления в списке ини-
циализации. Поэтому для уменьшения числа возможных ошибок по-
рядок указания полей в списке инициализации
конструктора дол-
жен соответствовать порядку их объявления в классе.
• Статические поля не должны инициализироваться в конструкторе,
поскольку им нужно присваивать начальное значение только один
раз для каждого класса, а конструктор выполняется для каждого
объекта класса. Статические поля инициализируются в глобальной
области определения (вне любой функции).
• Конструкторы копирования также должны использовать списки ини-
циализации полей, поскольку иначе для базовых классов и вло-
женных объектов будут вызваны конструкторы по умолчанию.
• Операция присваивания не наследуется, поэтому она должна быть
определена в производных классах. При этом из нее следует яв-
ным образом вызывать соответствующую операцию базового класса
• Открытое наследование класса Y из
класса X означает, что Y
представляет собой разновидность класса X, то есть более кон-
кретную, частную концепцию. Базовый класс X является более об-
щим понятием, чем Y. Везде, где можно использовать X, можно
использовать и Y, но не наоборот (вспомните, что на место ссы-
лок на базовый класс можно передавать ссылку на любой из про-
изводных). Необходимо помнить, что во время выполнения про-
граммы не существует иерархии классов и передачи сообщений
17 следует всегда явно определять конструктор копирования и опе- рацию присваивания, выполняющие выделение памяти под динамиче- ские поля объекта. • Динамическая память, выделенная в конструкторе объекта, должна освобождаться в его деструкторе. Невыполнение этого требования приводит к утечкам памяти. Удаление нулевого указателя безо- пасно (при этом ничего не происходит), поэтому если конструк- торы, конструкторы копирования и операция присваивания написа- ны правильно, любой указатель либо ссылается на выделенную об- ласть памяти, либо равен нулю, и к нему можно применять delete без проверки. • Разница между конструктором копирования и операцией присваива- ния заключается в том, что последняя работает в том случае, когда объект-приемник уже существует, поэтому в ней перед вы- делением динамической памяти следует освободить память занятую ранее. Из этого следует, что при реализации операции при- сваивания для классов, содержащих поля-указатели, необходимо проводить проверку на самоприсваивание и в этом случае оста- вить объект без изменений. Необходимо также помнить о том, что операция присваивания должна возвращать ссылку на константу. • В конструкторах для задания начальных значений полям рекомен- дуется использовать инициализацию, а не присваивание. Инициа- лизация более универсальна, так как может применяться в тех случаях, когда присваиванием пользоваться нельзя (например, при задании значений константным полям или ссылкам). Кроме то- го, она выполняется более эффективно, потому что создание объ- екта в C++ начинается с инициализации его полей конструктором по умолчанию, после чего выполняется вызываемый конструктор. Необходимо учитывать и тот факт, что поля инициализируются в порядке их объявления, а не в порядке появления в списке ини- циализации. Поэтому для уменьшения числа возможных ошибок по- рядок указания полей в списке инициализации конструктора дол- жен соответствовать порядку их объявления в классе. • Статические поля не должны инициализироваться в конструкторе, поскольку им нужно присваивать начальное значение только один раз для каждого класса, а конструктор выполняется для каждого объекта класса. Статические поля инициализируются в глобальной области определения (вне любой функции). • Конструкторы копирования также должны использовать списки ини- циализации полей, поскольку иначе для базовых классов и вло- женных объектов будут вызваны конструкторы по умолчанию. • Операция присваивания не наследуется, поэтому она должна быть определена в производных классах. При этом из нее следует яв- ным образом вызывать соответствующую операцию базового класса • Открытое наследование класса Y из класса X означает, что Y представляет собой разновидность класса X, то есть более кон- кретную, частную концепцию. Базовый класс X является более об- щим понятием, чем Y. Везде, где можно использовать X, можно использовать и Y, но не наоборот (вспомните, что на место ссы- лок на базовый класс можно передавать ссылку на любой из про- изводных). Необходимо помнить, что во время выполнения про- граммы не существует иерархии классов и передачи сообщений
Страницы
- « первая
- ‹ предыдущая
- …
- 15
- 16
- 17
- 18
- 19
- …
- следующая ›
- последняя »