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

на главную - закладки

Жанры

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

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

Шрифт:

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

Решить проблему можно, передав в функцию указатель на константный объект класса SimpleCat. В этом случае к данному объекту могут применяться только константные

методы, не имеющие прав на изменение объекта SimpleCat. Эта идея демонстрируется в листинге 9.11.

Листинг 9.11. Передача константных указателей

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

2: // Передача константных указателей на объекты

3:

4: #include <iostream.h>

5:

6: class SimpleCat

7: {

8: public:

9: SimpleCat;

10: SimpleCat(SimpleCat&);

11: ~SimpleCat;

12:

13: int GetAge const { return itsAge; }

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

15:

16: private:

17: int itsAge;

18: };

19:

20: SimpleCat::SimpleCat

21: {

22: cout << "Simple Cat Constructor...\n";

23: itsAge = 1;

24: }

25:

26: SimpleCat::SimpleCat(SimpleCat&)

27: {

28: cout << "Simple Cat Copy Constructor...\n";

29: }

30:

31: SimpleCat::~SimpleCat

32: {

33: cout << "Simple Cat Destructor...\n";

34: }

35:

36: const SimpleCat * const FunctionTwo (const SimpleCat * const theCat);

37:

38: int main

39: {

40: cout << "Making а cat...\n";

41: SimpleCat Frisky;

42: cout << "Frisky is " ;

43: cout << Frisky.GetAge;

44: cout << " years old\n";

45: int age = 5:

46: Frisky.SetAge(age);

47: cout << "Frisky is " ;

48: cout << Frisky.GetAge;

49: cout << " years old \n";

50: cout << "Calling FunctionTwo...\n";

51: FunctionTwo(&Frisky);

52: cout << "Frisky is ";

53: cout << Frisky.GetAge;

54: cout << " years_ald\n";

55: rsturn 0;

56: }

57:

58: // functionTwo, passes a const pointer

59: const SimpleCat * const FunctionTwo (const SimpleCat * const theCat)

60: {

61: cout << "Function Two, Returning...\n";

62: cout << "Frisky is now " << theCat->GetAge;

63: cout << " years old \n";

64: // theCat->SotAge(8): const!

65: return theCat;

66: }

Результат:

Making a cat...

Simple Cat constructor...

Frisky is 1 years old

Frisky is 5 years old

Calling FunctionTwo...

FunctionTwo. Returning...

Frisky is now 5 years old

Frisky is 5 years old

Simple Cat Destructor...

Анализ:

В класс SimpleCat были добавлены две функции доступа к данным: метод GetAge (строка 13), который является константной функцией, и метод SetAge (строка 14), который не является константным. В этот класс была также добавлена переменная-член itsAge (строка 17).

Конструктор, конструктор-копировщик и деструктор по-прежнему определены для вывода на экран своих сообщений. Однако конструктор-копировщик ни разу не вызывался, поскольку объект был передан как ссылка и поэтому никаких копий объекта не создавалось. В строке 41 был создан объект со значением возраста, заданным по умолчанию. Это значение выводится на экран в строке 42.

В строке 46 переменная itsAge устанавливается с помощью метода доступа SetAge, а результат этой установки выводится на экран в строке 47. В этой программе функция FunctionOne не используется, но вызывается функция FunctionTwo, которая слегка изменена. Ее объявление занимает строку 36. На этот раз и параметр, и значение возврата объявляются как константные указатели на константные объекты.

Поскольку и параметр, и возвращаемое значение передаются как ссылки, никаких копий не создается и конструктор-копировщик не вызывается. Однако указатель в функции FunctionTwo теперь является константным, следовательно, к нему не может применяться неконстантный метод SetAge. Если обращение к методу SetAge в строке 64 не было бы закомментировано, программа не прошла бы этап компиляции.

Обратите внимание, что объект, создаваемый в функции main, не является константным и объект Frisky может вызвать метод SetAge. Адрес этого обычного объекта передается функции FunctionTwo, но, поскольку в объявлении функции FunctionTwo заявлено, что передаваемый указатель должен быть константным указателем на константный объект, с этим объектом функция обращается так, как если бы он был константным!

Ссылки в качестве альтернативы

При выполнении программы, показанной в листинге 9.11, устранена необходимость создания временных копий, что сокращает число обращений к конструктору и деструктору класса, в результате чего программа работает более эффективно. В данном примере использовался константный указатель на константный объект, что предотвращало возможность изменения объекта функцией. Однако по-прежнему имеет место некоторая громоздкость синтаксиса, свойственная передаче в функции указателей.

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

Листинг 3.12. Передача ссылок на объекты

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

2: // Передача ссылок на объекты

3:

4: #include <iostream.h>

5:

6: class SimpleCat

7: {

8: public:

9: SimpleCat;

10: SimpleCat(SimpleCat&);

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

Мама для дракончика или Жена к вылуплению

Максонова Мария
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Мама для дракончика или Жена к вылуплению

Черный дембель. Часть 2

Федин Андрей Анатольевич
2. Черный дембель
Фантастика:
попаданцы
альтернативная история
4.25
рейтинг книги
Черный дембель. Часть 2

Архил...? Книга 2

Кожевников Павел
2. Архил...?
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Архил...? Книга 2

Мастер Разума IV

Кронос Александр
4. Мастер Разума
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Мастер Разума IV

Дочь опальной герцогини

Лин Айлин
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Дочь опальной герцогини

Эволюционер из трущоб. Том 3

Панарин Антон
3. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
6.00
рейтинг книги
Эволюционер из трущоб. Том 3

Идеальный мир для Лекаря 25

Сапфир Олег
25. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 25

Барон не играет по правилам

Ренгач Евгений
1. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Барон не играет по правилам

Кодекс Крови. Книга VII

Борзых М.
7. РОС: Кодекс Крови
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга VII

Сержант. Назад в СССР. Книга 4

Гаусс Максим
4. Второй шанс
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Сержант. Назад в СССР. Книга 4

Неудержимый. Книга XIV

Боярский Андрей
14. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга XIV

Штуцер и тесак

Дроздов Анатолий Федорович
1. Штуцер и тесак
Фантастика:
боевая фантастика
альтернативная история
8.78
рейтинг книги
Штуцер и тесак

Второй кощей

Билик Дмитрий Александрович
8. Бедовый
Фантастика:
юмористическое фэнтези
городское фэнтези
мистика
5.00
рейтинг книги
Второй кощей

Бестужев. Служба Государевой Безопасности. Книга третья

Измайлов Сергей
3. Граф Бестужев
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бестужев. Служба Государевой Безопасности. Книга третья