Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Листинг 10.5. Конструктор-копировщик






1: // Листинг 10.5.

2: // Конструктор-копировщик

3:

4: #include < iostream.h>

5:

6: class CAT

7: {

8: public:

9: CAT(); // конструктор по умолчанию

10: CAT (const CAT &); // конструктор-копировщик

11: ~CAT(); // деструктор

12: int GetAge() const { return *itsAge; }

13: int GetWeight() const { return *itsWeight; }

14: void SetAge(int age) { *itsAge = age; }

15:

16: private:

17: int *itsAge;

18: int *itsWeight;

19: };

20:

21: CAT:: CAT()

22: {

23: itsAge = new int;

24: itsWeight = new int;

25: *itsAge = 5;

26: *itsWeight = 9;

27: }

28:

29: CAT:: CAT(const CAT & rhs)

30: {

31: itsAge = new int;

32: itsWeight = new int;

33: *itsAge = rhs.GetAge(); // открытый метод доступа

34: *itsWeight = *(rhs.itsWeight); // закрытый метод доступа

35: }

36:

37: CAT:: ~CAT()

38: {

39: delete itsAge;

40: itsAge = 0;

41: delete itsWeight;

42: itsWeight = 0;

43: }

44:

45: int main()

46: {

47: CAT frisky;

48: cout < < " frisky's age: " < < frisky.GetAge() < < endl;

49: cout < < " Setting frisky to 6...\n";

50: frisky.SetAge(6);

51: cout < < " Creating boots from frisky\n";

52: CAT boots(frisky);

53: cout < < " frisky's age: " < < frisky.GetAge() < < endl;

54: cout < < " boots' age; " < < boots.GetAge() < < endl;

55: cout < < " setting frisky to 7...\n";

56: frisky.SetAge(7);

57: cout < < " frisky's age: " < < frisky.GetAge() < < endl;

58: cout < < " boot's age: " < < boots.GetAge() < < endl;

59: return 0;

60: }

 

Результат:

frisky's age: 5

Setting frisky to 6...

Creating boots from frisky

frisky's age: 6

boots' age: 6

setting frisky to 7...

frisky's age: 7

boots' age: 6

 

Анализ: В строках программы с 6 по 19 объявляется класс CAT. Обратите внимание, что в строке 9 объявляется конструктор по умолчанию, а в строке 10 — конструктор-копировщик.

В строках 17 и 18 объявляется две переменные-члены, представляющие собой указатели на целочисленные значения. В реальной жизни трудно вообразить, для чего может понадобиться создание переменных-членов как указателей на целочисленные значения. Но в данном случае такие переменные являются отличными объектами для демонстрации методов управления переменными-членами, сохраненными в динамической области памяти.

Конструктор по умолчанию в строках с 21 по 27 выделяет для переменных области динамической памяти и инициализирует эти переменные.

Работа копировщика начинается со строки 29. Обратите внимание, что в копировщике задан параметр rhs. Использовать в параметрах копировщиков символику rhs, что означает right-hand side (стоящий справа), — общепринятая практика. Если вы посмотрите на строки 33 и 34, то увидите, что в выражениях присваивания имена параметров копировщика располагаются справа от оператора присваивания (знака равенства).

Вот как работает копировщик. Строки 31 и 32 выделяют свободные ячейки в области динамической памяти. Затем, в строках 33 и 34 в новые ячейки переписываются значения из существующего класса CAT.

Параметр rhs соответствует объекту классу CAT, который передается в копировщик в виде константной ссылки. Как объект класса CAT, rhs содержит все переменные- члены любого другого класса CAT.

Любой объект класса CAT может открыть доступ к закрытым переменным-членам для любого другого объекта класса CAT. В то же время для внешних обращений всегда лучше создавать открытые члены, где это только возможно. Функция-член rhs.GetAge() возвращает значение, сохраненное в переменной-члене itsAge, адрес которой представлен в rhs.

Процедуры, осуществляемые программой, продемонстрированы на рис. 10.3. Значение, на которое ссылалась переменная-член исходного класса CAT, копируется в новую ячейку памяти, адрес которой представлен в такой же переменной-члене нового класса CAT.

В строке 47 вызывается объект frisky из класса CAT. Значение возраста, заданное в frisky, выводится на экран, после чего в строке 50 переменной возраста присваивается новое значение — 6. В строке 52 методом копирования объекта frisky создается новый объект boots класса CAT. Если бы в качестве параметра передавался объект frisky, то вызов копировщика осуществлялся бы компилятором.

В строках 53 и 54 выводится возраст обеих кошек. Обратите внимание, что в обоих случаях в объектах frisky и boots записан возраст 6, тогда как если бы объект boots создавался не методом копирования, то по умолчанию было бы присвоено значение 5. В строке 56 значение возраста в объекте было изменено на 7 и вновь выведены на экран значения обоих объектов. Значение объекта frisky действительно изменилось на 7, тогда как в boots сохранилось прежнее значение возраста 6. Это доказывает, что переменная объекта frisky была скопирована в объект boots по новому адресу.

 

Рис. 10.3 Пример глубинного копирования

 

Когда выполнение программы выходит за область видимости класса CAT, автоматически запускается деструктор. Выполнение деструктора класса CAT показано в строках с 37 по 43. Оператор delete применяется к обоим указателям — itsAge и itsWeigth, после чего оба указателя для надежности обнуляются.

 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.