Сначала замечу, что нет никакого смысла переписывать код в стиле ООП, потому что класс, назовем его Calculator, не имеет состояния, не хранит данных, состоит только из функций. То есть весь код будет выглядеть как раньше, но придется приписывать в начало операций имя объекта класса типа Calculator, напр.
calculator.divide(1, 2);
. Достаточно собрать эти функции в нашем пространстве имен my_math, например,
namespace my_math {
bool operator<(const std::string& st1, const std::string& st2) {
size_t len1 = st1.length();
size_t len2 = st2.length();
if (len1 != len2) return (len1 < len2);
long int i = 0;
// ищем разряд, в котором значения отличаются
while (i < len1 && st1[i] == st2[i])
{
i++;
}
// если разряд найден, то меньше число с меньшей цифрой для положительных и с большей цифрой для отрицательных, иначе числа равны
return (i < len1) && ((st1[i] < st2[i]) );
}
bool les(int lhs, int rhs) {
return lhs <= rhs;
}
}
int main() {
using my_math::operator<; // иначе cout << my_math::operator<(s1, s2) << endl;
std::string s1 = "1", s2 = "2";
cout << (s1 < s2) << endl;
int a = 1, b = 2;
cout << (my_math::les(a, b)) << endl;
return 0;
}
Для ООП можно воспользоваться примером
https://godbolt.org/z/rEPzdKe4j. В нем определены два файла: calculator.h и calculator.cpp с объявлением класса и реализацией соответственно.
Замечу, что в реализациях бинарных операций не следует передавать string по значению, чтобы избежать лишних копирований. Если заменить тип аргумента std::string на ссылочный const std::string&, придется поправить код, чтобы он не изменял значения аргументов.