|
Программирование >> Перегруженные имена функций и идентификаторы
В следующем примере деструктор для объекта b будет вызван первым, а только затем деструктор для объекта a: void userCode() Fred a; Fred b; ... В каком порядке вызываются деструкторы для массивов объектов? В порядке обратном созданию: первым создан - последним будет уничтожен. В следующем примере порядок вызова деструкторов будет таким: a[9], a[8], a[1], a[0]: void userCode() Fred a[10]; ... Могу ли я перегрузить деструктор для своего класса? Нет. У каждого класса может быть только один деструктор. Для класса Fred он всегда будет называться Fred::~Fred(). В деструктор никогда не передаётся никаких параметров, и сам деструктор никогда ничего не возвращает. Всё равно вы не смогли бы указать параметры для деструктора, потому что вы никогда на вызываете деструктор напрямую (точнее, почти никогда). Могу ли я явно вызвать деструктор для локальной переменной? Нет! Деструктор всё равно будет вызван еще раз при достижении закрывающей фигурной скобки } конца блока, в котором б1а создана локальная переменная. Этот вызов гарантируется языком, и он происходит автоматически; нет способа этот вызов предотвратить. Но последствия повторного вызова деструктора для одного и того же объекта могут быть плачевными. Бах! И вы покойник... А что если я хочу, чтобы локальная переменная умерла раньше закрывающей фигурной скобки? Могу ли я при крайней необходимости вызвать деструктор для локальной переменной? Нет! Предположим, что (желаемый) побочный эффект от вызова деструктора для локального объекта File заключается в закрытии файла. И предположим, что у нас есть экземпляр f класса File и мы хотим, чтобы файл f был закрыт раньше конца своей области видимости (т.е., раньше }): void someCode() File f; ... [Этот код выполняется при открытом f] ... <-- Нам нужен эффект деструктора f здесь ... [Этот код выполняется после закрытия f] ... Для этой проблемы есть простое решение. Но пока запомните только следующее: нельзя явно вызывать деструктор. Хорошо, я не буду явно вызывать деструктор. Но как мне справиться с этой проблемой? Просто поместите вашу локальную переменную в отдельный блок {...}, соответствующий необходимому времени жизни этой переменной: void someCode() File f; ... [В этом месте f еще открыт] ... деструктор f будет автоматически вызван здесь! ... [В этом месте f уже будет закрыт] ... А что делать, если я не могу поместить переменную в отдельный блок? В большинстве случаев вы можете воспользоваться дополнительным блоком {...} для ограничения времени жизни вашей переменной. Но если по какой-то причине вы не можете добавить блок, добавьте функцию-член, которая будет выполнять те же действия, что и деструктор. Но помните: вы не можете сами вызывать деструктор! Например, в случае с классом File, вы можете добавить метод close(). Обычный деструктор будет вызывать close(). Обратите внимание, что метод close() должен будет как-то отмечать объект File, с тем чтобы последующие вызовы не пытались закрыть уже закрытый файл. Например, можно устанавливать переменную-чен fileHandle в какое-нибудь неиспользуемое значение, типа -1, и проверять вначале, не содержит ли fileHandle значение -1. class File { public: void close(); ~File(); ... private: int fileHandle ; fileHandle >= 0 если/только если файл открыт File::~File() close(); void File::close() if (fileHandle >= 0) { ... [Вызвать системную функцию для закрытия файла] fileHandle = -1; Обратите внимание, что другим методам класса File тоже может понадобиться проверять, не установлен ли fileHandle в -1 (т.е., не закрыт ли файл). Также обратите внимание, что все конструкторы, которые не открывают файл, должны устанавливать fileHandle в -1. А могу ли я явно вызывать деструктор для объекта, созданного при помощи new? Скорее всего, нет.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |