Назад | Начало урока | Вперед
Содержание

Глава 9

Вверх

На что можно ссылаться?

Ссылаться можно на любой объект, включая определенный пользователем.
Обратите внимание что ссылка создается на объект класса, а не на класс.

int &rIntRef=int //неправильно!

Ссылку rIntRef необходимо инициализировать, использую конкретную целочисленную переменную, так

int howBig=200;
int &rIntRef=howBig;

howBig-это конкретный объект класса int.

Точно так же нельзя инициализировать ссылку на класс CAT

CAT &rCatRef=CAT;//неверно

Надо использовать конкретный объект

CAT Frisky; CAT &rCatRef=frisky;

Ссылки на объекты используются точно так же как и сами объекты. Доступ к данным-членам и функциям осуществляется с помощью обычного оператора доступа к членам класса(.) Подобно встроенным типам ссылка действует как псевдоним объекта.
Посмотрите программу:

Ссылки на объекты класса // Listing 9.4 // References to class objects


#include <iostream>

class SimpleCat {

public: SimpleCat (int age, int weight);
~SimpleCat() {
}
int GetAge() {
return itsAge;
}
int GetWeight() {
return itsWeight;
} private:
int itsAge;
int itsWeight;
};

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

itsAge = age;
itsWeight = weight;
}

int main() {

SimpleCat Frisky(5,8);
SimpleCat & rCat = Frisky;

std::cout << "Frisky is: ";
std::cout << Frisky.GetAge() << " years old. \n";
std::cout << "And Frisky weighs: ";
std::cout << rCat.GetWeight() << " pounds. \n";
return 0;

}

Результат:

Frisky is:5 years old And Frisky weight 8 pounds

Анализ:

Сначала в главной программе Frisky объявлен как объект класса SimpleCat. Далее объявлена ссылка rCat на объект класса SimpleCat, которая инициализируется объектом Frisky .

SimpleCat Frisky(5,8); SimpleCat & rCat = Frisky;

Здесь еще интересно как при объявлении объекта инициализируются его закрытые переменные -возраст и вес. Смотри цифры в скобках (5,8). Это происходит автоматически благодаря конструктору.

Далее вызываются функции доступа к членам класса. Сначала напрямую через объект класса и затем к этим же функциям обращаются через ссылку.
std::cout << "Frisky is: ";
std::cout << Frisky.GetAge() << " years old. \n";
std::cout << "And Frisky weighs: ";
std::cout << rCat.GetWeight() << " pounds. \n";

Обратите внимание что результаты идентичны. Потому что ссылка-это всего лишь псевдоним реального объекта!


Объявляя ссылку, сначала указывают тип данных, а затем оператор ссылки (&) и ее имя. Инициализировать ссылки необходимо при объявлении.

int hisAge;
int &rAge=hisAge;

CAT boots;
CAT &rCatRef=boots;


Вверх

Нулевые указатели и нулевые ссылки

Когда указатели не инициализированы или когда они освобождены, им следует присваивать нулевое значение (0). Ссылок это не касается. Фактически ссылка не может быть нулевой, программа содержащая ссылку на нулевой объект, считается некорректной. Во время работы такой программы может случиться все что угодно -например выбросит все файлы с вашего жеского диска. Компиляторы могут поддерживать нулевой объект ничего не сообщая по этому поводу и это опасно!

Вверх

Передача функции аргументов по ссылке

Функции имеют два ограничения: аргументы передаются как значения и теряют связь с исходными данными и возвращать функция может только одно значение.

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


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

Посмотрим программу: В этой программе передача параметров по значению

//Listing 9.5 Demonstrates passing by value


#include <iostream>

using namespace std;
void swap(int x, int y);

int main() {

int x = 5, y = 10;

cout << "Main. Before swap, x: " << x << " y: " << y << "\n";
swap(x,y);
cout << "Main. After swap, x: " << x << " y: " << y << "\n";
return 0;

}

void swap (int x, int y) {

int temp;

cout << "Swap. Before swap, x: " << x << " y: " << y << "\n";

temp = x;
x = y;
y = temp;

cout << "Swap. After swap, x: " << x << " y: " << y << "\n";

}


Результат:

Main Before swap x:5 y:10 Swap. Before swap x:5 y:10
Swap. After swap, x:10 y:5
Main After swap, x:5 y:10

Как видим при выходе из функции swap() значения переменных не изменились. Это происходит потому что значения были переданы по значению

Есть два способа решения этой проблемы: можно сделать параметры функции swap() указателями на исходные значения или передать функции ссылки на их исходные значения.


Назад | Начало урока | Вверх | Вперед
Содержание

Hosted by uCoz