Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Глава 19. Копирующий конструктор 205
Ресурсом, требующим глубокого копирования, является не только память в куче, но и открытые файлы, порты, выделенные аппаратные средства (например, принтеры) и т.п. Кроме того, все эти типы ресурсов должны освобождаться деструктором. Таким образом, можно вывести правило: глубокое копирование необходимо всегда, когда деструктор класса осво- бождает ресурсы.
Копии создаются не только тогда, когда объекты передаются в функции по значе- нию. Копии объектов могут создаваться и по другим причинам, например при возвра- те объекта по значению. Рассмотрим пример. //возвращает объект по значению main (int argcs, char* { Student s; s //в результате вызова будет // создан временный объект return 0; ) Функция п возвращает объект по значению. В конечном счете этот объект бу- дет скопирован в s, но где он находится до этого? Для хранения таких объектов C++ создает временные объекты (такие объекты соз- даются и в некоторых других случаях). скажете вы, C++ создает вре- менные объекты, но откуда он знает, когда их надо уничтожать?" (Спасибо за хоро- ший вопрос!) В нашем примере это не имеет особого значения, поскольку временный объект выйдет из области видимости, как только копирующий конструктор скопирует его в s. Но что, если s будет определено как ссылка? int main (int argcs, char* (
//.. теперь ?. . . return } Теперь период жизни временного объекта имеет большое поскольку ссылка ref s продолжает свое существование независимо от существования объекта! В приведенном ниже примере я отметил место, начиная с которого временный объект становится недоступен. Student int int main argcs, char* { int x; // Создаем объект Student, вызывая // а затем передаем этот объект функции // возвращает целочисленное значение, // которое для выполнения // некоторых // Весь этот период временный объект, возвращенный // функцией fnl (), доступен х 3*fn2 (fnl () ) + Ю;
206 Часть "Классическое" программирование // временный объект, который вернула функция // недоступен код.. . return 0; } Таким образом, пример с использованием ссылки неверен, поскольку объект вый- дет из области видимости, a ref S будет продолжать существовать и ссылка будет ука- зывать на несуществующий объект. Вы можете подумать, что изучение всего этого копирования объектов туда и об- ратно пустая трата времени. Что, если вы не хотите делать все эти копии? Самое простое решение заключается в передаче и приеме объектов функции по ссылке. Это исключает все описанные неприятности. Но как убедиться, что C++ не создает временных объектов незаметно для вас? Допустим, ваш класс использует ресурсы, которые вы не хотите копировать. Что же вам Можно просто использовать вывод сообщения в копирующем конструкторе, кото- рое предупредит вас о том, что была сделана копия. А можно объявить копирующий конструктор защищенной функцией, как показано в приведенном ниже clas s Student {
s){}
остальное как обычно... i ; Такой подход исключит использование копирующего конструктора любыми внеш- ними функциями, включая сам C++, а значит, запретит создание копий ваших тов studen t (позволяя при этом создавать копии функциям-членам). Использование копирующего конструктора для создания временных объектов и копий объектов вызывает один интересный вопрос. Рассмотрим очередной пример. class Student {
{ что угодно...
s) { что угодно. . .
void {
int main argcs, { Studentrns;
return 0; ) И в самом деле, почему бы не объявить копирующий конструктор класса как ? Однако такое объявление попросту невозможно! |
Последнее изменение этой страницы: 2019-04-19; Просмотров: 178; Нарушение авторского права страницы