Aquí tienes tu programa completo. Puedes cambiar el "int" por "long" si vas a calcular números grandes, o inclusive crear tus propias clases (siempre y cuando sobrecargues los operadores necesarios). Creo que el código es claro y fácil de comprender. Deberías apreciarlo ya que me llevó una media hora escribirlo, solo para tí, y hasta empleando buenas técnicas y patrones de diseño. Solo no puse mucha atención en las validaciones como overflows y eso.
Saludos.
#include <cstddef>
#include <iostream>
using namespace std;
template<typename T, class TFunctor>
class Factorial
{
public:
Factorial() : _t() { }
Factorial(const Factorial& fact) : _t(fact._t) { }
Factorial(const T& t) : _t(t) { }
virtual ~Factorial() { }
T Calc()
{
T t;
TFunctor func;
t = func(_t);
return t;
}
T Calc(TFunctor func)
{
T t;
t = func(_t);
return t;
}
Factorial& operator= (const Factorial& fact)
{
_t = fact._t;
return *this;
}
Factorial& operator= (const T& t)
{
_t = t;
return *this;
}
private:
T _t;
};
template<typename T, class TEstrategia, class TUnit>
class CalcFactorial : public TEstrategia
{
public:
CalcFactorial() { }
virtual ~CalcFactorial() { }
T operator()(const T& tval)
{
T tres;
TEstrategia* estrategia;
estrategia = static_cast<TEstrategia*>(this);
tres = (*estrategia)(tval);
return tres;
}
};
template<typename T, T TUnit>
class EstrategiaRecursiva
{
public:
EstrategiaRecursiva() { }
virtual ~EstrategiaRecursiva() { }
T operator()(const T& tval)
{
T taux;
T tres;
taux = static_cast<T>(tval);
if (taux == _tunit)
tres = _tunit;
else
tres = taux * (*this)(taux - _tunit);
return tres;
}
private:
static const T _tunit = TUnit;
};
template<typename T, T TUnit>
class EstrategiaDirecta
{
public:
EstrategiaDirecta() { }
virtual ~EstrategiaDirecta() { }
T operator()(const T& tval)
{
T taux;
T tres;
taux = static_cast<T>(tval);
tres = _tunit;
for (T t = _tunit; t <= tval; t += _tunit)
{
tres *= t;
}
return tres;
}
private:
static const T _tunit = TUnit;
};
int main()
{
Factorial<int, EstrategiaRecursiva<int, 1> > factorial;
char cmd;
int num;
int res;
cmd = 0;
num = 0;
res = 0;
do
{
cout << "Indique el número a calcular o escriba '0' para salir." << endl;
cin >> num;
if (num > 0)
{
cout << "Indique la estrategia a utilizar: " << endl;
cout << " R - Recursiva" << endl;
cout << " D - Directa" << endl;
cin >> cmd;
if (cmd == 'R')
{
Factorial<int, EstrategiaRecursiva<int, 1> > factorial;
factorial = num;
res = factorial.Calc();
cout << "El factorial de " << num << " empleando la estrategia recursiva es " << res << endl;
}
else if (cmd == 'D')
{
Factorial<int, EstrategiaDirecta<int, 1> > factorial;
factorial = num;
res = factorial.Calc();
cout << "El factorial de " << num << " empleando la estrategia directa es " << res << endl;
}
else
{
cout << "Opción inválida." << endl;
}
cout << "
" << endl;
}
} while (num > 0);
return 0;
}