Существуют три механизма вызова параметров в функции: вызов по величине, вызов по ссылке и вызов по постоянной ссылке. Чтобы понять, когда какой механизм применять, посмотрим на следующий пример. void f(int, int) main(){ int a,b; a=5; b=6; f(a,b); cout << a << b << endl; }
В .срр файле укажем, как функция f работает: void f(int x,int y) { x=x+1; y=y+1; }
Таким образом, параметры в функции f я вызвала по величине. Что же наша main функция выведет на экран? Рассмотрим, что происходит когда мы вызываем функию f. Как только мы объявили а и b, в стеке (специальная память для местных переменных) выделилось достаточное количество места для типа integer(2-4 байта на каждую) и каждой переменной присвоен свой собственный адрес в памяти. x и y - местные переменные для функции f, при их появлении стек опять выделяет им место и присваивает адрес. После кода :x=x+1; y=y+1;
Нашим переменным соответсвенно присваиваются значения 6 и 7. Когда функция f выполнила своё назначение по правилам С++ все местные переменные стираются из памяти компьютера, то есть при выполнении нашей программы, когда дело доходит до вывода результата на экран ...... Какими будут значения a и b ? Если вы поняли мои объяснения, то ваш ответ должен быть 5 и 6. Соответвенно, функция f не изменила первоначальные величины. Что же сделать, чтобы после выполнения расчётов функции результат не был бы утерян? Надо всего лишь вызвать наши параметры не по величине, а по ссылке. Изменения в коде минимальные: В .срр файле: void f(int &x,int &y)
Когда мы ставим & перед названием переменной, мы указываем компилятору, что теперь наши переменные мы вызываем по ссылке. Теперь в стеке при появлении y и х не выделяется особое место, им присваивается тот же адрес, что у а и b. Таким образом, мы не теряем результаты подсчётов. После выполнения функции f ничего из памяти не стирается, так как она не заняла ни одного байта у стека. Разобрав первый два механизма, можно прийти к выводу. Если мы хотим, чтобы функция не изменила наши параметры, вызываем их по величине. Если, на против, мы хотим чтобы им было присвоено новое значение, используем вызов по ссылке. Остаётся последний вопрос, когда же применять вызов по постоянной ссылке! Этот механизм имеет тот же эффект что и вызов по величине, а так же экономит память, как и вызов по ссылке. Применять его лучше, когда вы имеете дело с большими параметрами. Например, при перегрузке операторов в классе. friend ostream & operator<<(ostream & out, const int &VALUE);
В данном случае, мы хотим получить гарантию, что данная функция выполнит свою роль и не сделать нежелательных изменений параметров. Особенности кода при вызове по постоянной ссылке: ставим const перед типом переменной и знак "&" перед именем. |