|
Программирование >> Расширенная версия языка c++
class samp { int i ; public : samp (int n) { i i; } void set i(int n) { i = n; int get i() ( return i; } /* Заменяет переменную о, i ее квадратом. Это влияет на объект, используемый при вызове void 3qr it (samp *о) o->set i(o->get i() * o->get i ( ) ) ; cou Для объекта а значение i равно: o->get i(); cout \n ; int main{) ; samp a sqrit (Sa) ; функции it ( } передан адрес объекта а cou Теперь значение объекта а в функции main() изменилось: ; cou t i ( ) ; выводится 100 return 0; Теперь результат работы программы следующий: i равно: 100 а в функции изменилось: 100 Для объекта а значение Теперь екие объекта 4. Если при передаче объекта в функцию делается его копия, это означает, что появляется новый объект. Когда работа функции, которой б1л передан объект, завершается, то копия аргумента удаляется. Возникают два вопроса. Во-первых, вызывается ли конструктор объекта, когда создается его копия? Во-втор1х, вызывается ли деструктор объекта, когда эта копия удаляется? Ответ на первый вопрос может показаться неожиданным. Когда при вызове функции создается копия объекта, конструктор копии не вы-з1вается. См1сл этого понять просто. Поскольку конструктор об1чно используется для инициализации некоторых составляющих он не должен вызываться при создании копии уже существующего объекта. Если бы это было то изменилось бы содержимое объекта, поскольку при передаче объекта функции необходимо его текущее, а не начальное состояние. class samp { int i; . . public: n) ( i = n; , cout Работа кокструктораХп ; -sarapO { cout Работа деструктора\n ; ) .. . . int get i() { return i; } . Возвращает квадрат переменной o.i int sqr it (samp о) return t i 0 *o.get i(); \ . , . .. int main () samp a (10) ; г.- -r > . - , = jp J cout sqr it(a) Vn ; return 0; Эта программа выводит следующее: Работа конструктора 100 Работа деструктора Работа деструктора Обратите внимание, что конструктор вызывается только один раз. Это происходит при создании объекта а. Однако деструктор вызывается дважды. Однако если работа завершается и копия удаляется, то деструктор копии вызывается. Это происходит потому, что иначе оказались бы невыполненными некоторые необходимые операции. Например, для копии может быть выделена память, которую, после завершения работы необхо- димо освободить. Итак, при создании копии объекта, когда он используется в качестве аргумента функции, конструктор копии не вызывается. Однако, когда копия удаляется (обычно это происходит при возвращении функцией своего значения), вызывается ее деструктор. Следующая программа иллюстрирует эти положения: #include <iostream> . а.-:< using namespace std; .и, Первый раз он вызывается для копии, созданной, когда объект а бьш передан функции sqr it(), другой - для самого объекта а. . . . Тот факт, что деструктор объекта, являющегося копией передаваемого функции аргумента, выполняется при завершении работы функции, может стать потенциальным источником проблем. Например, если для объекта, используемого в качестве аргумента, выделена динамическая память, которая освобождается при его удалении, тогда и для копии объекта при вызове деструктора будет освобождаться та же самая память. Это приведет к повреждению исходного объекта. (Для примера см. упражнение 2 данного раздела.) Чтобы избежать такого рода ошибок, важно убедиться в том, что деструктор копии объекта, используемого в качестве аргумента, не вызывает никаких побочных эффектов, которые могли бы повлиять на -исходный аргумент. Как вы жно, уже догадались, одним из способов обойти проблему удаления деструктором необходимых данных при вызове функции с объектом в качестве аргумента должна стать передача функции не самого объекта, а его адреса. Если функции передается адрес объекта, то нового объекта не создается и поэтому при возвращении функцией своего значения деструктор не вызывается. (Как вы увидите в следующей главе, в C++ имеется и иное, более элегантное решение этой задачи.) Тем не менее имеется другое, лучшее решение, о котором вы узнаете, изучив особый тип конструктора, а именно конструктор копий (copy constructor). Конструктор копий позволяет точно определить порядок создания копий объекта. (О конструкторах копий рассказывается в главе 5.) Упра)кнени 1. Используя класс stack из раздела 3.1, пример 2, добавьте в программу функцию которой в качестве аргумента передается объект типа stack. Эта функция должна выводить содержимое стека на экран. 2. Как вы знаете, если объект передается функции, создается копия этого объекта. Далее, когда эта функция возвращает свое значение, вызывается деструктор копии. Вспомнив это, ответьте, что неправильно в следующей программе? В это отрамме есть ошибка i ttinclude <iostream> ttinclude <cstdlib> - . using namespace std; class dyna f int *p; piiblic: dyna(int i); ~dyna() e(p); cou << освобождение ти\п ; }
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |