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

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

Жанры

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

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

Шрифт:

Следует также отметить, что при объявлении соответствующих переменных можно использовать разные стили размещения операторов ссылки (&) и косвенного обращения (*). Вполне законной будет любая из следующих записей:

1: CAT& rFrisky;

2: CAT & rFrisky;

3: CAT &rFrisky;

Примечание:Символы пробелов в программах на языке C++ полностью игнорируются, поэтому везде, де вы видите пробел, можно ставить несколько пробелов, символов табуляции или символов разрывов строк. Оставив в покое вопросы свободного волеизъявления,

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

Однако есть и контраргумент. CAT — это тип. Оператор & является частью объявления, которое включает имя переменной и амперсант. Но следует отметить, что слияние вместе символа & и имени типа CAT может привести к возникновению следующей ошибки:

CAT& rFrisky, rBoots;

Поверхностный анализ этой строки может натолкнуть на мысль, что как переменная rFrisky, так и переменная rBoots являются ссылками на объекты класса CAT. Однако это не так. На самом деле это объявление означает, что rFrisky является ссылкой на объект класса CAT, а rBoots (несмотря на свое имя с характерным префиксом) — не ссылка, а обыкновенная переменная типа CAT. Поэтому последнее объявление следует переписать по-другому:

CAT &rFrisky, rBoots;

В ответ на это возражение стоит порекомендовать, чтобы объявления ссылок и обычных переменных никогда не смешивались в одной строке. Вот правильный вариант той же записи:

CAT& rFrisky; CAT Boots;

Примечание:Наконец, многие программисты не обращают внимания на приведенные аргументы и, считая, что истина находится посередине, выбирают средний вариант (средний, кстати, в двух смыслах), который иллюстрируется случаем 2:

2: CAT & rFrisky;

Безусловно, все сказанное до сих пор об операторе ссылки (&) относится в равной степени и к оператору косвенного обращения (<<). Выберите стиль, который вам подходит, и придерживайтесь его на протяжении всей программы, ведь ясность текста программы — одна из основных составляющих успеха.

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

1. Размещать амперсант или звездочку посередине, окаймляя этот символ пробелами с двух сторон.

2. Никогда не объявлять ссылки, указатели и переменные в одной и той же строке программы.

Не возвращайте ссылку на объект, который находиться вне области видимости!

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

объекта. При передаче ссылки в функцию или из нее не забудьте задать себе вопрос: "Что представляет собой объект, псевдонимом которого я манипулирую, и будет ли он существовать в момент его использования?"

В листинге 9.13 показан пример возможной ошибки, когда функция возвращает ссылку на объект, которого уже не существует.

Листинг 9.13. Возвращение ссылки на несуществующий объект

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

2: // Возвращение ссылки на объект,

3: // которого больше не существует

4:

5: #include <iostream.h>

6:

7: class SimpleCat

8: {

9: public:

10: SimpleCat (int age, int weight);

11: ~SimpleCat { }

12: int GetAge < return itsAge; }

13: int GetWeight { return itsWeight; }

14: private:

15: int itsAge;

16: int itsWeight;

17: };

18:

19: SimpleCat::SimpleCat(int age, int weight)

20: {

21: itsAge = age;

22: itsWeight = weight;

23: }

24:

25: SimpleCat &TheFunction;

26:

27: int main

28: {

29: SimpleCat &rCat = TheFunction;

30: int age = rCat.GetAge;

31: cout << "rCat " << age << " years old!\n"

32: return 0;

33: }

34:

35: SimpleCat &TheFunction

36: {

37: SimpleCat Frisky(5,9);

38: return Frisky;

39: }

Результат:

Compile error: Attempting to return a reference to a local object! (Ошибка компиляции: попытка возвратить ссылку на локальный объект!)

Предупреждение:Эта программа не компилируется на компиляторе фирмы Borland, но для нее подходят компиляторы компании Microsoft. Однако профессиональный программист никогда не станет полагаться на уступки компилятора.

Анализ: В строках 7—17 объявляется класс SimpleCat. В строке 29 инициализируется ссылка на объект класса SimpleCat с использованием результатов вызова функции TheFunction, объявленной в строке25. Согласно объявлению эта функция возвращает ссылку на объект класса SimpleCat.

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

По возвращении функции TheFunction локальный объект Frisky будет разрушен (надеюсь, безболезненно для самого объекта). Ссылка же, возвращаемая этой функцией, останется псевдонимом для несуществующего объекта, а это явная ошибка.

Возвращение ссылки на в области динамического обмена

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

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

Её (мой) ребенок

Рам Янка
Любовные романы:
современные любовные романы
6.91
рейтинг книги
Её (мой) ребенок

Лорд Системы

Токсик Саша
1. Лорд Системы
Фантастика:
фэнтези
попаданцы
рпг
4.00
рейтинг книги
Лорд Системы

Сыночек в награду. Подари мне любовь

Лесневская Вероника
1. Суровые отцы
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Сыночек в награду. Подари мне любовь

Затерянные земли или Великий Поход

Михайлов Дем Алексеевич
8. Господство клана Неспящих
Фантастика:
фэнтези
рпг
7.89
рейтинг книги
Затерянные земли или Великий Поход

История "не"мощной графини

Зимина Юлия
1. Истории неунывающих попаданок
Фантастика:
попаданцы
фэнтези
5.00
рейтинг книги
История немощной графини

Последнее желание

Сапковский Анджей
1. Ведьмак
Фантастика:
фэнтези
9.43
рейтинг книги
Последнее желание

Совок

Агарев Вадим
1. Совок
Фантастика:
фэнтези
детективная фантастика
попаданцы
8.13
рейтинг книги
Совок

Магнатъ

Кулаков Алексей Иванович
4. Александр Агренев
Приключения:
исторические приключения
8.83
рейтинг книги
Магнатъ

Жена по ошибке

Ардова Алиса
Любовные романы:
любовно-фантастические романы
7.71
рейтинг книги
Жена по ошибке

Николай I Освободитель. Книга 2

Савинков Андрей Николаевич
2. Николай I
Фантастика:
героическая фантастика
альтернативная история
5.00
рейтинг книги
Николай I Освободитель. Книга 2

Провалившийся в прошлое

Абердин Александр М.
1. Прогрессор каменного века
Приключения:
исторические приключения
7.42
рейтинг книги
Провалившийся в прошлое

Офицер

Земляной Андрей Борисович
1. Офицер
Фантастика:
боевая фантастика
7.21
рейтинг книги
Офицер

Адвокат вольного города 3

Кулабухов Тимофей
3. Адвокат
Фантастика:
городское фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Адвокат вольного города 3

Убивать чтобы жить 7

Бор Жорж
7. УЧЖ
Фантастика:
героическая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 7