1. El diagrama en Rose que acompaña el código es incompleto.
2. Una constructora como la siguiente
Number(const Number& r, const Number& i);Permite que se creen números complejos con parte entera compleja...
Operaciones como
virtual Number restaInt (Number& n); virtual Number restaLong (Number& n); virtual Number restaLargeint (Number& n); virtual Number restaComplex (Number& n);No tienen porque hacer parte de la interfaz pública de la clase handle. Basta con que las subclases las definan y que sea protegida. Además, el tipo del parámetro ya es conoce: en restaInt es Int, en restalong es Long y así sucesivamente...
3. La siguiente operación puede fallar en caso de overflow del
tipo int.
Number Int::sumaInt(Number& n)
{
Number retval;
int temp = valor;
Int *i2 = (Int*) &n;
temp += i2->valor;
Int *i1 = new Int(temp);
retval.Redefine(i1);
return retval;
}
Es necesario comprobar que la operación no se salga del rango permitido.
4. La siguiente función de calcular el tamaño de un LargeInt no considera el tamano que se gasta el almacenamiento del mismo número
const long Largeint::Tamano()
{
long t=0;
t = sizeof(*this);
t += valor.Tamano();
return t;
}
Debe contarse el tamaño de la cadena, por ejemplo t+= valor.Lenght();
(Suponiendo el valor un objeto String con el método nombrado para
calcular el tamaño).
5. No es necesario modelar el tipo del objeto como otro atributo. Pude ser dado por un método redefinido, si se requiere para la visualización. (Por ejemplo un método const char* getTipo( ) redefinido en cada subclase)
6. El constructor por copia, como en el idiom Reference Counting, debe
referenciar la representación, no crear una nueva... Por ejemplo:
NumberC::NumberC ( const NumberC& n )
{
switch ( n.tipo )
{
INT:
rep = new Int ( n.valueI() );
tipo = INT;
break;
...
}
Debería hacer algo como lo siguiente
NumberC::NumberC ( const NumberC& n )
{
rep = n.rep;
rep->count++;
}
7. Las clases particulares son responsables de sus operaciones de suma,
resta, división y multiplicación con los otros tipos. Una
definición como la siguiente es incompleta y deja demasiada responsabilidad
al handle
class Int : public Simple
{
public:
Int();
Int ( Int& n );
Int& operator= ( Int& n );
~Int();
Int ( const int& n);
int& valueI();
private:
int rep;
};
8. El siguiente tipo de operaciones no son válidas dentro de un
esquema de un virtual constructor. El objetivo de este idiom es no tratar
mediante switch llos tipos de datos sino mediante el mecanismo de sobrecarga
de operaciones y métodos
Number Integer::operator+(const Number &Num2) {
switch (Num2.tipo) {
case INTEGER:
return new Number(Valor+((Integer *)Num2.rep)->Valor);
case LONG:
return new Number(Valor+((Long *)Num2.rep)->Valor);|
case FLOAT:
return new Number(Valor+((Float *)Num2.rep)->Valor);
case DOUBLE:
return new Number(Valor+((Double *)Num2.rep)->Valor);
default:
assert(false && "Operacion Invalida");
}
}
Algunas de las características encontradas
en el código son:
1. Hacer un Makefile para compilar un prgrama con varios fuentes.
Los errores encontrados por cuenta son:
| 01 | 1, No esta terminado |
| 02 | - |
| 03 | - |
| 04 | - |
| 05 | 1, 2, 3, 4, 5, no parece funcionar el tamano de los objetos, No hay reducción de tipos |
| 06 | - |
| 07 | - |
| 08 | - |
| 09 | 1, 5,7, No están implementadas las operaciones, No compila, Constructoras confusas (Complex) |
| 10 | (Mismo grupo 9?) |
| 11 | - |
| 12 | (mismo grupo 5?) |
| 13 | No hay permisos !! |
| 14 | No hay permisos !! |
| 15 | - |
| 16 | - |
| 17 | - |
| 18 | 1, 8, No es claro dentro de qué contexto se requiere un constructor del tipo Number(Number *num), No corre el main pedido. |
| 19 | - |
| 20 | - |
| 21 | 1, No se nota la necesidad de operaciones como int_equality en la parte pública de Number, corre con un main distinto al pedido. No hay conteo de referencias |