Autor |
Mensaje |
Kartlan
Nivel 5
Edad: 43
Registrado: 09 Ago 2005
Mensajes: 176
Ubicación: Once
Carrera: Informática
|
|
Bueno la cuestión es simple, luego de haber programado MUCHO C++, uno se llega a pudrir de hacer getItem, setItem, +const +referencias, en fin uno se pudre de escribir las mismas lineas de código simplemente para permitir a una clase tener la capacidad de tener un atributo y cumplir con la encapsulación. Entonces encontré la idea de los mixin que se pueden usar con la herencia multiple de C++ para generar clases, es muy útil a la hora de armar frameworks o conjuntos de clases que comparten atributos.
La idea seria armar una clase con esta interfaz (esta reducida para ver lo importante).
[code ]
template <typename>
class mixinData {
protected:
T data;
public:
void setData(const T& t) { this->data = t; }
const T& getData() const { return data; }
};
[/code]
Esta interfaz mínima tiene varias falencias (resueltas en el código del final del post); otras falencias avisen.
1) Tengo que copiar y pegar todo el código y cambiar Data por el nombre del atributo que quiero por cada atributo.
2) Una vez hechas esas clases, si todas tienen el miembro privado data, el compilador puede no ser capaz de entender a que "data" se refiere cada getX o setX. (Resuelto parcialmente, pues no tiene sentido que un objeto tenga dos atributos de igual nombre, aunque si puede tener dos getData que devuelva distintos valores).
3) A veces es necesario acceso de edición a los atributos.
4) Constructores, de copia, a partir de un T.
Y ahora la joyita, un script que dado tres argumentos arma un template con la definición mínima de un mixin.
Código:
|
#Modifica el texto suministrado por stdin, cambiando:
# _DEFINE_NAME_ = arg[1]
# NAMESPACE = arg[2]
# ATTRIBUTE = arg[3]
define=$1
namespace=$2
attribute=$3
mixin_code='#ifndef _DEFINE_NAME_
#define _DEFINE_NAME_
namespace NAMESPACE {
template <typename>
class mixinATTRIBUTE {
protected:
//Nombre interno, "_mixin" es un prefijo reservado.
T _mixinATTRIBUTE;
//Metodo privado para modificar la instancia sin tener que conocer el nombre interno.
inline T& getATTRIBUTE() { return _mixinATTRIBUTE; }
public:
inline mixinATTRIBUTE() {}
inline ~mixinATTRIBUTE() {}
inline mixinATTRIBUTE(const T& t) { this->_mixinATTRIBUTE = t; }
inline mixinATTRIBUTE(const mixinATTRIBUTE& other) { this->_mixinATTRIBUTE = other._mixinATTRIBUTE; }
inline mixinATTRIBUTE& operator=(const mixinATTRIBUTE& other) {
this->_mixinATTRIBUTE = other._mixinATTRIBUTE;
return *this;
}
inline void setATTRIBUTE(const T& t) { this->_mixinATTRIBUTE = t; }
inline const T& getATTRIBUTE() const { return _mixinATTRIBUTE; }
};
}
#endif //_DEFINE_NAME_
'
echo "$mixin_code" | sed "s/ATTRIBUTE/$attribute/g" | sed "s/_DEFINE_NAME_/$define/g" | sed "s/NAMESPACE/$namespace/g"
|
|
|
|
|
|
|
|
|
|
Kartlan
Nivel 5
Edad: 43
Registrado: 09 Ago 2005
Mensajes: 176
Ubicación: Once
Carrera: Informática
|
|
Me dejo mal la primer parte del código...
Y me olvide como se usaria:
Lo que esta bueno es como limpia las demás clases, reduciendo su carga de código, y permite una lectura mas veloz de su código, una vez que uno empieza a darle bola a la parte de la herencia.
Por ejemplo una clase que tiene un atributo size, data, name, se definiria:
class mashup : public mixinSize<size_t>, public mixinData<Clase>, public mixinName<std> {};
Y solo se agregan los métodos propios del comportamiento de la clase y no los getter/setters.
Y si se define "virtualMixin" donde los métodos get y set sean virtuales se puede utilizar el polimorfismo para forzar que una clase cumpla con ciertos atributos para ser usados en un método, escapando a la locura de lo templates por ese lado.
|
|
|
|
|
|
|
|
|
EpidemiaN
Nivel 7
Edad: 35
Registrado: 28 Ago 2007
Mensajes: 402
Carrera: Informática
|
|
Interesante el script.
Si bien ahorra código en las clases grosas, también tiene la desventaja de que los proyectos van a terminar con un montonaso de clases mixin, para cada tipo de atributo que haya dando vueltas. Pero está muy buena la idea de poder aprovechar estos atributos nuevamente.
Una observación: en el constructor con parámetro conviene inicializar el atributo en una lista de inicialización =)
Si no me equivoco el script se utilizaría, para definir un mixin para el atributo "gorra", en un namespace "framework::ropa", y con un define de los seguros =P (suponiendo que el script se le dio acceso global y se llama "generate_mixin")...
Código:
|
$ generate_mixin COM_ROPA_MIXIN_GORRA__ framework::ropa Gorra >./framework/ropa/gorra.h
|
En si son bastantes cosas para pasarle al script, me parece que varias de ellas las podrían inferir a aprtir de otras, como el nombre del define, y quizá también el nombre de archivo en donde tiene que tirar el código, pero así se tiene un poco mas de control.
Bueno, eso es todo... go C++!
|
|
|
|
|
|
|
|
|
Kartlan
Nivel 5
Edad: 43
Registrado: 09 Ago 2005
Mensajes: 176
Ubicación: Once
Carrera: Informática
|
|
EpidemiaN escribió:
|
Una observación: en el constructor con parámetro conviene inicializar el atributo en una lista de inicialización =)
|
Yep!
EpidemiaN escribió:
|
Bueno, eso es todo... go C++!
|
Yep! Yep!
|
|
|
|
|
|
|
|
|
Kartlan
Nivel 5
Edad: 43
Registrado: 09 Ago 2005
Mensajes: 176
Ubicación: Once
Carrera: Informática
|
|
Ademas, "the ultimate generate_mixin" debería ser una macro para poder crear los mixin "on the fly" dentro del mismo proyecto c++.
|
|
|
|
|
|
|
|
|
joephantom
Nivel 9
Edad: 87
Registrado: 30 Jul 2007
Mensajes: 1510
Ubicación: Violando tus prejuicios
Carrera: Electrónica y Informática
|
|
EpidemiaN escribió:
|
Bueno, eso es todo... go C++!
|
Go a pegarle a los que hacen mixin de sockets
|
|
|
|
_________________ LA UNIÓN EN EL REBAÑO OBLIGA AL LEÓN A ACOSTARSE CON HAMBRE.
Es buscando lo imposible que el hombre ha siempre realizado y reconocido lo posible. Aquellos que sabiamente se han limitado a lo que les pareciera posible no han dado un solo paso adelante - Mijail Bakunin
La teoría política no es una ciencia enigmática cuya jerarquía cabalística manejan unos pocos iniciados, sino un instrumento de las masas para desatar la tremenda potencia contenida en ellas. No les llega como un conjunto de mandamientos dictados desde las alturas, sino por un proceso de su propia conciencia hacia la comprensión del mundo que han de transformar - John William Cooke
Personally I'm in favor of democracy, which means that the central institutions in the society have to be under popular control. Now, under capitalism we can't have democracy by definition. Capitalism is a system in which the central institutions of society are in principle under autocratic control. Thus, a corporation or an industry is, if we were to think of it in political terms, fascist; that is, it has tight control at the top and strict obedience has to be established at every level -- there's a little bargaining, a little give and take, but the line of authority is perfectly straightforward. Just as I'm opposed to political fascism, I'm opposed to economic fascism. I think that until major institutions of society are under the popular control of participants and communities, it's pointless to talk about democracy. - Noam Chomsky
http://joephantom.net
Verborragia de mes yeux
|
|
|
|
|
EpidemiaN
Nivel 7
Edad: 35
Registrado: 28 Ago 2007
Mensajes: 402
Carrera: Informática
|
|
joephantom escribió:
|
EpidemiaN escribió:
|
Bueno, eso es todo... go C++!
|
Go a pegarle a los que hacen mixin de sockets
|
Nahhh... no es lo mismo. Estos mixins que propone Kartlan están buenos. Es herencia "posta", pública. Nada de hacer chamullos como herencia privada con el pretexto de "ahorrar código" .
|
|
|
|
|
|
|
|
|
|
|
Ver tema siguiente
Ver tema anterior
Podés publicar nuevos temas en este foro No podés responder a temas en este foro No podés editar tus mensajes en este foro No podés borrar tus mensajes en este foro No podés votar en encuestas en este foro No Podéspostear archivos en este foro No Podés bajar archivos de este foro
|
Todas las horas son ART, ARST (GMT - 3, GMT - 2 Horas)
Protected by CBACK CrackerTracker365 Attacks blocked.
|