Программисты-«волшебники»
Про программистов-«волшебников», большая цитата (ниже весь текст не мой).
Хочу высказаться также по триаде «объект — указатель — ссылка».
Изначально в Си (не «++») ссылок не было. Были только объекты и указатели. Любой начинающий сталкивался с указателями, как только ему требовалось впервые изменить в теле функции значение переданного функции параметра:
void func1(int i) { i = 1; }
void func2(int* i) { *i = 1; }
Далее:
int i = 0;
func1(i); // всё ещё i==0
func2(i); // вот теперь i==1
Этот код демонстрирует то свойство Си, из-за которого он называется «высокоуровневым ассемблером». В тексте языка явно указано, что происходит на уровне ассемблера. В func1 в ячейку на стеке, отведённую под параметры функции, кладут целое значение, i — имя этой ячейки. Туда пишется «1». В func2() в ячейку кладётся указатель i, то есть адрес некоторой другой ячейки, где и лежит значение. В теле явно стоит операция разадресации (*i) — «обратимся к той другой ячейке, адрес которой лежит i». Именно в ту ячейку засовываем «1».
Спрашивается, так зачем ещё потребовались ссылки? Ответ таков. В мире существует, не исчезает и даже порой ширится класс «программистов-волшебников», то есть любителей «программирования с волшебными словами». Программисты-волшебники рассуждают так: запись i = 1; хорошая и понятная. «Присвой i единицу». Запись *i = 1; — противная, компьютерная, не для людей. «Положи „1“ в ячейку, адрес которой лежит в i». Фу.
Пусть лучше в теле func2 тоже будет написано по-человечески: i=1. Однако работает пусть всё, как раньше — func1 получает на стек значение, а func2 — указатель. И оператор присваивания, с виду теперь одинаковый, пусть работает по разному. В func1 — обычное присваивание, в func2 — с разадресацией указателя. А чтобы теперь понять, как это работает, мы введём в язык волшебный значок «&». Теперь всё просто:
void func1(int i) { i = 1; }
void func1(int &i){ i = 1; }
int i = 0;
func1(i); // волшебного значка нет, i не изменилось
func2(i); // волшебный значок! i изменилось.
Смотрите, операторы в теле функций одинаковые, а работает по-разному, и всё из-за волшебного значка! При этом можно даже не разбираться, как это работает, даже не знать про какие-то указатели. Как-то само присваивается, из-за чудесного значка.
Программисты Си долго сопротивлялись, но программисты-волшебники победили, и ссылки появились в Си++.