Hola, es la primera vez que posteo por estos foros, aunque algunos ya me conocereis del irc.
Interesante y original el codigo, algunos comentarios:
-Hay que tener en cuenta que RLE solo funcionara en casos muy concretos. Por otro lado, el coste de getElement es _muy_ grande, por lo que solo se hace util con arrays pequeños. Y para ganar un par de bytes, tampoco hace falta que te compliques demasiado. Y tambien deberia poder crearse y ampliarse el array poco a poco para que el ahorro de memoria sea continuado, porque de esta forma lo que tienes es mas bien un "liberador de recursos", en vez de un array. Esto implicaria usar una lista o un array que se autoincremente, estilo std::vector. La allocacion de std::vector si es rapida, ya que cada vez que debe ampliar el array reserva mas memoria que la que necesita (p.ej. duplicar el tamaño del array cuando necesite crecer es habitual), aunque claro esta que esto no seria lo mas eficiente en cuanto a uso de memoria
-He entendido antes que decis que usar un struct en vez de una clase elimina la vtable. Un struct es identico a una clase, solo cambia el nivel de acceso por defecto (public en vez de private). Lo que eliminara la vtable sera no tener ningun metodo virtual.
-Un interface tipo stl con iterators estaria bien, pero no olvides un operator[] ;). Por otro lado, aprovechando esto, podria optimizarse para un acceso secuencial a los datos mas rapido, ya que no tendrias que realizar la busqueda desde 0 en cada iteracion.
-La clase Bucket me da la impresion de que estaria mejor dentro de la clase Array. La funcion que realiza compress() opino que deberia estar disponible desde el constructor de Array y adicionalmente como un metodo en la clase. Igual para decompress(). Ademas, de esta forma meterias la administracion de memoria dentro de la clase, depender de deletes es odioso y acabas con leaks a la minima. El metodo setBuckets() opino que sobra, no le veo mucho sentido ya que se supone que nadie va a utilizar la clase Bucket directamente. Lo mismo para la getBuckets(), o bien deberia devolver un puntero a datos const, para evitar al menos que puedan modificar el array desde fuera "sin avisar" y cargarse todo, si la intencion de dar acceso al array interno es poder ampliar la funcionalidad, derivas de la clase y añades la funcionalidad que quieras. Para ello, es mejor acostumbrarse a usar private solamente en los datos que realmente son depedientes de la implementacion y no del interface, y protected para el resto de datos que no quieres que los usarios vean, pero si alguien que quiera ampliar la clase.
Juan Mellado:
-Ten en cuenta lo que ocurriria si copias un objeto Array a otro. Tendrias dos instancias apuntando al mismo puntero, a la minima todo haria -chof-. Por ello, seria necesario un operator= y un constructor de copia (aunque sean privados o aunque no tengan implementacion, para al menos evitar que se pueda copiar y le suelte un error de compilacion/linkado).
-No es necesario comprobar si el puntero vale 0 antes de hacer un delete, él mismo lo comprueba. El typedef para el struct tambien es redundante.
Algunas de las cosas que comento ya las ha implementado Juan en su modificacion.
Interesante y original el codigo, algunos comentarios:
-Hay que tener en cuenta que RLE solo funcionara en casos muy concretos. Por otro lado, el coste de getElement es _muy_ grande, por lo que solo se hace util con arrays pequeños. Y para ganar un par de bytes, tampoco hace falta que te compliques demasiado. Y tambien deberia poder crearse y ampliarse el array poco a poco para que el ahorro de memoria sea continuado, porque de esta forma lo que tienes es mas bien un "liberador de recursos", en vez de un array. Esto implicaria usar una lista o un array que se autoincremente, estilo std::vector. La allocacion de std::vector si es rapida, ya que cada vez que debe ampliar el array reserva mas memoria que la que necesita (p.ej. duplicar el tamaño del array cuando necesite crecer es habitual), aunque claro esta que esto no seria lo mas eficiente en cuanto a uso de memoria
-He entendido antes que decis que usar un struct en vez de una clase elimina la vtable. Un struct es identico a una clase, solo cambia el nivel de acceso por defecto (public en vez de private). Lo que eliminara la vtable sera no tener ningun metodo virtual.
-Un interface tipo stl con iterators estaria bien, pero no olvides un operator[] ;). Por otro lado, aprovechando esto, podria optimizarse para un acceso secuencial a los datos mas rapido, ya que no tendrias que realizar la busqueda desde 0 en cada iteracion.
-La clase Bucket me da la impresion de que estaria mejor dentro de la clase Array. La funcion que realiza compress() opino que deberia estar disponible desde el constructor de Array y adicionalmente como un metodo en la clase. Igual para decompress(). Ademas, de esta forma meterias la administracion de memoria dentro de la clase, depender de deletes es odioso y acabas con leaks a la minima. El metodo setBuckets() opino que sobra, no le veo mucho sentido ya que se supone que nadie va a utilizar la clase Bucket directamente. Lo mismo para la getBuckets(), o bien deberia devolver un puntero a datos const, para evitar al menos que puedan modificar el array desde fuera "sin avisar" y cargarse todo, si la intencion de dar acceso al array interno es poder ampliar la funcionalidad, derivas de la clase y añades la funcionalidad que quieras. Para ello, es mejor acostumbrarse a usar private solamente en los datos que realmente son depedientes de la implementacion y no del interface, y protected para el resto de datos que no quieres que los usarios vean, pero si alguien que quiera ampliar la clase.
Juan Mellado:
-Ten en cuenta lo que ocurriria si copias un objeto Array a otro. Tendrias dos instancias apuntando al mismo puntero, a la minima todo haria -chof-. Por ello, seria necesario un operator= y un constructor de copia (aunque sean privados o aunque no tengan implementacion, para al menos evitar que se pueda copiar y le suelte un error de compilacion/linkado).
-No es necesario comprobar si el puntero vale 0 antes de hacer un delete, él mismo lo comprueba. El typedef para el struct tambien es redundante.
Algunas de las cosas que comento ya las ha implementado Juan en su modificacion.