Мета-версия здесь - это состояние. От какого состояния зависит любая функция и насколько она меняется? Затем рассмотрите, какое состояние является неявным по сравнению с явным, и сопоставьте его с проверкой и изменением.
Если у вас есть функция / метод / что-либо, что называется DoStuff (), вы не знаете извне, от чего она зависит, что ей нужно и что произойдет с общим состоянием. Если это член класса, вы также не знаете, как будет изменяться состояние этого объекта. Это плохо.
В отличие от чего-то вроде cosf (2), эта функция понимается как не изменяющая любое глобальное состояние, а любое требуемое состояние (например, справочные таблицы) скрыты от просмотра и не влияют на ваша программа в целом. Это функция, которая вычисляет значение на основе того, что вы ему даете, и возвращает это значение. Не меняет состояния.
Функции-члены класса имеют возможность усилить некоторые проблемы. Существует огромная разница между
myObject.hitpoints -= 4;
myObject.UpdateHealth();
и
myObject.TakeDamage(4);
В первом примере внешняя операция меняет некое состояние, от которого неявно зависит одна из ее функций-членов. Дело в том, что эти две строки могут быть разделены многими другими строками кода, что делает неочевидным то, что произойдет в вызове UpdateHealth, даже если вне вычитания оно совпадает с вызовом TakeDamage. Инкапсуляция изменений состояния (во втором примере) подразумевает, что особенности изменений состояния не важны для внешнего мира, и, надеюсь, это не так. В первом примере изменения состояния явно важны для внешнего мира, и это на самом деле ничем не отличается от установки некоторых глобальных переменных и вызова функции, которая использует эти глобальные переменные. Например. надеюсь, вы никогда не увидите
extern float value_to_sqrt;
value_to_sqrt = 2.0f;
sqrt(); // reads the global value_to_sqrt
extern float sqrt_value; // has the results of the sqrt.
И все же, сколько людей делают именно такие вещи в других контекстах? (Особенно учитывая, что состояние экземпляра класса является «глобальным» по отношению к этому конкретному экземпляру.)
Так что - предпочитайте давать явные инструкции вашим вызовам функций и предпочитать, чтобы они возвращали результаты напрямую, вместо того, чтобы явно устанавливать состояние перед вызовом функции, а затем проверять другое состояние после ее возврата.
Чем больше зависимостей в коде от состояний, тем сложнее будет сделать его многопоточным безопасным, но об этом уже говорилось выше. Я хочу подчеркнуть, что проблема не столько в глобальности, сколько в наглядности коллекции состояний, которая требуется для работы некоторого кода (и, следовательно, в какой степени другой код также зависит от этого состояния).