Pongo la última versión de BGL, aunque tenga pocos cambios, así puedo poner los fuentes de "Escape del Volcán".
Hay pocos cambios respecto a la versión anterior. Solo he añadido un módulo nuevo: BGL Util
En este módulo pondré cosillas que no encajan en otro y que son tan pequeñas que no merecen uno independiente.
De momento incluye:
- Clase Vector simple: Para evitar usar STL.
- Clase Parser: Sencillito por ahora.
- Clase Config: Para leer ficheros de configuración.
Este nuevo módulo vino por culpa de Config, ya que no me gustaba nada de lo que había visto para leer ficheros INI o similares.
La utilizo en un ejemplo de BGL y en Escape. El fichero de Escape es algo así:
/*
Fichero de configuración de "Escape del Volcán"
*/
fullscreen = no
player1 {
control {
left = 75
right = 77
up = 57
}
}
Es, para mí, bastante más versátil que los típicos INI de Windows o Properties de Java. Aunque supongo que tendrá algún fallo y seguramente le falten cosas, creo que permite utilizar ficheros con una cierta complejidad ya que permite anidar secciones y el acceso a las variables es muy sencillo (cfg.getIntValue( "player1.control.left" )).
La clase permite tanto extraer variables como secciones completas (similar a XML pero mas simple).
Buneo, bueno, que me enrollo. Los enlaces:
BGL comleta:
bgl-full-snapshot-2005-03-03.zipBGL de desarrollo (cabeceras, librerías y documentación):
bgl-dev-snapshot-2005-03-03.zipLa documentación, donde antes:
DocumentaciónEscape del Volcán completo:
escape-src.zip
Una curiosidad, la función bgl::Painter::drawImage ¿La has hecho tú o utilizas internamente algúna función de windows?
un saludo
Cita de: fieroUna curiosidad, la función bgl::Painter::drawImage ¿La has hecho tú o utilizas internamente algúna función de windows?
Es mía, está en los fuentes. Eso sí, aun está en C ^_^, espero pasarla pronto a ensamblador.
BGL Video tiene funciones de dibujo, o sea, mueve memoria de un sitio a otro. No tiene sentido que utilice nada específico del SO (de eso se encarga la clase VideoDriver).
Ses, si eso solo mueve memoria de un sitio a otro... quizas te interesen las rutinas de copia que tengo por ahi superoptimizadas, basicamente son las de AMD y otras modificadas para que funcionen bien en los P3 y PM.
Si las quieres, te las envio, yo las utilizo con mi lib y dependiendo del caso...sobre todo cuando es render por software..se nota bastante :)
un saludo
Supongo que más adelante, cuando soporte imágenes no indexadas sin transparencia o comprimidas, sí podría ser útil.
Ahora mismo no servirían de mucho :(. Las imágenes que pinto son indexadas; hay pocos "memcpy". Aunque no fueran indexadas, habría que comprobar cada punto para ver si se dibuja o no (key color).
Pero gracias, me lo apunto para cuando se pueda utilizar ;)
Una preguntita sés... ¿por qué evitas usar STL?
Cita de: gdlUna preguntita sés... ¿por qué evitas usar STL?
Porque quiero que BGL sea independiente de otras librerías. Utilizar un vector no lo veo motivo para obligar a alguien a utilizar STL.
No quiero empezar con dependencias de tropecientas librerías de terceros como otras librerías. Ya me ha pasado más de una vez ver algo que parecía majo... hasta que descubres que tiene 5 dependencias y lo que parecía una librería de unas Kb termina ocupando varias Mb... ejem.
Si quieres evitar librerías de "terceros" deberías codearte tu propia libc, tu propio SO, tus propios drivers de dispositivos... te recuerdo que STL es STANDARD template library y que por defecto viene en todos los compiladores de c++. Es posible que ciertas características como hash_map u otras no vengan en todas las implementaciones pero std::vector es tan estandard como printf, std::cout o cualquiera de las que seguramente uses en tu librería.
Todo el párrafo anterior viene a cuento de que si usas std::vector tendrás bastantes ventajas entre las que destaco la mayor rapidez de programación y de ejecución, el poder usar todos los algoritmos disponibles en la STL sin necesidad de cambios... por no citar la ventaja de poder cambiar un std::vector por un std::queue o un std::list sin necesidad de andar cambiando absolutamente nada (solo un typedef).
En conclusión, no veo nada más que ventajas usando STL. La verdad creo que la pega del tamaño es un sin sentido teniendo en cuenta que después hay imágenes y sonidos de un tamaño más que considerable que, seguramente es mucho más de lo que añadirá STL a tu ejecutable final.
un saludo
Cita de: ethernetSi quieres evitar librerías de "terceros" deberías codearte tu propia libc, tu propio SO, tus propios drivers de dispositivos...
Tampoco exageres :P Simplemente intento evitar la mayor parte de dependencias de otras librerías.
La clase Vector es un ejemplo. Tengo una clase Vector simple ya hecha, ¿para qué utilizar STL si esta clase me da lo que quiero? ¿Dónde está lo malo de quitarme una dependencia a cambio de nada?
Además hay que tener en cuenta que utilizar una simple función (no digo que este sea el caso) puede hacer que se enlacen bastantes más cosas que esa sencilla función. Cuando necesite varias clases de la STL pues... será otra historia.
Cita de: sésCuando necesite varias clases de la STL pues... será otra historia.
Precisamente por eso puede ser el momento de usar STL
Quizás dentro de 3 meses cuando necesites algún contenedor más te arrepientas y tengas que volver atrás el desarrollo. Y eso en el caso de que todo vaya bien porque quien no se ha estado horas buscando un error que finalmente lo has encontrado en el código que supuestamente estaba bien.
Desde mi punto de vista el uso de STL da muchísimo más de lo que quita. Es más, yo diría que ahora mismo es lo mínimo que puede ofrecerte un lenguaje de programación.
Acabo de hacer una prueba. He compilado un programa que tenía de pruebas para mis clases Vector y String:
Usando bgl::Vector y bgl::String -> 49217 bytes
Usando stl::vector y stl::string -> 120059 bytes
70842 bytes de diferencia.
De momento como que me quedo con mis clases ^_^
Para mí es el mismo caso que tengo entre utilizar SDL o hacer BGL. SDL me da muchas cosas, pero no quiero cargar con todo para 2 que utilizo. Así que hago BGL. Lo mismo con STL.
Que algo tenga 1000 cosas y no tenga fallos me parece estupendo, pero si solo necesito el 1%, me lo hago yo mismo y listo.
Por muy estándar que sea, si hace crecer mi código con cosas que no necesito, me sobra. Hacer las cosas de otra forma sería ir en contra de mis principios, y BGL no sería como yo quiero.
Terminaría convirtiendose en un mastodonte y al final tendría un pegote sin las ventajas que quiero que tenga. Entre ellas está el que sea ligera.
ok, supongo entonces que sintetizarás las imágenes y el sonido para que no te ocupen más de los 70kb que te añade STL.
Por otra parte debes saber que el código el código "extra" que te añade STL es muy ortogonal con lo cual añadie nuevas funcionalidades apenas hará variar tu tamaño de ejcutable. Me resulta curioso que a estas alturas os preocupeis por 70kb más de ejecutable, si quieres reducirlo usa upx (upx.sf.net).
Ahora me gustaría que hicieras un benchmark de rapidez de ejecución, eso sí, especificando como has usado STL.
saludos
Pobre sés, un poco más y le pegas (twist) Es broma ;)
La verdad es que STL tiene sus ventajas, como bien dices.
El contrapunto es el peso que añade al ejecutable y al working set de la aplicación (modo pijo de decir que usa mucha memoria de acceso frecuente y la fragmenta, y si, se que luego crece homogeneamente, es solo el pico inicial y tal).
El tema es que para determinados casos, el tamaño si importa. Y aunque no importase, los puristas lo queremos todo light y con 0% grasas XD
Y ya hablando de importancia de tamaños, me marco un offtopic por la face:
Interesado como estoy en el mundo indie, donde la descarga del juego completo (con graficos y sonido) debe ser de unos 10MB máximo (15MB en casos muy muy muy excepcionales) y funcionar en PCs de 64MB-128MB, me hice unas pruebecillas de carga de distintos motores 3D (los valores son medias a ojo, no es una prueba estricta ni quiere ser una comparativa):
Ogre: 10MB en disco 40-50MB de RAM
Irrlicht: 1.5MB disco 25-35MB de RAM
Blitz3D: 1.5MB disco 8-10MB de RAM
Nebula Device 1: 1.5MB disco 4-9MB de RAM
Me ha sorprendido ver el consumo de memoria de Irrlicht. No es tan compacto como parece al ver el tamaño en disco.
el blitz3d ponlo en cabeza con 10000megas por que las pruebas que hice yo hace tiempo con simplemente leer una animacion de md2 consume 60 megas :D
bueno yo puedo decir y sentirme orgullo que yo no uso stl tampoco ya que usa templates (no os hecheis las manos a la cabeza jeje), los templates no me gustan por que por cada tipo que definas el compilador genera una clase entera con ese nuevo tipo y el exe y la memoria en ejecuacion aumentan, mientras que si usas conversiones de void solo generas una clase en disco y en memoria, ademas las conversiones entre puntero son "ficticias" ya que son para que el compilador entienda el tipo de dato y no implica perdida de velocidad en ningun caso y si no os gusta el void hacer una clase base y derivar de ella :P
saludos
No entiendo que tiene de raro no querer usar STL (o cualquier otra librería o función).
Si no me gusta, sea por la razón que sea, cómo funciona una librería o función concreta, ¿por qué no rehacerla a mi gusto?
Para eso aprendí a programar, para hacer lo que necesite como lo necesite. Si algo no sé hacerlo, me aguanto con lo que tenga a mano, pero mientras tanto...
Creo que las librerías y las funciones están ahí para el que le sirvan y quiera utilizarlas. No veo la razón de usar algo por el simple hecho de que esté ahí.
Si la gente se limitase a utilizar lo que ya está hecho, solo por no reinventar la rueda, probablemente estaríamos utilizado la librería BGI de Borland... o algo peor :P
La programación no es si no reinventar constantemente la rueda. A veces, curiosamente, se inventan ruedas mejores ;)
Yo ni siquiera estoy reinventando la rueda, simplemente hago mi popia rueda.
-= EDIT =-
Se me olvidaba decir que probablemente utilice el método que dice zupervaca. Es lo que hacía antes y me parece lo mejor. Utilicé mi "template" Vector porque la tenía hecha y quería probarla. Seguramente cambie mi "template" Vector por una "clase" Vector (solo tengo que convertir lo que tengo en C a una clase C++ y listo).
Si os fijáis, ni siquiera incluí Vector en la documentación ^_^
he bajado el codigo fuente para hecharle un vistazo pero me da error el archivo comprimido :(
Es cierto, estaba mal. He vuelto a subirlo.
Citar
bueno yo puedo decir y sentirme orgullo que yo no uso stl tampoco ya que usa templates (no os hecheis las manos a la cabeza jeje), los templates no me gustan por que por cada tipo que definas el compilador genera una clase entera con ese nuevo tipo y el exe y la memoria en ejecuacion aumentan, mientras que si usas conversiones de void solo generas una clase en disco y en memoria, ademas las conversiones entre puntero son "ficticias" ya que son para que el compilador entienda el tipo de dato y no implica perdida de velocidad en ningun caso y si no os gusta el void hacer una clase base y derivar de ella
Me hace bastante gracia que nos preocupemos de eso teniendo después:
1.- imágenes, sonidos y modelos que ocupan 100 veces (me quedo corto) más que el código
2.- usando otras librerías que tienen miles de capas de abstracción, por dios, STL son contenedores
Me hace gracia también que se penalice el tamaño en memoria de ejecutable... como si el código fuera el responsable mayor del consumo de memoria que lo es, pero no por su propio código, si no por la memoria que el consume.
Además lanzo una pregunta: si el compilador no te genera el código autmáticamente, quien lo debe generar? y no quiero respuestas de void* ni nada así, puesto que hay implementaciones de contenerdores con una clase base basada en void* y por encima templatizadas para que el trabajo sucio lo haga el compilador. Dudo mucho que el que haga esas implementaciones tenga en mente el paradigma orientado a objetos y me gustaría ver cómo lidia con operator=, etc, etc, si std::vector tiene restricciones me gustaría ver esa implementación.
Quiero matizar tb que aunque genere más código no quiere decir que la aplicación sea más lenta en ejecución ya que por introducir un template no añade código extra a cada una de las implementaciones.
En conclusión, para mi carece de sentido no usar STL salvo que sea porque estás codeando algo para un dispositivo embebido donde el tamaño si importa, seas tan bueno que seas capaz de hacer una implementación mejor o, como sés, te de el gusto de no usarla. En cuanto a la frase "los templates no me gustan" y "te ahorras la conversión de punteros" y los razonamientos posteriores me ahorré el comentario y dejaré que zupervaca lo medite.
Bueno ^_^... es que yo no tengo modelos que ocupen 100 veces más.
Si estoy haciendo un programa enorme, ese tamaño me daría exactamente igual.
Lo mismo si fuera para algo del trabajo. En el trabajo utilizo lo que tenga a mano, no voy a comerme la cabeza.
La diferencia es que por esto no me pagan, lo hago porque quiero. No me va a pasar nada por "perder" el tiempo rehaciendo algunas cosas a mi gusto, la verdad.
Otra cosa, es que BGL no es un programa. Yo no digo que alguna vez utilize STL para algún programa mío, o para algún juego, pero este no es el caso: es una librería. Una de las características que quiero que tenga, es que debe ser ligera.
Y esa clase Vector ni siquiera está en la documentación; es "privada" y no debería usarse de momento. Seguramente lo haga de otra forma (posiblemente con una lista o yo qué sé). Y si algún día veo que necesito utilizar STL en mi librería pues... qué narices, la uso y listo.
ethernet realmente veo lo que sabes de programacion orientada a objetos desde la primera linea, pero te pondre un ejemplo rapido de como solucionar el problema de un contenedor la sobrecarga de operadores
class item
{
};
class contenedor
{
void operator << ( item &i );
};
class naveespacial : public item
{
};
void main()
{
nameespacial protagonista;
contenedor naves;
nave << protagonista;
}
lo he puesto sencillo para que veas la solucion, no se a mi me parece muy orientada a objetos ;)
¿? no sé qué tiene que ver lo que yo te he puesto con lo que has puesto tú
Yo hago referencia a lo siguiente:
class vector
{
void* _data;
void push_back(void*):
// etc
};
void main()
{
vector v1,v2;
v1.push_back(reinterpret_cast<void*>(new std::string));
//etc
v2 = v1; // no funciona, porque string tiene su operator= y no es invocado
}
de estos ejemplos te puedo poner todos los que quieras
saludos
Ah! y por cierto no sé qué quieres decir con lo de "solo viendo la primera frase sé lo que sabes de programación orientada a objetos". Frases de ese tipo sobran en mi opinión, las calificaciones personales las dejamos para la barra del bar.
CitarDudo mucho que el que haga esas implementaciones tenga en mente el paradigma orientado a objetos y me gustaría ver cómo lidia con operator=, etc, etc, si std::vector tiene restricciones me gustaría ver esa implementación.
de ahi lo saco que mas da << que =, son funciones que controlas como quieras, puedes hacer que << sea sacar en vez de meter o que incluso no haga nada o saque un mensaje en pantalla :P
realmente ese ejemplo no se para que sirve, ya que no tiene sentido meter en una clase un string para ocultarlo, y si no creas una funcion en la clase vector con el operador igual no te funcionara en la vida hagas lo que hagas
CitarAh! y por cierto no sé qué quieres decir con lo de "solo viendo la primera frase sé lo que sabes de programación orientada a objetos". Frases de ese tipo sobran en mi opinión, las calificaciones personales las dejamos para la barra del bar.
es una opinion personal en la que no digo si es mala o buena con lo que no llega a calificacion y no te he podido ofender ni gratificar
si quieres que te funcione con clases derivadas que es en lo que consiste la programacion orientada a objetos se hace con este codigo:
class base
{
virtual base &operator=( base *clase ) = 0;
};
class string : public base
{
virtual base &operator=( base *clase );
}
class vector : public base
{
base *_data;
void push_back(base*);
virtual base &operator= ( base *clase );
}
void main()
{
vector v1, v2;
v1.push_back( new string() );
v2 = v1; // Si funciona ya que todo deriva de la clase base y en la funcion operator= de vector haces lo que quieras
}
pd: voy a acabar poniendo al pie de mis post la lucha contra el stl (twist), yo creo que todos los ejemplos que se pongan siempre tendran solucion con programacion orientada a objetos, los templates como su nombre indica son plantillas y mientras mas plantillas mas tochas las apps, fijaros que simplemente si tienes un contenedor por cada tipo de dato (byte, word, dword, string, personalizados....) en una aplicacion grande puede aumentar mucho su tamaño, en cambio si derivas la clase contenedor y cambias la forma de calcular o buscar los indices estas agregando una sola funcion ya que todo el codigo se aprovecha, no se, no obstante cada uno es libre de programar como quiera, yo por mi parte pienso que los templates se usan por comodidad y no tener que pensar en jerarquias de clases
saludos
¿? de nuevo
Se supone que un contenedor debe aceptar cualquier tipo de clase y no una derivada de una clase base que defines. Estás implementando en el fondo los que hacen lenguajes como C# o java. Haciendo eso lo único que consigues es tener que activar el rtti ...
Cuando puse el ejemplo de string, podrías haber puesto cualquier otra clase y sin necesidad de tener que heredar de un objeto base consigues la misma funcionalidad, de eso se trata, ese no es el objetivo que se propone.
Me gustaría ver el código para retornar de base* a la clase concreta que hemos metido y me gustaría ver también qué pasaría en el caso de querer (por error) asignar un string (derivado de base claro) a un MiObjeto (tb derivado de clase) por poner un ejemplo. Y no hablar claro de si hay por medio herencia, herencia múltiple u otras cosas.
por último cabe descatar que para implementar todo tu sistema basta con hacer:
typedef std::vector tuvector;
y con eso tengo implementado la clase vector en un momento, sin ocupar memoria extra (solo tengo la implementación para una clase) y además optimizadísima (tanto como son de expertos los que programan cualquier a de als implementaciones de STL).
Para eso sirve STL y para eso sirven los templates.
Con respecto a la frase y haciendo referencia a lo que dices me reafirmo más en mi opinión, esa frase sobra. Me parece que una frase no se pone para no decir nada.
saludos
CitarSe supone que un contenedor debe aceptar cualquier tipo de clase y no una derivada de una clase base que defines. Estás implementando en el fondo los que hacen lenguajes como C# o java. Haciendo eso lo único que consigues es tener que activar el rtti ...
tu mismo das la solucion mas abajo, herencia multiple, el c# nunca lo he tocado y el java no es uno de los lenguajes que mas me gustan, incluso su sistema de eventos no me gusta
CitarCuando puse el ejemplo de string, podrías haber puesto cualquier otra clase y sin necesidad de tener que heredar de un objeto base consigues la misma funcionalidad, de eso se trata, ese no es el objetivo que se propone.
la clase base se pone precisamente para meter en la funcion del operador= de vector esto:
*_data = *clase;
CitarMe gustaría ver el código para retornar de base* a la clase concreta que hemos metido y me gustaría ver también qué pasaría en el caso de querer (por error) asignar un string (derivado de base claro) a un MiObjeto (tb derivado de clase) por poner un ejemplo. Y no hablar claro de si hay por medio herencia, herencia múltiple u otras cosas.
pues si metes una clase por error seria lo mismo que si le metes a vector una conversion de un puntero a una clase que no toca; ej: v1.push_back( (tipo del template*)new aviondepapel ); con esto el template traga pa entro :D
para retornar es de lo mas sencilla: base *get(){return _data; };
lo dicho la herencia multiple evita precisamente uno de los problemas que mencionabas arriba :rolleyes:
Citarpor último cabe descatar que para implementar todo tu sistema basta con hacer:
typedef std::vector tuvector;
y con eso tengo implementado la clase vector en un momento, sin ocupar memoria extra (solo tengo la implementación para una clase) y además optimizadísima (tanto como son de expertos los que programan cualquier a de als implementaciones de STL).
el numero de lineas no importa, ya que entonces el lenguaje del basic gana a todos los demas :P, ademas quien no te dice que la la clase vector que mencionas esta que da ascucho por dentro B)
CitarCon respecto a la frase y haciendo referencia a lo que dices me reafirmo más en mi opinión, esa frase sobra. Me parece que una frase no se pone para no decir nada.
esa frase dice algo para mi muy importante, que se tu nivel de programacion orientada a objetos :)
saludos xente
Citar
tu mismo das la solucion mas abajo, herencia multiple, el c# nunca lo he tocado y el java no es uno de los lenguajes que mas me gustan, incluso su sistema de eventos no me gusta
yo no doy ninguna solución de eso, y si es así muestramle aexplícitamente
Citar
a clase base se pone precisamente para meter en la funcion del operador= de vector esto:
*_data = *clase;
no respondes a mi pregunta, te la haré de forma directa: qué sucede si quiero meter en tu contenedor una clase de una librería aparte que no deriba de base?
Citar
pues si metes una clase por error seria lo mismo que si le metes a vector una conversion de un puntero a una clase que no toca; ej: v1.push_back( (tipo del template*)new aviondepapel ); con esto el template traga pa entro biggrin.gif
para retornar es de lo mas sencilla: base *get(){return _data; };
lo dicho la herencia multiple evita precisamente uno de los problemas que mencionabas arriba
por puntos:
1.- no usas los cast de c++ por lo tanto no me sirve ese ejemplo, esto es c++ no c.
2.- Yo no abogo por usar es implemenación, yo prefiero usar templates para evitar precisamente eso
3.- con respecto a retornar: me refería a como vuelves de un tipo base* al tipo que verdaderamente yo he metido?
4.- Con herencia múltiple lo único que haces aquí es liarla más porque tienes que ndar con herencia virtual si sigues tu patrón de seguir una clase base.
Citar
el numero de lineas no importa, ya que entonces el lenguaje del basic gana a todos los demas tongue.gif, ademas quien no te dice que la la clase vector que mencionas esta que da ascucho por dentro cool.gif
No he hablado del número de lineas y por cierto, la implementación de std::vector de SGI (que es a que yo uso) es bastante elegante aunque eso sí, con una notación infernal.
Por último me gustaría que respondieras a mis preguntas y no uses terminología de c++ que no responde y además confunde las respuestas. En este post no has contestado a nada de lo que he preguntado, si la tónica en el siguiente post sigue así pasaré de largo de esta conversación porque no creo que beneficie a nadie y, la verdad, creo que ya todos saben lo que cada uno sabemos de OOP.
saludos
Citaryo no doy ninguna solución de eso, y si es así muestramle aexplícitamente
si quieres agregar una clase que tiene otra clase base a un contenedor que requiere una clase base distitanta simplemente utiliza herencia multiple
Citarno respondes a mi pregunta, te la haré de forma directa: qué sucede si quiero meter en tu contenedor una clase de una librería aparte que no deriba de base?
haz un interfaz que contenga la clase de esa libreria como se ha hecho toda la vida
Citarno usas los cast de c++ por lo tanto no me sirve ese ejemplo, esto es c++ no c
CitarYo no abogo por usar es implemenación, yo prefiero usar templates para evitar precisamente eso
esos casting son validos 100%, ademas de que si te la pueden colar asi y tu no quieres sigue siendo problema del template o un bug de programacion, la solucion es muy sencilla, con una clase base podrias definir el tipo de clase en una variable y comprobar si son iguales o diferentes, quitando el bug al 100%, un ejemplo lo tienes en la clase CObject de las MFC
Citarcon respecto a retornar: me refería a como vuelves de un tipo base* al tipo que verdaderamente yo he metido?
se llama casting de toda la vida, aunque mejor seria decir que con el template solo puedes introducir un solo tipo de clase con lo que en el contendor siempre tienes un solo tipo de clase
CitarCon herencia múltiple lo único que haces aquí es liarla más porque tienes que ndar con herencia virtual si sigues tu patrón de seguir una clase base
a mi no me resulta complicado trabajar con herencia multiple, es mas lo encuentro sumamente util y facil de utilizar en c++, ademas si no la quieres usar siempre tienes la posibilidad de realizar un interface como siempre se ha hecho
CitarNo he hablado del número de lineas y por cierto, la implementación de std::vector de SGI (que es a que yo uso) es bastante elegante aunque eso sí, con una notación infernal.
yo nunca he visto el codigo fuente de la clase std::vector y creo que la han hecho dos personas, para mi gusto la clase std::vector es lenta, siempre prefiero mi clase hash interpolada con arboles :D
CitarPor último me gustaría que respondieras a mis preguntas y no uses terminología de c++ que no responde y además confunde las respuestas.
es que el bgl esta programado en c++ y por eso salio el tema de templates en c++, ademas las stl tambien son c++, con lo que no logro entenderte
CitarEn este post no has contestado a nada de lo que he preguntado, si la tónica en el siguiente post sigue así pasaré de largo de esta conversación porque no creo que beneficie a nadie y, la verdad, creo que ya todos saben lo que cada uno sabemos de OOP
creo haber respondido a tus preguntas, pero si ves que falta alguna por responder ponmela directamente, yo por mi parte no creo ofender a nadie, el tema me parece interesante ya que tal vez sea yo el que me de cuenta que estoy equivocado nunca se sabe, por ahora los templates no me han convencido salvo si en un trabajo me exigieran usarlas :), es mas, la ultima vez que me llamaron para una entrevista mencionaron si sabia manejar las stl, lo cual para mi me sorprendio ya que son cuatro clases y comparado con cualquier otro api mas moderno no son mucha cosa
en serio te digo que para mi esto no es ir en contra tuya ni nada, para mi es exponer dos opiniones diferentes y poder llegar conclusiones nuevas
saludos
A mí los templates me gustan, pero lo veo como XML: no es la solución a todo :P
Y a todo esto... (ses) ¿de qué iba este hilo?
Por mi parte pido disculpas a sés por entrometerme en el post de su librería.
en cuanto a zupervaca, como te dije, no has respondido a lo que te he preguntado y además demuestras tener carencias en el uso de cast y otras cosas, te recomiendo leer effective c++ y more effective c++. Te podría poner mil pegas a todos tus intentos de respuesta pero para eso lee un libro, te vendrá mejor.
saludos
Cita de: ethernetPor mi parte pido disculpas a sés por entrometerme en el post de su librería.
en cuanto a zupervaca, como te dije, no has respondido a lo que te he preguntado y además demuestras tener carencias en el uso de cast y otras cosas, te recomiendo leer effective c++ y more effective c++. Te podría poner mil pegas a todos tus intentos de respuesta pero para eso lee un libro, te vendrá mejor.
saludos
¿realmente no ves el codigo que te estoy poniendo? ¿o simplemente no quieres verlo?
no te entiendo ya que estas viendo miles de soluciones para evitar usar templates y ahorrar memoria y tamaño del ejecutable y sigues diciendo que no son validos y que hay una pregunta que no te contesto.
¿que pregunta es esa?
los casting de c++ son para programadores que tienden a equivocarse al realizar casting y estos son meros chequeos que hace el compilador ya que no se si sabras que los casting son ficticios y solo sirven para que el compilador entienda que estructura es la que se esta procesando
me gustaria que me dijeras una sola pega de las miles que mencionas, por cada pega que pongas te aseguro que te digo varias buenas razones y desmiento esa pega :P
A mí me gusta la forma de programar de sés. Yo programo igual. Y no entiendo nada de poo de lo que estais hablando XD
El tamaño importa.
un saludo
Buenas....
Respecto al offtopic, y yo que creía saber algo de POO O_O
El tema esta bastante interesante, pero si que es cierto que quizás este post no sea el mejor lugar. Os invito (como si lo necesitarais, sorry >_<) a crear un post en general o en offtopic para continuar este alocado pero interesante tema xDD
Respecto a BGL+Escape, mis felicitaciones sés, tanto por la libreria como con el juego (ole) (ole)
Cita de: ethernetMe hace bastante gracia que nos preocupemos de eso teniendo después:
1.- imágenes, sonidos y modelos que ocupan 100 veces (me quedo corto) más que el código
2.- usando otras librerías que tienen miles de capas de abstracción, por dios, STL son contenedores
Lo más gracioso es que tu juego era el de 4Kb X'D
Cita de: fieroA mí me gusta la forma de programar de sés. Yo programo igual.
Gracias.
Cita de: shephirothRespecto a BGL+Escape, mis felicitaciones sés, tanto por la libreria como con el juego (ole) (ole)
Gracias de nuevo :)
No pasa nada por el off-topic, pasa siempre, qué se le va a hacer. Igualmente me parece un tema interesante.
Estoy acostumbrado a C y a Java, no soy precisamente un experto en C++ y en su forma de hacer las cosas. Todo lo que pueda aprender estará bien.
Como ya dije, yo no he hablado a favor ni en contra de STL. Supongo que están bien para lo que están, nada más. Lo único que defiendo, y que no veo nada raro ni malo en ello (que para algo somos programadores), es el rehacernos las cosas que no nos gusten.
Lo dicho, me apunto a otro hilo para hablar del tema.
P.D.: Ya he quitado mi clase Vector de BGL, ale. Irá en la próxima versión.
Con respecto a BGL símplemente hice un comentario pero me parece muy respetable que sés no quiera meter STL, hay muchos programadores que por una u otra razón no usan STL. Si ir más lejos tim sweney no usa STL en el code del unreal y se codea sus propios contenedores. En mi opinión los hubiera usado pero, como digo, es un opinión como cualquier otra. En cuanto a la librería me parece bastante interesante y que el desarrollo y progresión que ha llevado es muy buena. Además a todo el desarrollo de la librería se le un el juego del concurso 24 horas que es un buen escaparate para la librería.
En cuanto al offtopic: Yo definendo el uso de templates, no para todo, pero sí para lo que es necesario y acepto (y uso ) otras opciones como las que zupervaca cita (usar void* como contenedor) pero sabiendo las restricciones que eso conlleva (uso para tipos básicos, sin necesidad de construcción explícita, sin herencia, etc). Esta discusión podría ser fructífera si los problemas que he propuesto sobre la implementación que propone zupervaca fueran coherentes, sin embargo no he obtenido ninguna respuesta que me sirva, y por extensión, que sirva a nadie interesado en el tema. Un ejemplo de las contradicciones es el último post:
Citar
los casting de c++ son para programadores que tienden a equivocarse al realizar casting y estos son meros chequeos que hace el compilador ya que no se si sabras que los casting son ficticios y solo sirven para que el compilador entienda que estructura es la que se esta procesando
Te plateo el siguiete código:
#include <iostream>
class B { public: virtual void foo() { std::cout << "B" << std::endl;}};
class D : public B { public: void foo() { std::cout << "D" << std::endl;} };
class C { public: virtual void foo(){std::cout << "C" << std::endl; };};
int main()
{
B* pb = new D;
B* pb2 = new B;
C* pc = new C;
D *pd;
pd = dynamic_cast<D*>(pc); //upcasteo mal
if(!pd) std::cout << "fallo if 1" << std::endl; //me percato del error
pd = (D*)(pc); //upcasteo mal
if(!pd) std::cout << "fallo if 2" << std::endl; //ni puto caso del error
pd->foo(); //WOPS! ¿?
return 0;
Resultados
Citar
C:\temp> cl /GR 1.cpp
....
/out:1.exe
1.obj
C:\temp>1
fallo if 1
C
Como ves, un dinamic_cast no es un cast convencional y tiene sus usos específicos (como los otros 3 cast de c++, e gustaría ver como haces un cast de const a no const con uno de esos tuyos de C tan útiles... ).
Esto aplicado a tu código:
tuvector v1;
v1.push_back(new C);
D* d =(D*) v1.get(0);
d->foo(); //error
usando templates y cast adecuados obtendrás errores de compilación y errores en ejecución cuando la cagues. Como ves no se pueden hacer cosas así como así y si en C, C++ y demás lenguajes tipados (C++ fuertemente tipado a mi modo de ver) son para algo, no para pasárselo por el forro. En el caso de herencia múltiple tienes muchísimos más problemas, ejemplos tienes en:
http://msdn.microsoft.com/library/default..../express_72.aspSupongo que como no te equivocas nunca porque eres un programador que no se equivoca no necesitarás este tipo de cast. Supongo que tampoco harás programas en los que no sepás qué tipo de dato te viene y tengas que definirlo en tiempo de ejecución (ejemplo en la url que te he dado) o quizás te programes tu propio RTTI y así continúes con la tónica de reinventar la rueda programandote un vector para recudir unos 3 o 4k's de código. Si quieres un ejemplo de lo que se puede hacer con templates y C++ solo tienes que mirar el cotw que puse hace unos meses o leerte el libro modern c++ design. La potencia que ofrecen los templates supera con creces la pérdida de espacio en disco e incluso con templates puedes usar código especializado para diferentes plataformas, mejorando el espacio en disco y la velocidad de ejecución (puedes verlo en modern c++ design).
Otra cosa que me gustaría ver es la lentitud de std::vector, teniendo en cuenta que muchos de los métodos que usa son inline (usa bastante métodos porque tiene un código muy ortogonal) y que a la hora de reservar memoria lo hace de una forma lógica me sorprende que digas eso. Lógicamente cada cosa tiene su uso y no es lógico usar un vector si necesitas hacer inserciones continuadas en el medio del vector. Ya buscaré algún benchmark acerca de eso, tengo curiosidad.
No voy a hacer ningún comentario más acerca de este tema, si acaso de BGL.
saludos
bien en el primer codigo que indicas que falla no es un fallo en si, si el programador no sabe con que clase trabaja es que no sabe sencillamente lo que hace, en ningun caso excepto con templates esto sucede, un motivo mas para eliminarlos de nuestros codigos ya q
** no se que ha pasado pero tengo que volver a escribir todo el post
bien en el primer codigo que indicas que falla no es un fallo en si, si el programador no sabe con que clase trabaja es que no sabe sencillamente lo que hace, en ningun caso excepto con templates esto sucede, un motivo mas para eliminarlos de nuestros codigos ya que el dinamic_cast de c++ añade codigo extra a nuestros codigos de forma oculta lo que puede provocar que la velocidad general disminuya
en el segundo codigo un contenedor solo tiene un tipo de clase y el programador siempre sabe cuala es ya que si guardas 100 tipos de clases diferentes tendrias que poner 100 ifs para saber que clase es
Citarusando templates y cast adecuados obtendrás errores de compilación y errores en ejecución cuando la cagues
plantear bien el codigo evita precisamente "cagarla", el dinamic_cast solo agrega codigo extra de forma oculta para programadores que efectivamente no saben lo que hacen
CitarSupongo que como no te equivocas nunca porque eres un programador que no se equivoca no necesitarás este tipo de cast. Supongo que tampoco harás programas en los que no sepás qué tipo de dato te viene y tengas que definirlo en tiempo de ejecución (ejemplo en la url que te he dado) o quizás te programes tu propio RTTI y así continúes con la tónica de reinventar la rueda programandote un vector para recudir unos 3 o 4k's de código
normalmente el programador sabe el tipo de dato que es y si no es asi en la clase base se indica una variable para indicarlo, que es algo parecido a lo que hace dinamic_cast de forma oculta y luego como harias con el dinamic_cast compruebas con ifs para saber si es el tipo de dato que buscas
CitarSi quieres un ejemplo de lo que se puede hacer con templates y C++ solo tienes que mirar el cotw que puse hace unos meses o leerte el libro modern c++ design. La potencia que ofrecen los templates supera con creces la pérdida de espacio en disco e incluso con templates puedes usar código especializado para diferentes plataformas, mejorando el espacio en disco y la velocidad de ejecución (puedes verlo en modern c++ design).
el template nunca podra ser mejor que una clase ya que el template es una plantilla para crear clases, el compilador usa el template para crear una clase por tipo de template, esto tiene que quedarte muy claro, la multiplataforma se puede hacer mucho mejor sin templates creando una clase base plataforma y derivando de ella y optimizando 100% para cada plataforma, que yo sepa por ahora todo el mundo lo ha hecho asi, desde glu hasta el famoso y moderno glfw (http://glfw.sourceforge.net/)
sobre esto que solo te quede claro que los templates como su nombre indica son plantillas generadoras de clases es como si cambiaras todos los T por el nombre de la clase que has puesto
CitarOtra cosa que me gustaría ver es la lentitud de std::vector, teniendo en cuenta que muchos de los métodos que usa son inline (usa bastante métodos porque tiene un código muy ortogonal) y que a la hora de reservar memoria lo hace de una forma lógica me sorprende que digas eso. Lógicamente cada cosa tiene su uso y no es lógico usar un vector si necesitas hacer inserciones continuadas en el medio del vector. Ya buscaré algún benchmark acerca de eso, tengo curiosidad.
los metodos inline solo evitan un salto o llamada, lo que realmente importa es la metodologia que usa la clase std::vector, la prueba de esto esta en la funcion standard qsort a la cual le pasas un puntero de funcion para comprobar los buffers a ordenar, me gustaria saber cuanto tarda en buscar 1 millon de registros en ese clase, en una tabla hash interpolada con arboles binarios 0,24 segundos a 1,25 segundos dependiendo del tamaño de la tabla hash con indices tipo string en un piii1200
CitarNo voy a hacer ningún comentario más acerca de este tema, si acaso de BGL.
realmente veo que crees que esto es una lucha y no sabes que para mi es un tema tan interesante y que a muchos les podemos ayudar a decidirse en usar o no usar templates y para que puede ser mejor usarlos o no
os voy a poner un ejemplo de lo que puede pasar usando templates:
- tenemos un template para realizar busquedas en nuestra base de datos de 10000 clientes, estos clientes tienen 20 tipos de indices, por cada indice creamos un template y cada template ocupa 10kb compilado el resultado es 20 * 10kb = 200kb mas que ocupa en memoria y en la aplicacion, resulta que el ordenador en el que se trabaja tiene la memoria ram saturada y gracias a nuestra aplicacion que ocupa 200kb en vez de 10kb como deberia ser el ordenador tira de disco duro para crear y trabajar con memoria virtual retardado el sistema de busquedas!!!, consecuencia: comprar mas memoria ram :lol:
como veis 190kb pueden llegar a ser muy importantes, si usaramos clases bases o void* solo ocuparia 10kb
otra cosa a tener en cuenta es que no por usar sobrecarga de operadores tenemos que usar templates, podemos sobrecargar diferentes tipos o el de la clase base asi como pasar de ellos y usar funciones de nombres; ej: void operator=(base*pepe); es lo mismo que void igualar(base*pepe);, ahora eso si los operadores quedan mas bonitos y son mas logicos
saludos y espero que el tema no pare que por mi parte me esta gustando hablar de ello
Cita de: zupervacaCitarNo voy a hacer ningún comentario más acerca de este tema, si acaso de BGL.
realmente veo que crees que esto es una lucha y no sabes que para mi es un tema tan interesante y que a muchos les podemos ayudar a decidirse en usar o no usar templates y para que puede ser mejor usarlos o no
No es una lucha, solo un off-topic como un piano.
-_- *saca la escoba y empieza a barrer el hilo*
-con respecto a dinamic_cast y lo que comentas de añadir una variable a la clase base para indicar el tipo de la clase derivada: eso se llama RTTI y no es necesario que te hagas una clase.
-No he dicho que un template por si solo optimice el código, he dicho que puedes optimizar el código usandolos, como te he dicho lee el libro modern c++ design y de paso aprendes algo de templates.
-Un template no genera código más lento:
template struct A { T a; };
struct B{ int a;}; es ___totalmente equivalente__ a A
-Por último comentar el ejemplo totalmente irreal que has pueso:
os voy a poner un ejemplo de lo que puede pasar usando templates:
- tenemos un template para realizar busquedas en nuestra base de datos de 10000 clientes, estos clientes tienen 20 tipos de indices, por cada indice creamos un template y cada template ocupa 10kb compilado el resultado es 20 * 10kb = 200kb mas que ocupa en memoria y en la aplicacion, resulta que el ordenador en el que se trabaja tiene la memoria ram saturada y gracias a nuestra aplicacion que ocupa 200kb en vez de 10kb como deberia ser el ordenador tira de disco duro para crear y trabajar con memoria virtual retardado el sistema de busquedas!!!, consecuencia: comprar mas memoria ram laugh.gif
como veis 190kb pueden llegar a ser muy importantes, si usaramos clases bases o void* solo ocuparia 10kb
Te reto a que intentes crear una aplicación que ocupe 10k sin templates y otra con templates y 20 tipos templatizados que ocupe 200kb o lo que quieras más, siendo representativo lógicamente, adelante. (basado en std:vector y en tu versión)
Además por último te animo a que intentes hacer algo con templates para que veas el beneficio que obtienes y te dejes de milongas de 4 ó 5 kb más de código ejecutable que no son representativos actualmente para absolutamente nada. Si quieres complicarte la vida por 5kb... adelante, tú mismo, un buen programador saber encontrar el equilibrio entre ese tipo de cosas.
ahora sí, fin
Citar-con respecto a dinamic_cast y lo que comentas de añadir una variable a la clase base para indicar el tipo de la clase derivada: eso se llama RTTI y no es necesario que te hagas una clase.
la ventaja de hacerlo tu es sencilla, sabes lo que esta haciendo por debajo
Citar-Un template no genera código más lento:
eso es lo que quiero decirte desde el principio, el template no es ni mejor ni peor simplemente genera clases y repite codigo, es otra forma de programar
CitarTe reto a que intentes crear una aplicación que ocupe 10k sin templates y otra con templates y 20 tipos templatizados que ocupe 200kb o lo que quieras más, siendo representativo lógicamente, adelante. (basado en std:vector y en tu versión)
¿me estas diciendo que el compilador no genera una clase diferente para cada template? el compilador siempre hara una copia del template cambiara el tipo del template y lo compilara, por cada tipo de template el compilador siempre generara una nueva clase, si una clase generada con un template ocupan 10kb y haces 20 clases mas con diferentes tipos de template salen 200kb, las matematicas no fallan (eso solo contando el codigo compilado no hablo de sizeof(clase) que eso da el tamaño de los datos de la clase que es otra cosa totalmente distinta)
CitarAdemás por último te animo a que intentes hacer algo con templates para que veas el beneficio que obtienes y te dejes de milongas de 4 ó 5 kb más de código ejecutable que no son representativos actualmente para absolutamente nada. Si quieres complicarte la vida por 5kb... adelante, tú mismo, un buen programador saber encontrar el equilibrio entre ese tipo de cosas.
ya he trabajado con ellos, para lo unico que valen es para repetir codigo compilado en tus aplicaciones, que es algo que nunca he entendido, si el c++ se base en la reutilizacion de todo el codigo posible ¿por que los templates crean funciones identicas con diferentes tipos?
saludox xente