Чтение онлайн

на главную

Жанры

Освой самостоятельно С++ за 21 день.

Либерти Джесс

Шрифт:

20: {

21: itsWidth = 5;

22: itsLength = 10;

23: }

24:

25: Rectangle::Rectangle (int width, int length)

26: {

27: itsWidth = width;

28: itsLength = length;

29: }

30:

31: int main

32: {

33: Rectangle Rect1;

34: cout << "Rect1 width: " << Rect1.GetWidth << endl;

35: cout << "Rect1 length: " << Rect1.GetLength << endl;

36:

37: int aWidth, aLength;

38: cout << "Enter a width: ";

39: cin >> aWidth;

40: cout << "\nEnter a length: ";

41: cin >> aLength;

42:

43: Rectangle Rect2(aWidth, aLength);

44: cout << "\nRect2 width: " << Rect2.GetWidth << endl;

45: cout << "Rect2 length: " << Rect2.GetLength << endl;

46: return 0;

47: }

Результат:

Rect1 width: 5

Rect1 length: 10

Enter a width: 20

Enter a length: 50

Rect2 width: 20

Rect2 length: 50

Анализ:

Класс Rectangle объявляется в строках с 6 по 17. В классе представлены два конструктора: один использует значения по умолчанию (строка 9), а второй принимает значения двух целочисленных параметров (строка 10). В строке 33 прямоугольный объект создается с использованием первого конструктора. Значения размеров прямоугольника, принятые по умолчанию, выводятся на экран в строках 34 и 35. Строки программы с 37 по 41 выводят на экран предложения пользователю ввести собственные значения ширины и длины прямоугольника. В строке 43 вызывается второй конструктор, использующий два параметра с только что установленными значениями. И наконец, значения размеров прямоугольника, установленные пользователем, выводятся на экран в строках 44 и 45.

Как и при использовании других перегруженных функций, компилятор выбирает нужное объявление конструктора, основываясь на числе и типе параметров.

Инициализация объектов

До сих пор переменные-члены объектов задавались прямо в теле конструктора. Выполнение конструктора происходит в два этапа: инициализация и выполнение тела конструктора.

Большинство переменных может быть задано на любом из этих этапов: как во время инициализации, так и во время выполнения конструктора. Но логически правильнее, а зачастую и эффективнее, инициализировать переменные-члены во время инициализации конструктора. В следующем примере показана инициализация переменных-членов:

CAT: // имя конструктора и список параметров

itsAge(5), // инициализация списка

itsWeigth(8)

{} // тело конструктора

После скобки закрытия списка параметров конструктора ставится двоеточие. Затем перечисляются имена переменных-членов. Пара круглых скобок со значением за именем переменной используется для инициализации этой переменной. Если инициализируется сразу несколько переменных, то они должны быть отделены запятыми. В листинге 10.4 показана инициализация переменных конструкторов, взятых из листинга 10.3. В данном примере инициализация переменных используется вместо присвоения им значений в теле конструктора.

Листинг 10.4. Фрагмент программного кода с инициализацией переменных-членов

1: Rectangle::Rectangle:

2: itsWidth(5),

3: itsLength(10)

4: {

5: }

6:

7: Rectangle::Rectangle (int width, int length):

8: itsWidth(width),

9: itsLength(length)

10: {

11: }

Результат: Отсутствует

Анализ: Некоторые переменные можно только инициализировать и нельзя присваивать им значения: например, в случае использования ссылок и констант. Безусловно, переменной-члену можно присвоить значение прямо в теле конструктора, но для упрощения программы лучше по возможности устанавливать значения переменных-членов на этапе инициализации конструктора.

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

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

Когда объект передается как значение либо в функцию, либо из функции в виде возврата, всегда создается его временная копия. Если в программе обрабатывается объект, созданный пользователем, то для выполнения этих операций вызывается конструктор- копировщик класса, как было показано на предыдущем занятии в листинге 9.6.

Все копировщики принимают только один параметр — ссылку на объект в том же классе. Разумно будет сделать эту ссылку константной, так как конструктор не должен изменять передаваемый в него объект. Например:

CAT(const CAT & theCat);

В данном случае конструктор CAT принимает константную ссылку на объект класса CAT. Цель использования конструктора-копировщика состоит в создании копии объекта theCat.

Копировщик, заданный компилятором по умолчанию, просто копирует все переменные-члены из указанного в параметре объекта в переменные-члены нового объекта. Такое копирование называется поверхностным; и, хотя оно подходит для большинства случаев, могут возникнуть серьезные проблемы, если переменные-члены окажутся указателями на ячейки динамической памяти.

Поверхностное копирование создает несколько переменных-членов в разных объектах, которые ссылаются на одни и те же ячейки памяти. Глубинное копирование переписывает значения переменных по новым адресам.

Например, класс CAT содержит переменную-член theCat, которая указывает на ячейку в области динамической памяти, где сохранено некоторое целочисленное значение. Копировщик по умолчанию скопирует переменную theCat из старого класса CAT в переменную theCat в новом классе CAT. При этом оба объекта будут указывать на одну и ту же ячейку памяти (рис. 10.1).

Рис. 10.1. Использование копировщика, заданного по умолчанию

Проблемы могут возникнуть, если программа выйдет за область видимости одного из классов CAT. Как уже отмечалось при изучении указателей, назначение деструктора состоит в том, чтобы очищать память от ненужных объектов. Если деструктор исходного класса CAT очистит свои ячейки памяти, а объекты нового класса CAT все так же будут ссылаться на эти ячейки, то над программной нависнет смертельная опасность. Эта проблема проиллюстрирована на рис. 10.2.

Поделиться:
Популярные книги

Прометей: каменный век II

Рави Ивар
2. Прометей
Фантастика:
альтернативная история
7.40
рейтинг книги
Прометей: каменный век II

Законы Рода. Том 4

Flow Ascold
4. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 4

Приручитель женщин-монстров. Том 4

Дорничев Дмитрий
4. Покемоны? Какие покемоны?
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Приручитель женщин-монстров. Том 4

Санек

Седой Василий
1. Санек
Фантастика:
попаданцы
альтернативная история
4.00
рейтинг книги
Санек

Младший сын князя

Ткачев Андрей Сергеевич
1. Аналитик
Фантастика:
фэнтези
городское фэнтези
аниме
5.00
рейтинг книги
Младший сын князя

Дядя самых честных правил 7

Горбов Александр Михайлович
7. Дядя самых честных правил
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Дядя самых честных правил 7

Мимик нового Мира 5

Северный Лис
4. Мимик!
Фантастика:
юмористическая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Мимик нового Мира 5

Генерал Империи

Ланцов Михаил Алексеевич
4. Безумный Макс
Фантастика:
альтернативная история
5.62
рейтинг книги
Генерал Империи

Протокол "Наследник"

Лисина Александра
1. Гибрид
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Протокол Наследник

Последний Паладин. Том 2

Саваровский Роман
2. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 2

Виконт. Книга 3. Знамена Легиона

Юллем Евгений
3. Псевдоним `Испанец`
Фантастика:
фэнтези
попаданцы
аниме
7.00
рейтинг книги
Виконт. Книга 3. Знамена Легиона

Возвращение

Жгулёв Пётр Николаевич
5. Real-Rpg
Фантастика:
боевая фантастика
рпг
альтернативная история
6.80
рейтинг книги
Возвращение

Проклятый Лекарь. Род III

Скабер Артемий
3. Каратель
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Проклятый Лекарь. Род III

Восход. Солнцев. Книга IV

Скабер Артемий
4. Голос Бога
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Восход. Солнцев. Книга IV