Я - все еще новичок C++. Просто прибыл, чтобы считать, что статическая функция членства класса не является конкретным объектом - существует единственная копия функций членства для всех объектов.
Теперь два вопроса возникают в моем уме:
Каково различие между обычной функцией и статической функцией "с точки зрения выделения памяти только"?
Что, если функция членства содержит некоторые локальные переменные? В этом случае функция "должна" иметь отдельную копию той переменной - характерный для объекта, вызывающего функцию... Как эта проблема решена в C++?
Спасибо!
В чем разница между обычная функция и статическая функция "с точки зрения памяти только выделение "?
Ничего. Статическая функция похожа на глобальную функцию, за исключением области видимости.
Даже для нестатических функций-членов дополнительная память не требуется. Функция-член int C :: f (int arg1, int arg2)
- это просто синтаксический сахар для чего-то вроде int C__f (C * this, int arg1, int arg2)
.
Что, если функция-член содержит какие-то локальные переменные? В этом случае функция "должна" иметь отдельный копия этой переменной - специфическая для объект, вызывающий функцию ...
Есть копия локальных переменных для каждого вызова функции (если они не статические
). Вот почему в C ++ возможна рекурсия.
Как эта проблема решена в C ++?
Вызов функций основан на «кадрах стека». Кадр стека состоит из:
this
, если применимо). статические
локальные переменные в функции. Каждый раз, когда вызывается функция, создается кадр стека. Когда функция есть, фрейм стека уничтожается. Если функция вызывается рекурсивно, каждый уровень рекурсии получает свой собственный кадр стека. Например, если у вас есть
int factorial(int n) {
if (n <= 1)
return 1;
else
return factorial(n - 1) * n;
}
, то при вызове factorial (3)
фрейм стека создается следующим образом:
------------------------ stack pointer (SP)
n = 3
RA = <in main()>
Когда выполняется рекурсивный вызов factorial (2)
, в верхнюю часть стека добавляется дополнительный кадр
------------------------ SP
n = 2
RA = <in factorial()>
------------------------
n = 3
RA = <in main()>
Выполняется другой рекурсивный вызов factorial (1)
.
------------------------ SP
n = 1
RA = <in factorial()>
------------------------
n = 2
RA = <in factorial()>
------------------------
n = 3
RA = <in main()>
Это базовый случай для рекурсии, и возвращаемое значение 1 сохраняется в регистре. После завершения вызова функции верхний фрейм стека уничтожается, и выполнение продолжается с сохраненным адресом возврата.
------------------------ SP
n = 2
RA = <in factorial()>
------------------------
n = 3
RA = <in main()>
Теперь вызов factorial (2)
может вычислить его возвращаемое значение (2), а другой кадр стека может быть уничтожен:
------------------------ SP
n = 3
RA = <in main()>
Наконец, мы можем вычислить результат исходного вызова функции (6), а также уничтожить этот фрейм стека.
Я бы счел очень маловероятным, чтобы была разница
Похоже, вам стоит немного почитать о разнице между кучей и выделением стека. Это дает хорошее представление о том, как работает память на низком, но все же высоком уровне. Извините, что не могу быть более полезным сейчас.
edit: too slow :)
На самом деле нет такой большой разницы. Оба хранятся в памяти только один раз, когда вызывается нестатический метод, указатель на текущий объект (указатель this) помещается в стек (или сохраняется в ECX в зависимости от вашего компилятора) в дополнение ко всем функциям параметры. Статической функции не нужен экземпляр класса, поэтому она просто вызывается как обычная функция C.
То же, что и в C, со стеком вызовов.