ВУЗ:
Составители:
Рубрика:
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
- …
- следующая ›
- последняя »
