Сравнение ссылок и указателей в C++
Ссылки — это концепция в C++. Новички часто путают ссылки с указателями.
В следующей программе n — это ссылка на m, а m — это референт.
int m; int &n = m;
n эквивалентно псевдониму (прозвищу) для m. Любая операция над n — это операция над m.
Таким образом, n не является ни копией m, ни указателем на m; фактически n — это сам m.
Правила для ссылок:
- (1) Ссылка должна быть инициализирована при создании (указатель может быть инициализирован в любое время).
- (2) Ссылки NULL не существует; ссылка должна быть связана с допустимой единицей хранения (указатель может быть NULL).
- (3) После инициализации ссылки связь ссылки нельзя изменить (указатель может в любой момент изменить объект, на который он указывает).
В следующем примере программы k инициализируется как ссылка на i.
Инструкция k = j не изменяет k так, чтобы k стал ссылкой на j; она только изменяет значение k на 6.
Поскольку k — ссылка на i, значение i также становится 6.
int i = 5; int j = 6; int &k = i; k = j; // k 和 i 的值都变成了 6;
Основное назначение ссылок — передавать параметры функций и возвращаемые значения.
В C++ есть три способа передачи параметров функций и возвращаемых значений: передача по значению, передача по указателю и передача по ссылке.
Ниже приведён пример программы для «передачи по значению».
Поскольку x внутри тела функции Func1 — это копия внешней переменной n, изменение значения x не влияет на n, поэтому значение n остаётся 0.
void Func1(int x)
{
x = x + 10;
}
...
int n = 0;
Func1(n);
cout << "n = " << n << endl; // n = 0
Ниже приведён пример программы для «передачи по указателю».
Поскольку x внутри тела функции Func2 — указатель на внешнюю переменную n, изменение содержимого, на которое указывает указатель, приведёт к изменению значения n, поэтому значение n становится 10.
void Func2(int *x)
{
(* x) = (* x) + 10;
}
...
int n = 0;
Func2(&n);
cout << "n = " << n << endl; // n = 10
Ниже приведён пример программы для «передачи по ссылке».
Поскольку x внутри тела функции Func3 — ссылка на внешнюю переменную n, x и n — одно и то же. Изменение x эквивалентно изменению n, поэтому значение n становится 10.
void Func3(int &x)
{
x = x + 10;
}
...
int n = 0;
Func3(n);
cout << "n = " << n << endl; // n = 10
Сравнив три приведённых выше примера программ, вы увидите, что «передача по ссылке» ведёт себя как «передача по указателю», но записывается как «передача по значению».
На самом деле всё, что могут делать «ссылки», могут делать и «указатели». Почему же нам всё ещё нужны «ссылки»?
Ответ: «используйте подходящий инструмент для подходящей задачи».
Указатели могут манипулировать чем угодно в памяти без ограничений. Хотя указатели мощны, они очень опасны.
Если вам действительно нужно просто позаимствовать "псевдоним" для объекта, то используйте "ссылку" вместо "указателя", чтобы избежать ошибок.