Foros - Stratos

Programadores => General Programadores => Mensaje iniciado por: sukhur en 05 de Enero de 2007, 10:12:24 AM

Título: C++ y POO
Publicado por: sukhur en 05 de Enero de 2007, 10:12:24 AM
Hola, estaba inventándome un ejercicio para repasar una asignatura y me he encontrado con un problema. El ejercicio es más o menos:

Vehiculo
  matricula
  año
  precio
  motor
  getMatricula()
  getAño()
  getPrecio()
  getMotor()

Camion:Vehiculo
    pma
    longitud
    getPma()
    getLongitud()

Moto:Vehiculo
    cm3
    velpunta
    getCm3()
    getVelPunta()

Pues bien ahora yo quiero crear un vector :

Vehiculo *vecVehiculos[10];

vecVehiculos[0]=new Camion(,,,,);
vecVehiculos[1]=new Moto(,,,,);

pero que además pueda acceder a los métodos propios de cada subclase, por ejemplo:

vecVehiculos[0]->getPma();
vecVehiculos[1]->getCm3();

¿Con que se hace esto? ¿Polimorfismo? ¿Clases abstractas? ¿Dónde está Wally?
Título: C++ y POO
Publicado por: Fran en 05 de Enero de 2007, 10:27:16 AM
Lo puedes hacer de varias formas

1.Herencia + Casteo (si donde lo vayas a tratar sabes a q te estás refiriendo)

Es decir: Moto deriva de Vehiculo

Y si cuando vayas a tratar sabes q es una moto haciendo (Moto)(Vehiculos[2])->cm3

2. Implementación abstracta:

Hay un método virtual y/o abstracto (sin implementación o con devolucion de 0 o valor nulo) en vehiculo, que luego en moto por ejemplo lo implementas como heredado y sobreescrito como lo q te  haga falta de modo que cuando llames al metodo PMA de una moto por ejemplo te devuelva el de Vehiculo=0 y cuando llames al de camion (q lo habras implementado) te devuelva 40 Tn.

3. Y hay otra pero es una patata.

Estas son las q se me ocurren y para mi la mejor es la 2.
Título: C++ y POO
Publicado por: Diferencial en 05 de Enero de 2007, 10:35:44 AM
Hola sulhur,
Si no estoy equivocado que alguien me corrija se haria de la siguiente forma:


Vehiculo vec[10];
vec[0] = new Camion();
/*vec[0] contiene una instancia de camión y esto es posible a la herencia y al polimorfismo ya que has convertido un vehiculo a un camion.
Vehiculo tiene que ser una clase abstracta. No es necesario pero en tu caso no necesitas crearte objetos de tipo vehiculo ya que seran camion o moto.*/

//Ahora puedes acceder a los metodos de camion de esta forma
vec[0].getPMA();
//Lo mismo sucede con moto
vec[1] = new Moto();
vec[1].getCm3();

//El ejemplo que tu pones tambien es correcto usando punteros, aunque no se muy bien si te referias a lo que he puesto yo??
Título: C++ y POO
Publicado por: sukhur en 05 de Enero de 2007, 10:51:48 AM
Entonces Fran, en Vehiculo tendria que poner ademas de las ya existentes estas otras:

virtual getPma()=0;
virtual getLongitud()=0;
virtual getCm3()=0;
virtual getVelPunta()=0;
Título: C++ y POO
Publicado por: Fran en 05 de Enero de 2007, 11:38:33 AM
Cita de: "sukhur"Entonces Fran, en Vehiculo tendria que poner ademas de las ya existentes estas otras:

virtual getPma()=0;
virtual getLongitud()=0;
virtual getCm3()=0;
virtual getVelPunta()=0;

Si. Yo adoptaría esa solución. Xq no recuerdo si en C++ se le podía poner abstract pero si lo declaras solo como abstract (q no tendrias mas que declararlas sin implementarlas), puede darte un error de abstract error code si las llamas desde un descendiente que no lo tenga implementado.

A lo mejor a alguien se le ocurre otra forma. Pero yo lo haría así
Título: C++ y POO
Publicado por: Fran en 05 de Enero de 2007, 11:39:02 AM
Cita de: "sukhur"Entonces Fran, en Vehiculo tendria que poner ademas de las ya existentes estas otras:

virtual getPma()=0;
virtual getLongitud()=0;
virtual getCm3()=0;
virtual getVelPunta()=0;

Si. Yo adoptaría esa solución. Xq no recuerdo si en C++ se le podía poner abstract (hace mas de 10 años q no lo toco) pero si lo declaras solo como abstract (q no tendrias mas que declararlas sin implementarlas), puede darte un error de abstract error code si las llamas desde un descendiente que no lo tenga implementado.

A lo mejor a alguien se le ocurre otra forma. Pero yo lo haría así
Título: C++ y POO
Publicado por: sukhur en 05 de Enero de 2007, 01:13:50 PM
Pues efectivamente se produce el error, en Camion porque no encuentra los métodos de Moto, y en Moto porque no encuentra los de Camion.

¿Como soluciono ésto?
Título: C++ y POO
Publicado por: tamat en 05 de Enero de 2007, 01:24:39 PM
La solución que te han dicho me parece una chapuza (con todos mis respetos).

Yo lo que hago es tener un método abstracto en la clase base que se llame GetType() que retorne un int, y luego hago un enum o unos defines para asignar un valor a cada clase.

Así cuando quieras hacer algo propio de camion hago:


if ( vec[0]->GetType() == CLASS_CAMION)
   ((Camion*)vec[0])->GetCM3();


Esta solución la he visto en muchos sitios y me parece la mejor, luego puedes activar el RTTI que sirve para preguntar de qué tipo es una instancia en C++ pero no se muy bien como va.
Título: C++ y POO
Publicado por: bnl en 05 de Enero de 2007, 01:35:46 PM
Yo creo q no tiene mucho sentido el enunciado.

Si el array de elementos de la clase base solo deberias llamar a los metodos propios de la clase padre. Si estamos hablando de vehiculos, no podrias decir  que te hiciera un caballito porque lo mismo es una moto que un camion.
Título: C++ y POO
Publicado por: Pogacha en 05 de Enero de 2007, 02:16:44 PM
La verdad es que la solucion mas amiga de la POO es el uso de RTTI(real time type information) y moldeo dinamico (dynamic cast)

No queda bien claro el caso pero he de suponer que debe ser algo como esto:void Imprimir_Reporte(Vehiculo *elvehiculo)
{
   printf("Matricula: %s\n", elvehiculo->getMatricula());
   printf("Año: %d\n", elvehiculo->getAño());
   printf("Precio: %.2f\n", elvehiculo->getPrecio());
   printf("Motor: %s\n", elvehiculo->getMotor());

   Camion *elcamion = dynamic_cast<Camion>(elvehiculo)
   if(elcamion) {
      printf("Pma: %d\n", elcamion->getPma());
      printf("Longitud: %.2f\n", elcamion->getLongitud());
  }

   Moto *lamoto = dynamic_cast<Moto>(elvehiculo)
   if(lamoto) {
      printf("Cm3: %d\n", lamoto->getCm3());
      printf("VelPunta: %.2f\n", lamoto->getVelPunta());
  }
}

Esto mismo se puede hacer con un falso RTTI como propone tamat pero debes agregar a vehiculo
class Vehiculo
public:
enum Tipo { CAMION, AUTO };
virtual Tipo getType() = NULL;
...


y a moto y camion los correspondientes
virtual Tipo getType() { return MOTO; }
virtual Tipo getType() { return CAMION; }


con lo que el imprimir reporte se transforma en:
void Imprimir_Reporte(Vehiculo *elvehiculo)
{
   printf("Matricula: %s\n", elvehiculo->getMatricula());
   printf("Año: %d\n", elvehiculo->getAño());
   printf("Precio: %.2f\n", elvehiculo->getPrecio());
   printf("Motor: %s\n", elvehiculo->getMotor());

  switch(elvehiculo->getType())
  {
      case Vehiculo::CAMION:
        {
          Camion *elcamion = static_cast<Camion>(elvehiculo)
          printf("Pma: %d\n", elcamion->getPma());
          printf("Longitud: %.2f\n", elcamion->getLongitud());
        }
        break;
      case Vehiculo::MOTO:
        {
           Moto *lamoto = satic_cast<Moto>(elvehiculo)
           printf("Cm3: %d\n", lamoto->getCm3());
           printf("VelPunta: %.2f\n", lamoto->getVelPunta());
        }
        break;
   }
}


La solución de tener una clase abstracta con todas las funciones por mas que sean absurdas no es muy amiga de la POO, por que entonces, para que quieres heredar de ellas si la clase base ya tiene todas las funcionalidades que tu querias?

Saludos!
Título: C++ y POO
Publicado por: Fran en 05 de Enero de 2007, 02:33:58 PM
Cita de: "tamat"La solución que te han dicho me parece una chapuza (con todos mis respetos).

Yo lo que hago es tener un método abstracto en la clase base que se llame GetType() que retorne un int, y luego hago un enum o unos defines para asignar un valor a cada clase.

Así cuando quieras hacer algo propio de camion hago:


if ( vec[0]->GetType() == CLASS_CAMION)
   ((Camion*)vec[0])->GetCM3();


Esta solución la he visto en muchos sitios y me parece la mejor, luego puedes activar el RTTI que sirve para preguntar de qué tipo es una instancia en C++ pero no se muy bien como va.

El método 1 q he escrito es este. A mi, personalmente, me parece un coñazo. Tienes que estar haciendo para cada propiedad q tengas el mismo código. Me parece mucho más corto (aunq no sea muy ortodoxo segun vosotros) decir que todos los vehiculos tienen CM3 y que en principio es 0. Si te interesa para alguno de ellos saber cual es (las motos), lo redefines en esa clase en particular y ya está. De hecho a mi entender lo q estás diciendo es un absurdo. Segun tu el metodo de un clase figura sería algo asi como:

if ( vec[0]->GetType() == CLASSTRIANGULO)
   result=b * h * 0.5
else if .... = CLASSRECTANGULO
  result=b * h
else if......

Segun yo, defines metodo abstracto en clase figuras Area
y luego en cada clase hija pones su método de calculo . Metodo a todas luces (para mi) mas corto, mas racional y mas facilmente legible y escalable. Por ejemplo, si quieres insertar un nuevo tipo de vehiculo, con tu metodo hay que declararlo en esos IF (si tienes N propiedades y 3 vehiculos nuevos), 3N ifs nuevos, con el mio no tienes q hacer nada.
Título: C++ y POO
Publicado por: Fran en 05 de Enero de 2007, 02:37:15 PM
Cita de: "Pogacha"La verdad es que la solucion mas amiga de la POO es el uso de RTTI(real time type information) y moldeo dinamico (dynamic cast)

No queda bien claro el caso pero he de suponer que debe ser algo como esto:void Imprimir_Reporte(Vehiculo *elvehiculo)
{
   printf("Matricula: %s\n", elvehiculo->getMatricula());
   printf("Año: %d\n", elvehiculo->getAño());
   printf("Precio: %.2f\n", elvehiculo->getPrecio());
   printf("Motor: %s\n", elvehiculo->getMotor());

   Camion *elcamion = dynamic_cast<Camion>(elvehiculo)
   if(elcamion) {
      printf("Pma: %d\n", elcamion->getPma());
      printf("Longitud: %.2f\n", elcamion->getLongitud());
  }

   Moto *lamoto = dynamic_cast<Moto>(elvehiculo)
   if(lamoto) {
      printf("Cm3: %d\n", lamoto->getCm3());
      printf("VelPunta: %.2f\n", lamoto->getVelPunta());
  }
}

Esto mismo se puede hacer con un falso RTTI como propone tamat pero debes agregar a vehiculo
class Vehiculo
public:
enum Tipo { CAMION, AUTO };
virtual Tipo getType() = NULL;
...


y a moto y camion los correspondientes
virtual Tipo getType() { return MOTO; }
virtual Tipo getType() { return CAMION; }


con lo que el imprimir reporte se transforma en:
void Imprimir_Reporte(Vehiculo *elvehiculo)
{
   printf("Matricula: %s\n", elvehiculo->getMatricula());
   printf("Año: %d\n", elvehiculo->getAño());
   printf("Precio: %.2f\n", elvehiculo->getPrecio());
   printf("Motor: %s\n", elvehiculo->getMotor());

  switch(elvehiculo->getType())
  {
      case Vehiculo::CAMION:
        {
          Camion *elcamion = static_cast<Camion>(elvehiculo)
          printf("Pma: %d\n", elcamion->getPma());
          printf("Longitud: %.2f\n", elcamion->getLongitud());
        }
        break;
      case Vehiculo::MOTO:
        {
           Moto *lamoto = satic_cast<Moto>(elvehiculo)
           printf("Cm3: %d\n", lamoto->getCm3());
           printf("VelPunta: %.2f\n", lamoto->getVelPunta());
        }
        break;
   }
}


La solución de tener una clase abstracta con todas las funciones por mas que sean absurdas no es muy amiga de la POO, por que entonces, para que quieres heredar de ellas si la clase base ya tiene todas las funcionalidades que tu querias?

Saludos!

Respondido en lo anterior. ¿Para que tienes q hacer un CASE? . No veis q liais la programación sin necesidad de hacerlo?
Título: C++ y POO
Publicado por: Pogacha en 05 de Enero de 2007, 02:49:25 PM
Cita de: "Fran"Segun yo, defines metodo abstracto en clase figuras Area
y luego en cada clase hija pones su método de calculo . Metodo a todas luces (para mi) mas corto, mas racional y mas facilmente legible y escalable. Por ejemplo, si quieres insertar un nuevo tipo de vehiculo, con tu metodo hay que declararlo en esos IF (si tienes N propiedades y 3 vehiculos nuevos), 3N ifs nuevos, con el mio no tienes q hacer nada.
Pero eso no es POO!, ¿para que vas a heredar si con la base clase ya tienes todo lo que quieres?
Hay mil formas de hacer eso, muchas mas rapidas de codificar (incluso mas eficientes también) pero en la POO se sacrifica rendimiento y eficiencia para poder alcanzar objetivos mas altos los cuales solo se pueden lograr con disciplina, la misma que este paradigma nos presenta.
Saludos.
Título: C++ y POO
Publicado por: Fran en 05 de Enero de 2007, 02:54:33 PM
http://www.linuxjournal.com/article/3687

www.cs.tau.ac.il/~borens/courses/oop-03b/prez/oop_08.ppt

Extraido de este ultimo

"Our goal in polymorphism is to avoid checking the actual type of an object by using virtual methods "

Osease que me da q a lo mejor , la patata (para mi es asi) la estais plantenando vosotros. Estar checando de que tipo es , es una patata. Y demuestra no tener clara la teoria de OOP. Para mi y para muchos.
Título: C++ y POO
Publicado por: Fran en 05 de Enero de 2007, 02:56:04 PM
Cita de: "Pogacha"
Cita de: "Fran"Segun yo, defines metodo abstracto en clase figuras Area
y luego en cada clase hija pones su método de calculo . Metodo a todas luces (para mi) mas corto, mas racional y mas facilmente legible y escalable. Por ejemplo, si quieres insertar un nuevo tipo de vehiculo, con tu metodo hay que declararlo en esos IF (si tienes N propiedades y 3 vehiculos nuevos), 3N ifs nuevos, con el mio no tienes q hacer nada.
Pero eso no es POO!, ¿para que vas a heredar si con la base clase ya tienes todo lo que quieres?
Hay mil formas de hacer eso, muchas mas rapidas de codificar (incluso mas eficientes también) pero en la POO se sacrifica rendimiento y eficiencia para poder alcanzar objetivos mas altos los cuales solo se pueden lograr con disciplina, la misma que este paradigma nos presenta.
Saludos.

jajajajajajajaja. Mira. Leete un tratado serio de OOP.
Título: C++ y POO
Publicado por: Pogacha en 05 de Enero de 2007, 03:04:53 PM
Bueno ... saludos, con el mismo respeto.
Título: C++ y POO
Publicado por: Zaelsius en 05 de Enero de 2007, 03:29:17 PM
No os sulfureis, al fin y al cabo C++ no es un lenguaje orientado a objetos puro, y no siempre existe una manera claramente más correcta que otra para hacer ciertas cosas...

(Leyendo el resto del hilo..)

Bueno sí, en este caso lo tengo claro: lo mismo que Tamat.
Título: C++ y POO
Publicado por: fiero en 05 de Enero de 2007, 03:35:02 PM
Cita de: "tamat"Yo lo que hago es tener un método abstracto en la clase base que se llame GetType() que retorne un int, y luego hago un enum o unos defines para asignar un valor a cada clase.

Así cuando quieras hacer algo propio de camion hago:


if ( vec[0]->GetType() == CLASS_CAMION)
   ((Camion*)vec[0])->GetCM3();


Esta solución la he visto en muchos sitios y me parece la mejor, luego puedes activar el RTTI que sirve para preguntar de qué tipo es una instancia en C++ pero no se muy bien como va.

Yo tambien utilizo este método, aunque sólo lo he usado con structuras, en las que siempre hay un campo "tipo" en la misma posición de la estructura. El método de tener una función getType() en la clase base me parece muy limpio, y no es demasiado engorroso.

un saludo
Título: C++ y POO
Publicado por: tamat en 05 de Enero de 2007, 04:14:58 PM
Cita de: "Fran"Segun yo, defines metodo abstracto en clase figuras Area
y luego en cada clase hija pones su método de calculo . Metodo a todas luces (para mi) mas corto, mas racional y mas facilmente legible y escalable. Por ejemplo, si quieres insertar un nuevo tipo de vehiculo, con tu metodo hay que declararlo en esos IF (si tienes N propiedades y 3 vehiculos nuevos), 3N ifs nuevos, con el mio no tienes q hacer nada.

Fran, no mees fuera de tiesto, el ejemplo que tu pones del area no tiene nada que ver, si ese fuese el caso yo tendría un método area que cada uno implementaria pero porque supondré todas las figuras tienen area, sin embargo en su caso habla de propiedades que SOLO una de las clases derivadas posee. El sistema que propones no solo rompe con la POO por todos lados sino que añade un overhead a cada instancia por cada método virtual que "podria tener una clase derivada".

Ciñiendome a las necesidades que él planteaba en su post (acceder a un método especifico de una clase derivada) yo le digo cómo se suele hacer. Pero como muy bien han dicho pogacha o bnl el problema es que dicho requisito ya parte de un mal diseño (aunque existen muchos casos donde se da).
Título: C++ y POO
Publicado por: Fran en 05 de Enero de 2007, 05:21:09 PM
Cita de: "tamat"
Cita de: "Fran"Segun yo, defines metodo abstracto en clase figuras Area
y luego en cada clase hija pones su método de calculo . Metodo a todas luces (para mi) mas corto, mas racional y mas facilmente legible y escalable. Por ejemplo, si quieres insertar un nuevo tipo de vehiculo, con tu metodo hay que declararlo en esos IF (si tienes N propiedades y 3 vehiculos nuevos), 3N ifs nuevos, con el mio no tienes q hacer nada.

Fran, no mees fuera de tiesto, el ejemplo que tu pones del area no tiene nada que ver, si ese fuese el caso yo tendría un método area que cada uno implementaria pero porque supondré todas las figuras tienen area, sin embargo en su caso habla de propiedades que SOLO una de las clases derivadas posee. El sistema que propones no solo rompe con la POO por todos lados sino que añade un overhead a cada instancia por cada método virtual que "podria tener una clase derivada".

Ciñiendome a las necesidades que él planteaba en su post (acceder a un método especifico de una clase derivada) yo le digo cómo se suele hacer. Pero como muy bien han dicho pogacha o bnl el problema es que dicho requisito ya parte de un mal diseño (aunque existen muchos casos donde se da).

:) Yo no meo fuera del tiesto. Simplemente digo que esa forma que he expuesto es bastante usada. De hecho esa forma de declarar métodos aunque luego no los uses es en lo que se basa los interfaces de Java por ejemplo. Da mucha mas flexibilidad. Disminuye código (como por ejemplo podrás ver en www.kbcafe.com/articles/OOP.Concepts.pdf (mira abstraction)) y sobre todo da claridad al mismo sin tener que retocar el código cada vez q te cambian cualquier cosa o quieres introducir un nuevo tipo de clase. Vamos . Para mi no solo no está en contraposicion a la OOP sino que es una manera inteligente de usarla. Y si está en contra encuentrame un sitio donde diga q está en contra xq yo me he molestado incluso en mirar mi olvidado "Manual de Referencia C++ con anotaciones" de STROUSTRUP  (Addison-Wesley) y lo único q sí he encntrado es que no le gusta hacer exactamente lo q tú haces. Página 247 , clases derivadas :
[..]
Segundo: Si se proporciona una forma sencilla , conveniente de preguntar de qué tipo es un objeto, se pondría en marcha un estilo de programación que se apoyaría en tener un campo de tipo o preguntar que tipo, mas que en el uso de funciones virtuales. Cuando se tomo la decision de no incluir en C++ esa posibilidad (q x lo q veo no es de C++ basico) ejerció mucha influencia el hecho de saber que, en los programas de Simula, este estilo condujo a que el código resultase confuso y no modular.
Por otro lado, la ausencia de tal utilidad hace algunas tareas bastante mas dificiles - como la entrada/salida de objetos- porque el usuario se ve obligado a construirse mecanismos propios....
[...]

Creo que si el creador de C++ consideró q no era necesario el mecanismo de RTTI sino que era mejor usar métodos virtuales, por algo será. De todos modos creo q esta discusion se basa simple y llanamente en falta de experiencia. Es evidente cuando has tirado mas de 2,5 millones de lineas de código (y no hace falta que venga a decirlo STROUSTRUP , ni que lenguajes como Java implementen algo similar en los interfaces (con toda la sobrecarga que supone esto), ni el ejemplo del enlace de las piernas y lo que pone debajo) que una cosa
es mucho mucho más flexible y clara que la otra.

Por cierto es la edición del 94. Cuando yo usaba C++.
Título: C++ y POO
Publicado por: Diferencial en 05 de Enero de 2007, 06:41:50 PM
Creo que existe una confusión porque tanto lo que dice fran como lo que dice tamat esta en lo cierto. Es decir, para metodos comunes a las clases hijas lo metes en la clase base como virtual puro y lo redefines en las clases hijas. Pero para metodos propios de la clase hija es decir el ejemplo que ha dado
sukhur, tienes que hacer obligatoriamente el cast si es que los quieres meter todos dentro de un vector. Pero la mejor respuesta es la de bnl ya que creo que lo que quiere hacer sukhur esta mal planteado, deberias de separar los objetos o hacerte una estructura mejor para evitar esos casts.
Título: C++ y POO
Publicado por: sukhur en 05 de Enero de 2007, 06:50:51 PM
Hola de nuevo, como ya había dicho es un ejercicio inventado y claro, me ha salido de tal manera que no tiene solución si atiendo a lo que me han explicado en clase segun veo.

Gracias a todos.
Título: C++ y POO
Publicado por: fiero en 05 de Enero de 2007, 07:59:13 PM
Fran, lo que explicas tiene mucho sentido y está claro que es bastante lógico. Estoy de acuerdo que para el ejemplo planteado por sukhur es una solución válida. Sin embargo, en la práctica esto no se dá casi nunca.

Por ejemplo, en las MFC (no estoy diciendo que las MFC sean ningún ejemplo a seguir), existe la clase CWnd (ventana genérica) de la que derivan otros objetos como combos, botones, listas, dialogos... Hay muchas funciones de la biblioteca que devuelven un puntero a CWnd y es el programador el que debe saber de que tipo de objeto se trata, ya que la clase base no tiene tooodas las funciones virtuales de tooodas las posibles funciones de las clases derivadas.

un saludo
Título: C++ y POO
Publicado por: zupervaca en 05 de Enero de 2007, 09:07:05 PM
Mi granito de arena para ayudarte:

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <conio.h>

class Vehiculo
{
public:
Vehiculo( const char* matricula, const char* fecha, int precio, const char* motor )
{
this->matricula = matricula;
this->fecha = fecha;
this->motor = motor;
this->precio = precio;
}

const char* getMatricula()
{
return this->matricula;
}

const char* getFecha()
{
return this->fecha;
}

int getPrecio()
{
return this->precio;
}

const char* getMotor()
{
return this->motor;
}

virtual const int getType() = 0;

private:
const char* matricula, *fecha, *motor;
int precio;
};

class Moto : public Vehiculo
{
public:
Moto( const char* matricula, const char* fecha, int precio, const char* motor, int cm3, int velpunta )
: Vehiculo( matricula, fecha, precio, motor )
{
this->cm3 = cm3;
this->velpunta = velpunta;
}

int getCm3()
{
return this->cm3;
}

int getVelPunta()
{
return this->velpunta;
}

const int getType()
{
return Moto::Type;
}

static const int Type;

private:
int cm3, velpunta;
};
const int Moto::Type = (const int)(__int64)&Moto::Type;

class Camion : public Vehiculo
{
public:
Camion( const char* matricula, const char* fecha, int precio, const char* motor, const char* pma, int longitud )
: Vehiculo( matricula, fecha, precio, motor )
{
this->pma = pma;
this->longitud = longitud;
}

const char* getPma()
{
return this->pma;
}

int getLongitud()
{
return this->longitud;
}

const int getType()
{
return Camion::Type;
}

static const int Type;

private:
const char* pma;
int longitud;
};
const int Camion::Type = (const int)(__int64)&Camion::Type;

int main()
{
const int numVehiculos = 4;
Vehiculo* v[numVehiculos];
v[0] = new Camion( "B-23-AZ", "19/12/2005", 100000, "4 Valvulas", "PMA1", 500 );
v[1] = new Moto( "W-743-TH", "2/1/2007", 1000, "Pegasus", 500, 150 );
v[2] = new Moto( "X-364-YT", "5/6/2005", 1000, "Cañero", 500, 150 );
v[3] = new Camion( "A-7453-HC", "17/5/2006", 100000, "20 Valvulas", "PMA16", 600 );

char sz[512] = "";
for( int n = 0; n < numVehiculos; n++ )
{
Vehiculo* ve = v[n];
if( ve != NULL )
{
if( ve->getType() == Camion::Type )
{
Camion* camion = (Camion*)ve;
sprintf( sz, "n=%i, tipo=camion, getType=%i, idtipo=%i, pma=%s\r\n",
n, camion->getType(), Camion::Type, camion->getPma() );
}
if( ve->getType() == Moto::Type )
{
Moto* moto = (Moto*)ve;
sprintf( sz, "n=%i, tipo=moto, getType=%i, idtipo=%i, cm3=%i\r\n",
n, moto->getType(), Moto::Type, moto->getCm3() );
}
printf( sz );
delete ve;
}
}

getch();

return 0;
}

Lo unico que te puede interesar es como crear un tipo para cada clase unico sin tener que especificarlos, es decir, evitar que se pueda repetir un mismo tipo sin tener que conocer los demas.

Suerte :wink:
Título: Re: C++ y POO
Publicado por: shephiroth en 05 de Enero de 2007, 10:20:58 PM
Me vais a perdonar, pero creo que mucha gente esta viciada de dar soluciones chapuzas en problemas mas complejos y se han olvidado de la teoria basica de POO.

Lo del getType es un apaño mas bien feo que se suele usar cuando se tienen mil tipos de objetos y la base madre existe solo para poder vectorizarlos de mala manera. Desde mi punto de vista lo mas normal seria para imprimir los datos crear un virtual mostrar y luego codificarla en cada clase como se maneja individualmente. Para acceder a sus variables obligaria a usar un cast, que quien quiera acceder que sepa pq accede. Si lo unico q quieres es mostrar los datos con el virtual mostrar sobra.

Si quieres hacer cosas mas elaboradas deberas crearlas siempre en funciones virtuales y que hereden (ejemplo mover, cargar, encender, etc...).

Insisto, lo del getType me parece un apaño chapuza que os habeis enviciado por otros problemas.
Título: Re: C++ y POO
Publicado por: Zaelsius en 05 de Enero de 2007, 10:54:53 PM
Cita de: "shephiroth"Lo del getType es un apaño mas bien feo que se suele usar cuando se tienen mil tipos de objetos y la base madre existe solo para poder vectorizarlos de mala manera.

Vale, a ver cómo harías tú esto:

- Tenemos una colección de formularios formados por widgets de múltiples tipos. Clase base "Widget", clases derivadas "Botón","Lista","CheckBox" etc. Toda la funcionalidad codificada en C++.

- Por otro lado tenemos un script en Lua/Python/Loquesea que accede a uno de los widgets, llamado "dificultad" y del tipo "Lista", para preguntarle por el ítem actualmente seleccionado. ¿Pero cómo sabemos que el widget "dificultad" efectivamente es del tipo "Lista" y que por tanto ofrece el método deseado? Pues o haces un getType() y lo compruebas, o usas un dynamic_cast<> y capturas la excepción, o usas el operador typeof.

No es ninguna chapuza, es que no hay otra manera de hacer las cosas cuando no sabes de antemano de qué tipo es la instancia que estás tratando, y necesitas algo diferente de ella.

En Java tienes instanceof y en otro lenguajes modernos hay mecanismos similares. Si en C++/juegos no se usa RTTI más a menudo, y se usan los getType "a mano", es por evitar la más mínima sobrecarga y poder robar algunos ciclos más a la CPU... pero eso ya es otra historia.

Citarquien quiera acceder que sepa pq accede
¿Nos fiamos del programador? ¿Y la gestión de errores? ¿Dejamos que el programa explote o lo dejamos fallar en 'silencio' a pesar de las consecuencias posteriores?
Título: C++ y POO
Publicado por: zupervaca en 05 de Enero de 2007, 11:02:11 PM
Entonces segun tu... ¿como obtendrias los cm3 de un objeto moto ya que hay mas programadores en tu empresa y no sabes si lo van a necesitar para realizar alguna operacion en la que no has pensado? sabiendo claro que la lista puede contener camiones u otros tipos de vehiculos.

Nota: Es que si sabes el tipo de objeto con el que trabajas no hace falta llamar a la funcion getType, pero nunca esta de mas poner alguna forma de identificar la clase, ademas el c++ y otros lenguajes vienen con esta funcionalidad, con lo que tal mal como solucion no puede ser :?
Título: C++ y POO
Publicado por: swapd0 en 05 de Enero de 2007, 11:15:26 PM
Segun los libros, si estas usando RTTI no estas programando al estilo C++, yo, y supongo que todos, lo hemos tenido que usar alguna vez...

De todas formas, ¿por que no te planteas el diseño? no el de las clases, pero podrias hacer una clase que hiciera de contenedor, y al añadirle una moto o camion, lo meta en listas distintas, asi no tendrias problemas de llamar a una funcion que esta implementada solo en una de las clases.
Título: C++ y POO
Publicado por: Zaelsius en 05 de Enero de 2007, 11:26:24 PM
@Swapd0: Si coges un libro de C++ nuevo(p.ej. The C++ Programming Language, Stroustrup, 2002) verás que habla del RTTI y presenta casos donde es necesario su uso. Habla del typeid, el dynamic_cast, etc..

No entiendo cómo usar un contenedor "inteligente" con N listas soluciona el problema. Le pides al contenedor que te devuelva la instancia X y él te la da. Sigues sin saber su tipo. O bien le pides que te devuelva la instancia X del tipo Y, y él comprobará que efectivamente está en la lista Y. ¿Pero y si no está? De nuevo otra comprobación de error. No ganas nada dejando la comprobación de tipo al contenedor, y complicas el sistema innecesariamente.

La comprobación de tipos es necesaria e ineludible en algunos casos. No existe ningun patrón de diseño mágico que lo solucione.
Título: Re: C++ y POO
Publicado por: Fran en 06 de Enero de 2007, 12:23:38 AM
Cita de: "shephiroth"Me vais a perdonar, pero creo que mucha gente esta viciada de dar soluciones chapuzas en problemas mas complejos y se han olvidado de la teoria basica de POO.

Lo del getType es un apaño mas bien feo que se suele usar cuando se tienen mil tipos de objetos y la base madre existe solo para poder vectorizarlos de mala manera. Desde mi punto de vista lo mas normal seria para imprimir los datos crear un virtual mostrar y luego codificarla en cada clase como se maneja individualmente. Para acceder a sus variables obligaria a usar un cast, que quien quiera acceder que sepa pq accede. Si lo unico q quieres es mostrar los datos con el virtual mostrar sobra.

Si quieres hacer cosas mas elaboradas deberas crearlas siempre en funciones virtuales y que hereden (ejemplo mover, cargar, encender, etc...).

Insisto, lo del getType me parece un apaño chapuza que os habeis enviciado por otros problemas.

Totalmente de acuerdo. El propio Ellis Stroustrup se negó a meterlo en el Ansi C++ inicial xq para eso estan los virtuales como he transcrito arriba de su famoso libro
Título: C++ y POO
Publicado por: Pogacha en 06 de Enero de 2007, 12:35:21 AM
En realidad no me molesta que la gente piense diferente (siempre te parecera tener los pelos del chancho en la mano antes de decir que son blancos), si y mucho cuando se pierde el respeto en una conversación.

Saludos
Título: C++ y POO
Publicado por: Vicente en 06 de Enero de 2007, 12:25:36 PM
A ver, yo estoy también de acuerdo con tamat y cia que su solución es la correcta (frente a la de Fran y shephiroth). No podéis poneros a aplicar las reglas de la POO a un problema que está claramente mal planteado (meter un montón de cosas diferentes en un contenedor y querer acceder a sus especificaciones en vez de a la de la clase común).

Imaginaos que sois desarrolladores y vais a usar una u otra solución:

- usais la de tamat y cia: ningún problema, os va a ir perfecto y seguramente el getType ese ni lo uséis porque no intentaréis hacer cosas que están mal pensadas.

- usais la de Fran y cia: vais a ver clases (como moto y camion) que tienen un montón de métodos QUE NO HACEN NADA. Y no vais a pensar: ostias que cracks, seguro que querían meter motos y camiones en un contenedor de vehiculos y poder acceder a sus funcionalidades y por eso tenemos un montón de métodos que casi al azar, hacen cosas o no hacen cosas. Lo que vais a pensar es que vaya chapuza de libreria, donde hay clases que tienen varios métodos declarados que no hacen nada de nada.

O vamos, así pensaría yo si viera eso... Un saludo!

Vicente
Título: C++ y POO
Publicado por: shephiroth en 06 de Enero de 2007, 01:20:36 PM
ZAELSIUS: Respecto a la programacion de scripts, ya se que hay problemas para los q son "necesarios" ciertas practicas. Pero como me parece que deje claro esos problemas se dan por practicas mas avanzadas que una simple POO. Para una POO basica NO SE NECESITA un getType. Aun asi, en tu ejemplo, utilizar metodos virtuales puede parecer engorroso si cada clase hija tiene metodos totalmente diferente. Pero esq en ese caso la base madre existe solo para poder vectorizar de mala manera, no por ventaja de POO.

Sobre gestion de errores, si nosotros somos los programadores finales esta claro que sabemos de que va el tema. Sino, que de errores bien gordos y buena documentacion. Asi el programador que los use fijo que no puede dejarse cosas en el aire. Sobre errores silenciosos, me parecen lo peor del mundo, luego que se reinicia windows sin venir a cuento...

ZUPERVACA: Yo no digo que lo de getType no sirva nunca, lo que me parece es matar moscas a cañonazos. Desde luego para un enunciado (aunque mal planteado) de POO basica me parece una burrada usar getType...

POGACHA: Te he de dar la razon, ahora que me releo el post la manera en que lo escrebi no es la adecuada. Pido perdon a todo el mundo  :oops:

VICENTE: En lo unico que estoy deacuerdo contigo es que el uso del getType depende de la situacion y que el ejemplo que se expuso esta mal planteado. Pero para un ejemplo basico de POO el getType es demasiado lioso. Esta claro que si lo pones no te va a dar ningun problema, pero como dice mi profesor de universidad "hay que evitar usar codigo muerto", es decir, codigo que no se va a usar. El getType hay que ponerlo cuando se necesita, no por costumbre.

SALUDOS ^^
Título: C++ y POO
Publicado por: zupervaca en 06 de Enero de 2007, 01:28:12 PM
Cita de: "shephiroth"pero como dice mi profesor de universidad "hay que evitar usar codigo muerto", es decir, codigo que no se va a usar. El getType hay que ponerlo cuando se necesita, no por costumbre.
Pues sin querer ofender, pero no se decirlo de mejor manera... tu porofesor no sabe de lo que habla, ya que si la funcion getType existe, pero no se usa, esta funcion no existira en el ejecutable final, mientras mas funcionalidad mejor y si no se usa no pasa nada, esta es una de las mejores cosas que tienen los compiladores de c/c++.
Título: C++ y POO
Publicado por: shephiroth en 06 de Enero de 2007, 02:15:06 PM
Me estas diciendo que los compiladores de c solo compilan lo que utilizas en vez de todo el codigo?? Bueno saberlo :)

P.D: Actualmente no estdio c en la uni, sino component pascal y java.
Título: C++ y POO
Publicado por: Fran en 06 de Enero de 2007, 03:11:03 PM
No me voy a leer el hilo xq me parece darle la vuelta a lo mismo. Solo digo que si te hace falta getType o RTTi a menudo,en mi opinion es q no has pensado bien tu jerarquia de clases . Para mi son algo CASI como el goto (no tan feo). Algo q a veces hace falta, pero en lo q no puedes basar una programación
Título: C++ y POO
Publicado por: Fran en 06 de Enero de 2007, 03:22:13 PM
Cita de: "Vicente"A ver, yo estoy también de acuerdo con tamat y cia que su solución es la correcta (frente a la de Fran y shephiroth). No podéis poneros a aplicar las reglas de la POO a un problema que está claramente mal planteado (meter un montón de cosas diferentes en un contenedor y querer acceder a sus especificaciones en vez de a la de la clase común).

Imaginaos que sois desarrolladores y vais a usar una u otra solución:

- usais la de tamat y cia: ningún problema, os va a ir perfecto y seguramente el getType ese ni lo uséis porque no intentaréis hacer cosas que están mal pensadas.

- usais la de Fran y cia: vais a ver clases (como moto y camion) que tienen un montón de métodos QUE NO HACEN NADA. Y no vais a pensar: ostias que cracks, seguro que querían meter motos y camiones en un contenedor de vehiculos y poder acceder a sus funcionalidades y por eso tenemos un montón de métodos que casi al azar, hacen cosas o no hacen cosas. Lo que vais a pensar es que vaya chapuza de libreria, donde hay clases que tienen varios métodos declarados que no hacen nada de nada.

O vamos, así pensaría yo si viera eso... Un saludo!


Vicente

Yo sin embargo si veo muchas llamadas a RTTI o getType pienso: joder xq quieres casar lavadoras con capsulas espaciales???. En cualquier caso
te recomendaria que te vieras por ejemplo unos cuantos interfaces java. De ellos hay en ocasiones en los que solo usas 4 o 5 metodos. El resto es codigo muerto que como tu  dices (para mi no es asi) no vale para nada. Para mi vale para dar flexibilidad ante requerimientos no predefinidos. O te vieras el codigo de la VCL de Delphi a ver cuantas llamdas a RTTI ves (alguna pero pocas, casi ninguna).
Título: C++ y POO
Publicado por: zupervaca en 06 de Enero de 2007, 03:29:17 PM
Cita de: "shephiroth"Me estas diciendo que los compiladores de c solo compilan lo que utilizas en vez de todo el codigo?? Bueno saberlo :)

P.D: Actualmente no estdio c en la uni, sino component pascal y java.
Es lo que hacen y yo lo uso para optimizar muchas cosas, sobre todo las funciones virtuales, por ejemplo, tienes una clase base abstracta y dos derivadas que son para renderizar en ogl y d3d, si compilas las dos en el ejecutable las funciones virtuales seguiran siendolo teniendo que resolverse las llamadas a ellas en tiempo de ejecucion, ahora si compilas solo la del ogl o d3d el compilador resolvera en tiempo de compilacion las funciones virtuales con la consiguiente ganancia de velocidad.

Efectivamente en java no existe esta ventaja :( , no obstante tienes algunos ofuscadores que eliminan el codigo que no va a ser usado ahorrando espacio en el jar final :D, aunque no se exactamente si la eliminacion es por funciones y clases o solo por clases.
Título: C++ y POO
Publicado por: shephiroth en 06 de Enero de 2007, 03:38:07 PM
Los interfaces de java son otra cosa, con lo de codigo muerto (si lo decias por mi) me referia a crear funciones miembro que no se van a llamar nunca. Lo de dar flexibilidad.....es cierto que puedes dar cierta flexibilidad creando metodos alternativos.....pero una cosa es dar flexibilidad y otra cosa es trabajar de 2 maneras diferentes. Cuando creas una clase tienes q tener claro como trabajar con ella. Una vez tienes claro como trabajar, internamente haz toda la flexibilidad que quieras, pero publicamente la forma de trabajar tiene q ser una y solo una. Sino puedes estar creando una ambigüedad y dar muchos quebraderos de cabeza el pogramador que utilice tu clase.

SALUDOS ^^

Respecto a java, hemos empezado desde cero, y hasta el segun cuatrimestre no empezaremos con POO, asi que es un tema que no conozco, pero gracias por lo q dices ^^
Título: C++ y POO
Publicado por: swapd0 en 06 de Enero de 2007, 04:28:06 PM
Un ejemplo, yo tengo hecho un ensamblador de risc y cisc (los dos juntos), las instrucciones las meto en un contenedor, y despues para buscar dependencias en los registros (solo en codigo risc), tenia que usar RTTI. No me gustaba como estaba echo, pero por lo menos me servia para comprobar si funcionaba bien  el optimizador de codigo.

Para solucionar esto, cree 2 clases, una para codigo cisc y otra para risc:

class CodeChunk
{
...
   virtual void FindDependecies() { ; }
};

class CiscCodeChunk : public CodeChunk
{
...
};

class RiscCodeChunk : public CodeChunk
{
...
   virtual void FindDependecies() { // codigo para buscar dependencias }
};


El codigo cisc va a CiscCodeChunk y el risc a RiscCodeChunk. Ahora no uso RTTI, no me gusta que FindDependecies() este vacio, pero me gusta mas que usar RTTI, que queda muy feo en el codigo.
Título: C++ y POO
Publicado por: Vicente en 07 de Enero de 2007, 12:15:52 AM
Cita de: "Fran"Yo sin embargo si veo muchas llamadas a RTTI o getType pienso: joder xq quieres casar lavadoras con capsulas espaciales???.

Claro, ese es el problema del ejemplo, casar cosas diferentes en la misma colección... Lo de implementar solo "trozos" de interfaces, podrá estar en la jdk (también he visto cosas similares danzando por el framework de .NET), pero eso no lo hace la solución buena. Es simplemente porque no te queda más remedio (ya que ese método si no se implementa es porque no tiene sentido, y no lo va a tener en la vida). De todas formas, MS por ejemplo recomienda encarecidamente no usar las interfaces para definir funcionalidad común ;) (usar clases abstractas mejor)

Un saludo!

Vicente
Título: C++ y POO
Publicado por: fiero en 07 de Enero de 2007, 07:09:36 PM
Hombre... lo de casar lavadoras con capsulas espaciales no es tan raro. Yo por ejemplo uso en mi programa una lista de objetos que pueden ser cosas muy diferentes, otra cosa es como te lo montes.
Por ejemplo, en un cuadro de dialogo de Windows, el diálogo mantiene una lista de todos los elementos dentro del diálogo, ya sean iconos, combos, botones, etc. Un icono tiene poco que ver con un combobox, y sin embargo los dos derivan de la clase común "ventana" (CWnd si se usa MFC, o identificadores HWND si se usa el API de Windows). Al preguntar al diálogo por cada elemento que contiene te devuelve punteros CWnd, y es el programador el que tiene que hacer un cast de ese puntero para usarlo como combobox o como icono.

En fin, que estas cosas no son tan extrañas como pueda parecer.

un saludo
Título: C++ y POO
Publicado por: shephiroth en 07 de Enero de 2007, 07:29:32 PM
Iconos, botones, combobox y todos los controles de un formulario no derivan de Window, derivan de Control. Es una clase especial creada para unificar todo lo que contiene un formulario, para unificar todo lo que se dibuja encima  de un formulario.

Un ejemplo claro de esto lo tendrías en el objeto Form.Controls. En el MFC todos los controles que creas son añadidos a esta coleccion, y se utiliza tanto para dibujar como a la hora de finalizar el formulario.
Título: C++ y POO
Publicado por: Vicente en 07 de Enero de 2007, 09:01:45 PM
Ya, pero no por ser todos controles la clase Control define todos los métodos que cualquier posible control pueda necesitar. Control simplemente define la mínima funcionalidad común, y si quieres un control específico necesitas algo como el getType ese.

Un saludo!

Vicente
Título: Esto empieza a hacerse pesadito ya
Publicado por: Fran en 08 de Enero de 2007, 01:19:08 PM
8) Vamos a ver. No tengo a mi disposición (me la cargué hace ya años y he estado buscando pero no la encuentro) una jerarquia de clases que en su momento (año 92) me hice en C++ para hacer un GUI (con ventanas, botones, menus, combos... y todo eso) para MSDOS. No usé para nada GetType ni RTTI xq no estaban soportadas y además no me hacia falta. Pero es que a quien quiera convencerse y dado que no es lo q digamos unos u otros xq entiendo que lo q yo diga os tiene q ser tan indiferente como al resto lo vuestro,y dado que x lo q leo para muchos aqui una jerarquia de clases para un GUI es algo en lo que se debería usar profusamente el tema, os recomiendo leais una gran obra (de alguien q a día de hoy tiene en su haber dos grandes productos : Anders Helsberg  (Delphi y C# (es el arquitecto jefe)): la VCL de Delphi. Cuando encontreis en algo q no sea la conexion con activex un getType me lo decís. Yo os puedo decir donde se usan metodos virtuales vacios. Y hay unos cuantos en las clases base. Evidentemente para mi ese es un criterio. Fijarse en un grande. Y no en lo q diga alguien q usar RTTI es ortodoxo con la OOP y usar métodos virtuales y después redifinirlos no
Título: C++ y POO
Publicado por: fiero en 08 de Enero de 2007, 01:36:35 PM
Cita de: "shephiroth"Iconos, botones, combobox y todos los controles de un formulario no derivan de Window, derivan de Control.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_hierarchy_chart.asp

Todos los controles, vistas, dialogos, etc, derivan de la clase ventana genérica CWnd, o si se usa el API de Windows a pelo, identificadores HWND.

Me extraña mucho que todas las clases base de VCL de Delphi incluyan todos los metodos de todas sus posibles derivadas, pero bueno, yo no he leido a ese señor.

un saludo
Título: C++ y POO
Publicado por: Fran en 08 de Enero de 2007, 01:48:25 PM
Ya. Pues por ejemplo y ya q sacas el tema de MS. Crees q un CButton devolverá algo si llamas a su metodo GetMenu?  o un checkbox? Y sin embargo su clase padre (CWnd) los tiene implementados (mirate el enlace que has puesto).........  Por cierto. Haces muy mal no leyendo a Heiljsberg. Dado q fué quien diseño Delphi y C# creo q aprenderías como cualquiera (yo incluido) mucho

De la ayuda de Microsoft que has puesto tu mismo

GetMenu

Return Value

Identifies the menu. The value is NULL if CWnd has no menu. The return value is undefined if CWnd is a child window.

The returned pointer may be temporary and should not be stored for later use.
Remarks

This function should not be used for child windows because they do not have a menu.

Ostras!!!!! Lo q ha dicho. Ha implementado cosas en la clase base que en las hijas no devuelve nada.... SACRILEGIO. Con lo bien que qdaria un RTTI
Título: Re: Esto empieza a hacerse pesadito ya
Publicado por: Vicente en 08 de Enero de 2007, 01:53:41 PM
Cita de: "Fran"os recomiendo leais una gran obra (de alguien q a día de hoy tiene en su haber dos grandes productos : Anders Helsberg  (Delphi y C# (es el arquitecto jefe))

Pues Helsberg no ha repetido la jugada en el framework de .NET: la clase control no tiene todos los métodos posibles de todos los controles que heredan de ella como métodos virtuales vacios... Si recibes un control generico (por ejemplo de la lista de controles que contiene un panel), o haces algo como el if (es de este tipo) o vas apañao...

Un saludo!

Vicente
Título: Re: Esto empieza a hacerse pesadito ya
Publicado por: Fran en 08 de Enero de 2007, 02:00:33 PM
Cita de: "Vicente"
Cita de: "Fran"os recomiendo leais una gran obra (de alguien q a día de hoy tiene en su haber dos grandes productos : Anders Helsberg  (Delphi y C# (es el arquitecto jefe))

Pues Helsberg no ha repetido la jugada en el framework de .NET: la clase control no tiene todos los métodos posibles de todos los controles que heredan de ella como métodos virtuales vacios... Si recibes un control generico (por ejemplo de la lista de controles que contiene un panel), o haces algo como el if (es de este tipo) o vas apañao...

Un saludo!

Vicente

Lee mi anterior mensaje. Estamos tratando de si es ortodoxo o no meter metodos virtuales aunq devuelvan cosas como cero o cosas ( a vuestro modo de entender incongruentes).  Delphi lo tiene. Java lo tiene. La plataforma NET lo tiene , etc, etc. Luego cuando las principales plataformas OOP lo tienen tiene q ser bastante ortodoxo . Vamos para mi y para los autores de herramientas como esas (y otras que ya he referenciado) las ventajas son  claras. Cuanto mas grande es el proyecto y mas escalable quieres que sea, las ventajas lo son mucho mas. Y es q la verdad es q creo q si no lo veis hay poco mas q decir. Yo me enfrento en el dia a dia a cosas como tener q implementar funcionalidad que en 5-10 dias tiene q estar probada y en la calle en un programa de 800.000 lineas. Si tuviera q estar incluyendo con RTTI una subclase nueva en todo el programa... me cortaba las wenas. Si lo q hago es lo del camion o cosas en las q no hay plazo puedo entender q lo veais asi.
Título: C++ y POO
Publicado por: Vicente en 08 de Enero de 2007, 02:16:00 PM
A ver, que yo sepa Helsberg no diseñó la WinAPI... Y que yo sepa RTTI entró bastante tarde en C++, con lo cual puede (que no lo sé a ciencia cierta), que ese código se escribiera antes de que se pudiera usar RTTI en C++. Hasta donde yo tengo entendido en C++ el tema de la reflexión es mucho menos usado que en Java o .NET.

Ahora volvamos a cosas que ha diseñado Helsberg como .NET, que traen soporte nativo de reflexión (que para lo mala que es se usa que no veas).

- si tienes un panel con 2 botones y un listbox, y quieres acceder al elemento seleccionado del listbox, crees que funciona el iterar sobre todos los controles contenidos en el panel preguntando por su selecteditem? O que te tocará preguntar por su tipo para ver si es un listbox?

- si la reflexion es tan mala (RTTI), porque en .NET y Java GetType viene de serie en la clase object? (con lo cual todo el tiene ese método tan malo).

Un saludo!

Vicente
Título: C++ y POO
Publicado por: Fran en 08 de Enero de 2007, 02:17:40 PM
Mirad:

http://developers.sun.com/learning/javaoneonline/2005/coreplatform/TS-3268.pdf

Mito 3:

Uso de RTTI contra virtual

Leeroslo. Creo q hemos acabado.

Myth 3: use Run-Time Type Info
● int per object, passed into Base constructor
● Turns OO Java code into C code

Es decir. RTTI = C--, Virtual =OOP

Lo ortodoxo es usar esto, no RTTI aunque a veces tengas q usarlo

Saludos
Título: C++ y POO
Publicado por: Vicente en 08 de Enero de 2007, 02:20:09 PM
Por cierto, las razones que citas por las que .NET y Java tienen métodos virtuales vacios son diferentes a las de este caso.

La razón de meter un método virtual vacio en una clase abstracta de una libreria es porque:

- si lo metes en una interfaz, te cargas todo el código que use esa interfaz porque ya no la implementan correctamente.

- si lo metes abstracto en la clase abstracta te pasa lo mismo.

Con lo cual cuando estás sacando versiones de librerías, si te ves obligado a meter un método nuevo en las clases base, la unica manera que tienes de que no rompa el código que ya hay desplegado con las clases antiguas es meterlo ya implementado pero que no haga nada.

Un saludo!

Vicente
Título: C++ y POO
Publicado por: Fran en 08 de Enero de 2007, 02:21:21 PM
Cita de: "Vicente"Por cierto, las razones que citas por las que .NET y Java tienen métodos virtuales vacios son diferentes a las de este caso.

La razón de meter un método virtual vacio en una clase abstracta de una libreria es porque:

- si lo metes en una interfaz, te cargas todo el código que use esa interfaz porque ya no la implementan correctamente.


si lo metes abstracto en la clase abstracta te pasa lo mismo.

Con lo cual cuando estás sacando versiones de librerías, si te ves obligado a meter un método nuevo en las clases base, la unica manera que tienes de que no rompa el código que ya hay desplegado con las clases antiguas es meterlo ya implementado pero que no haga nada.

Un saludo!

Vicente

Para tu info por ejemplo, una interfaz en Java no tiene implementacion. Que si , q vale. Pero digais lo q digais. RTTI = C-- . Vamos contraorientacion a objetos. Aunq a veces sea necesaria. Y no lo digo yo ya. Leed y lo vereis.
Título: C++ y POO
Publicado por: Vicente en 08 de Enero de 2007, 02:26:10 PM
Claro, por eso rompes el código que ya esté desplegado con esa interfaz, porque las clases que implementen la interfaz no compilan porque tienen que implementar ese nuevo método que has añadido ;)

Un saludo!

Vicente
Título: C++ y POO
Publicado por: Fran en 08 de Enero de 2007, 02:42:53 PM
Cita de: "Vicente"Claro, por eso rompes el código que ya esté desplegado con esa interfaz, porque las clases que implementen la interfaz no compilan porque tienen que implementar ese nuevo método que has añadido ;)

Un saludo!

Vicente

Sinceramente no estoy siguiendo tu ejemplo. Simplemente digo y repito q si hay algo poco ortodoxo en toda esta conversación es la RTTI (aunq sigo diciendo q hay veces q es necesaria). Pero eso no es ++. Es --. Simplemente informaos y ya está.

Saludos
Título: C++ y POO
Publicado por: Vicente en 08 de Enero de 2007, 03:04:13 PM
La verdad es que puede que no me haya explicado muy bien. A ver que lo intento de nuevo.

Mi objetivo era explicar porque a veces las librerías de clases tienen métodos virtuales vacios (algo que yo he dicho que no está bien). Si tu haces una librería de clases (como VCL, JDK, o .NET) que va usar otra persona, normalmente das interfaces y clases abstractas que servirán como base para que el usuario extienda esas librerías (por ejemplo, la clase abstracta Control).

Si después de sacar la versión 1 de tu librería, al sacar la versión 2 te das cuenta de que hace falta un método nuevo, la única forma posible que tienes de añadir ese método sin romper el código de la gente que use tu librería version 1 es añadir un método vacio en una clase base.

- Si añades una declaración de método a una interfaz rompes las clases que usan la interfaz porque tienen que implementar ese nuevo método.

- Si añades un método abstracto en una clase abstracta las clases que la hereden también se rompen porque no implementan el método abstracto (y tendrían que pasar a ser abstractas).

Con lo cual la única solución que te queda es implementarlo vacio para evitar romper el código de terceros que pudiera haber usado tu clase base.

Por eso aparecen métodos "sin implementación" en clases base, porque son necesarios cuando van apareciendo versiones para no romper la compatibilidad hacia atrás, pero no porque sea un buen mecanismo de diseño cuando se diseña al principio la librería. Mirate la clase System.Windows.Form.Control de .NET, lo mismo tiene algún método vacio (que ni idea) por algún caso especial como el que antes te he comentado, pero lo que no tiene es un método vacio para todas las funcionalidades de las clases que derivan de ella, porque sería una locura absoluta.

Si quieres hacer lo del panel que te puse antes y que no respondiste, la única forma es preguntar si el control es un listbox antes de ejecutar el método (o andar cazando excepciones :p). Y eso no es malo, es que es así y no hay otra manera de hacerlo.

Un saludo!

Vicente
Título: C++ y POO
Publicado por: fiero en 08 de Enero de 2007, 03:43:06 PM
Pero, olvidais algo... YO quiero tener razón!!!   :)
Título: C++ y POO
Publicado por: Fran en 08 de Enero de 2007, 04:42:10 PM
http://www.artima.com/intv/constP.html


De Scott Meyers (Guru C++ al nivel de S...UP o como se ponga)

When to Use RTTI

Bill Venners: You said in the first edition of Effective C++:

   Fortunately, C++ provides no way to determine at runtime the actual type of object a pointer points to, and let me assure you this is no accident. In fact, runtime type inquiry (RTTI) was explicitly omitted from the language to prevent abuses such as this.

Doesn't C++ have RTTI now?

Scott Meyers: Yes.

Bill Venners: When is it appropriate to use RTTI?

Scott Meyers: Let me give you some history on why the committee added RTTI to the C++ language. This is one of those cases where the consumers won. At the time, every non-trivial class library being written was rolling its own RTTI, without exception. Every major class library used at the time, including MFC (Microsoft Foundation Classes) and NIHCL (National Institute of Health Class Library), had RTTI of some form or another. So the committee just said, "Rather than have N different ways to accomplish the same thing, we're going to have a single language mechanism that does the right thing." That's why RTTI was added. It was a simple matter of people wanted it.

Once the committee added RTTI, people started wondering when it was appropriate to use RTTI. All the bad things I wrote about RTTI in the first edition of Effective C++ continue to apply. They're still bad. So you end up with a classic engineering tradeoff. You use RTTI when the alternatives are worse.

The two most common ways to eliminate RTTI are to add virtual functions higher in the hierarchy and to hold onto a derived class interface by not promoting the derived class type to its base class type. For example, if you can replace RTTI with virtual function calls by modifying a base class, that's usually a better way to go. The other approach, eliminating the need to upcast in the first place, is especially appropriate in C++, because C++ has type-safe containers. C++ has no Object class like Java or C#. So instead of having, for example, a container of base class pointers, you can have three containers, one for each different type of derived class you're dealing with. Then you'll never lose the type information and you'll never have to do the downcast, so you don't need RTTI.


Yo, esta vez de verdad, con esto me despido . Xq creo q hay poco más que discutir. Los creadores de C++ te dicen q no lo uses y q intentes usar lo q yo puse al principio aunq suene raro . Los de Java q eso no es OO , etc, etc.. Y yo ademas de lo q ellos digan (q es todo) digo q habiendo programado mucho muchisimo ;) y muchos años, no hace falta q vengan a decirmelo ellos. Mi propia experiencia me dice q es mucho mejor lo q ahi dice y por eso dí la solucion q di a las lavadoras y carros del principio del hilo.

Saludos
Título: C++ y POO
Publicado por: shephiroth en 08 de Enero de 2007, 04:55:07 PM
Vicente, solo por curiosidad, te suena de algo los "EVENTOS"??? Deja de ser tan pesado con tu codigo de cambiar el selecteditem. Para que sepas eso lleva años solucionado, añadiendo un evento, y cuando en el codigo interno cambias de seleccion comprueba si has añadido dicho evento y llama a la funcion miembro que hayas creado para recibir dicho evento.

Respecto q todo hereda de CWnd en vez de Control, querido compañero, podrías comprobar CWnd de que hereda???

Voy a ver si consigo encontrar en la documentacion la tabla de herencias. La he visto en mas de una ocasion pero no me acuerdo donde estaba en este momento. Si la encuentro os la pongo.
Título: C++ y POO
Publicado por: tamat en 08 de Enero de 2007, 05:17:53 PM
CitarThe two most common ways to eliminate RTTI are to add virtual functions higher in the hierarchy and to hold onto a derived class interface by not promoting the derived class type to its base class type. For example, if you can replace RTTI with virtual function calls by modifying a base class, that's usually a better way to go.

En otras palabras, usando un metodo virtual como getType().

Yo no he leido tanto como vosotros pero he visto mucho codigo y en TODOS he visto algun tipo de getType() (TinyXML lo hace para saber el tipo de elemento, la libreria para abrir FBX o usa para saber el tipo de objeto de la escena, etc).
Título: C++ y POO
Publicado por: fiero en 08 de Enero de 2007, 05:22:21 PM
Cita de: "shephiroth"Respecto q todo hereda de CWnd en vez de Control, querido compañero, podrías comprobar CWnd de que hereda???

Sí, CWnd deriva de CCmdTarget que a su vez deriva de CObject, clase base de toda la MFC. Por cierto, estas dos clases con una funcionalidad muy básica que no tiene nada que ver con controles. Lo puedes ver aquí http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_hierarchy_chart.asp

Yo no he dicho que todo derive de CWnd, he dicho que todos los controles que se usan en dialogos deriban de CWnd, y esta clase no tiene implementadas todas las funciones de todos los controles. Además no existe ninguna clase "Control" como tú decías, que tenga implementadas todas las funcionalidades de todos los controles.

un saludo
Título: C++ y POO
Publicado por: Fran en 08 de Enero de 2007, 05:22:47 PM
Cita de: "tamat"
CitarThe two most common ways to eliminate RTTI are to add virtual functions higher in the hierarchy and to hold onto a derived class interface by not promoting the derived class type to its base class type. For example, if you can replace RTTI with virtual function calls by modifying a base class, that's usually a better way to go.

En otras palabras, usando un metodo virtual como getType().

Yo no he leido tanto como vosotros pero he visto mucho codigo y en TODOS he visto algun tipo de getType() (TinyXML lo hace para saber el tipo de elemento, la libreria para abrir FBX o usa para saber el tipo de objeto de la escena, etc).

¿?

Las dos formas más comunes de eliminar RTTI (xq no da lugar a pensar q no hay q quitarlo) son añadir funciones virtuales en un nivel más alto de jerarquia (es decir en las clases base) sin promover el tipo de la clase a su clase base (esto sobra. Es de cajon).  Por ejemplo, reemplazar RTTT con llamadas a funciones virtuales modificadno la clase base (lo q yo hice al principio del hilo) es usualmente la mejor manera de actuar o de hacerlo.

No sé que traducción has hecho

Por cierto. Y esto no es con ánimo de ofender ni con ningun animo de aleccionar ni nada por el estilo.  Lee mucho de buenos autores xq el ver mucho código si quien lo escribe no tiene la base suficiente es más perjudicial que otra cosa. Adquieres las malas costumbres de los demás. Eso te da bastante criterio para luego saber separar el buen código del mal código. Hay muchos códigos q funcionan, pero (ES MI OPINION) no quiere decir q sean buenos códigos.
Título: C++ y POO
Publicado por: shephiroth en 08 de Enero de 2007, 05:57:27 PM
Bueno, parece que sigo con mis cagadas, menuda semana llevo. Tienes razon, en el MFC CWind es la clase base de ventanas.  He estado buscando la de ATL pero no la he encontrado (si alguien tiene enlace, estaría muy agradecido xDD).

Referente a la clase control, System::Windows::Forms::Control.

SALUDOS ^^
Título: C++ y POO
Publicado por: Vicente en 08 de Enero de 2007, 07:16:55 PM
Cita de: "shephiroth"Vicente, solo por curiosidad, te suena de algo los "EVENTOS"??? Deja de ser tan pesado con tu codigo de cambiar el selecteditem. Para que sepas eso lleva años solucionado, añadiendo un evento, y cuando en el codigo interno cambias de seleccion comprueba si has añadido dicho evento y llama a la funcion miembro que hayas creado para recibir dicho evento.

Yo debo escribir muy mal la verdad... A ver, primero, SI se lo que es un evento en .NET (por si acaso, pero me hace gracia que me lo preguntes).

Segundo, te pego lo que puse:

"- si tienes un panel con 2 botones y un listbox, y quieres acceder al elemento seleccionado del listbox, crees que funciona el iterar sobre todos los controles contenidos en el panel preguntando por su selecteditem? O que te tocará preguntar por su tipo para ver si es un listbox?"

Aquí nadie habla de cambiar el SelectedItem, hablo de ser capaz de ejecutar la propiedad SelectedItem. Y la respuesta es que es imposible que ejecutes la propiedad SelectedItem del ListBox porque Control no la tiene. Ni virtual vacia, ni nada de nada. No la tiene, porque no debería tenerla, por mucho que una clase que herede de ella la pudiera tener. Control tiene lo mínimo que debe tener, no un porrón de métodos virtuales vacios sin pies ni cabeza.

Os he explicado porque a veces aparecen métodos virtuales vacios en las librerías de clases como Java o .NET. Es un problema de compatibilidad hacia atrás, no de que sea mejor diseñar cosas (porque vamos, si eso fuera así pues nada, que se pongan todos los métodos como virtuales vacios en Object y a correr). Quizás sea problema de haber mezclado C++ y Java/.NET ya que en C++ RTTI es algo no sé, marginal (o esa impresión me da) mientras que en Java/.NET la reflexion es una herramienta de primer orden.

Fran:

En el primer caso que comenta (lo que has puesto en negrita) dice un "usually" bastante majo ;)

Y luego podrías haber quoteado esto:

"C++ has no Object class like Java or C#. So instead of having, for example, a container of base class pointers, you can have three containers, one for each different type of derived class you're dealing with. Then you'll never lose the type information and you'll never have to do the downcast, so you don't need RTTI. "

Está claro que si tienes tres contenedores cada uno que tiene su propio tipo (con templates) no hay problemas. El problema es que estás mezclando por la clase base (Vehiculo en el ejemplo inicial, Control en el ejemplo de las ventanas, y Object en el caso general de Java o .NET), con lo cual necesitas alguna forma de saber el tipo (GetType()). Supongo que ese artículo es bastante viejo porque se refiere a los contenedores de Java y .NET cuando aún no tenian genericos (<T>) mientras que C++ si tenía templates, y por eso aparecía el problema del downcast.

Si tienes el downcast, nada te salva del GetType, y eso es lo que estamos hablando aquí, y lo que has quoteado tu mismo ;)

Un saludo!

Vicente
Título: C++ y POO
Publicado por: Fran en 08 de Enero de 2007, 07:29:36 PM
No. Que yo sepa aquí hemos estado hablando de si en C++ es mejor hacer o  usar RTTI o implementar los métodos virtuales hacia arriba. Y ningun autor deja lugar a dudas. Simplemente y sin liar la pelota. Y si, usually = lo normal. Lo otro es lo anormal.


Sigues intentando vender las bondades del RTTI o getType contra la teoria tradicional de OOP y a mi desde luego sigues sin convencerme. Buscame un autor de prestigio que diga que RTTI es mejor, mas adecuado para cosas como hacer un GUI o incluso las motos, y quizás me convenzas. Pero yo por ahora, y por mi experiencia me decanto mas por esa solucion, junto con C#, Delphi, Java, incluso el enlace a la jerarquia de clases de M$ en la que aun a sabiendas de que hay muchos métodos q van a devolver "burradas" o nil si se derivan de un clase madre de la q se quieren heredar 4 cosas, lo hacen


(Y q conste q tengo claro q para algunas cosas si es util y lo llevo diciendo todo el post)
Título: C++ y POO
Publicado por: Diferencial en 08 de Enero de 2007, 07:49:22 PM
Fran como resolverias el problema que ha planteado Vicente. (Java) Por ejemplo yo tengo una lista y varios botones en mi interfaz. Cada uno tiene asignado su metodo addActionCommand() en la misma clase que implementa ActionListener. Dentro del metodo actionPerformed() como sabes tu que objeto ha provocado el evento??

Por cierto se parece bastante al problema que se planteo desde el principio donde se quiere meter todo dentro del mismo vector.
Título: C++ y POO
Publicado por: Jare en 08 de Enero de 2007, 08:37:11 PM
1 - Extender las clases base con métodos virtuales vacíos.
2 - Llamar a getType() en el código que usa esas clases.
3 - Acompañar a un contenedor polimórfico de contenedores para cada tipo concreto.

La primera es la solución "por defecto" siempre que podamos hacerlo (podamos modificar las clases con las que estamos trabajando) y no se nos vaya de madre.

La segunda es la solución habitual cuando no podemos (o no queremos) incluir la funcionalidad que estamos programando dentro de esas clases.

La tercera suele aplicarse para optimizar, o cuando no queremos abusar de ninguna de las otras dos.

Hacer cualquier cosa de esas por norma es una marranada, hacerlo cuando resulta apropiado es perfectamente válido. Menos religión y más sentido común! :P
Título: C++ y POO
Publicado por: burb en 08 de Enero de 2007, 08:56:46 PM
Amén.
Título: C++ y POO
Publicado por: fiero en 08 de Enero de 2007, 09:36:41 PM
Exacto.
Título: C++ y POO
Publicado por: FANatiko en 08 de Enero de 2007, 10:08:28 PM
Hombre, usar RTTI a lo bruto no es buena idea... sobretodo porque ALGUNOS compiladores no tienen soporte de RTTI completo y simplemente solucionan casos sencillos (por contra, el Visual C++, p.ej, puede resolver cosas muy complejas, con herencias multiples y demas).

En mi opinión, si puedes buscar una forma de no tener que depender de ella, pues tanto mejor. Pero ojo, en esto, como dice Jare, tampoco hay reglas que sirvan siempre... aunque quizas no sea buena practica diseñar pensando en usar RTTI, sino que, cuando te lo encuentras, la usas y punto.

Yo prefiero el metodo de RTTI a lo de los metodos vacios, pero es simplemente una elección personal... es mas, consultrare mañana el Effective C++ 3a edición a ver que dice de RTTI...
Título: C++ y POO
Publicado por: Fran en 08 de Enero de 2007, 11:28:55 PM
Cita de: "Diferencial"Fran como resolverias el problema que ha planteado Vicente. (Java) Por ejemplo yo tengo una lista y varios botones en mi interfaz. Cada uno tiene asignado su metodo addActionCommand() en la misma clase que implementa ActionListener. Dentro del metodo actionPerformed() como sabes tu que objeto ha provocado el evento??

Por cierto se parece bastante al problema que se planteo desde el principio donde se quiere meter todo dentro del mismo vector.

No entiendo la pregunta. Xq q yo sepa cada boton puede tener su propio Listener y la JList tb. Asi q explicate mejor. Pero vamos, hay una cosa que ha dicho Jare en la q estoy completamente de acuerdo. Para cada cosa uso lo que sé q da mejor resultado. Partiendo del hecho de q el mejor código es el q no existe y de que si algo me limita y no me deja meter funcionalidad nueva que se le haya olvidado al puñetero cliente no me gusta, para las lavadoras me reafirmo en que seguiria en la misma historia. Xq si por ejemplo se le ha olvidado que ... ah!!!! además hay bicicletas, bastaria con añadir una nueva clase y todo lo demás funcionaría o que de pronto se le ocurriera que la moto si tiene x propiedad con hacerle un override valdría. No haría faltra nada más. Esa clase de ventajas es la q me inclina a usar en ese tipoi de casos eso. Aunq  desde luego mis clases hijas se parecen mas a sus padres. Pero vamos. Lo q si no adoptaria es getType ni RTTI xq p.e. si quieres meter una nueva clase tendrías q ir a todos los sitios donde uses las propiedades y meter nuevos cases, etc,etc. A cada cosa lo q menos te haga programar y la OOP bien usada te hace programar poco y ser muy flexible.

Por cierto. Me da q el ejemplo este q ya me explicaras no se parece en nada. Pero lo podemos derivar a él y al inicial de una clase base y yasta. Los casamos y tienes razon q se parecen.
Título: C++ y POO
Publicado por: zupervaca en 09 de Enero de 2007, 12:11:51 AM
En mi opinion creo que se esta debatiendo algo absurdo, ya que aunque yo defiendo el tipo de funciones getType como una funcionalidad extra, en toda la libreria multiplataforma que monte no la uso, el motivo es muy sencillo, no me he encontrado ningun caso en el que me haga falta, es mas en las propiedades del visual studio tengo desactivado el RTTI.
El otro dia pensando como meter ogl 1.1 pense en hacer funciones virtuales vacias que retornen NULL y en debug produzcan una ruptura del programa cuando se intenta crear por ejemplo un pixel o vertex shader ya que en la version de ogl 1.1 no se pueden crear (el motivo es para poder renderizar igualmente sprites 2d con la clase sprite desde ogl 1.1), con lo que aunque defiendo el getType siempre lo intento usar lo menos posible, no obstante creo que para el problema que indica el primer post del hilo no queda mas remedio, ya que mete todo en un mismo vector, otra posibilidad al getType para este problema es crear una funcion virtual en la clase base que permita obtener propiedades mediante un string o un identificador numerico (algo asi como la clasica funcion de mensajes que se usaba en c), como veis hay mas soluciones, no existe una mejor o peor, es solo cuestion de como se programe o nos guste programar o nos digan como debemos hacerlo :wink:
Creo que el caso que se expone aqui es algo imposible de encontrarse (por lo menos en la vida laboral, en la de estudiante puede), referente a los GUI normalmente se soluciona todo mediante eventos, el evento lo recibe el propio control, con lo que en el evento de ese control ya se sabe que tipo de control es y sabemos lo que queremos hacer.
Título: C++ y POO
Publicado por: Fran en 09 de Enero de 2007, 12:17:26 AM
Cita de: "zupervaca"En mi opinion creo que se esta debatiendo algo absurdo, ya que aunque yo defiendo el tipo de funciones getType como una funcionalidad extra, en toda la libreria multiplataforma que monte no la uso, el motivo es muy sencillo, no me he encontrado ningun caso en el que me haga falta, es mas en las propiedades del visual studio tengo desactivado el RTTI.
El otro dia pensando como meter ogl 1.1 pense en hacer funciones virtuales vacias que retornen NULL y en debug produzcan una ruptura del programa cuando se intenta crear por ejemplo un pixel o vertex shader ya que en la version de ogl 1.1 no se pueden crear (el motivo es para poder renderizar igualmente sprites 2d con la clase sprite desde ogl 1.1), con lo que aunque defiendo el getType siempre lo intento usar lo menos posible, no obstante creo que para el problema que indica el primer post del hilo no queda mas remedio, ya que mete todo en un mismo vector, otra posibilidad al getType para este problema es crear una funcion virtual en la clase base que permita obtener propiedades mediante un string o un identificador numerico (algo asi como la clasica funcion de mensajes que se usaba en c), como veis hay mas soluciones, no existe una mejor o peor, es solo cuestion de como se programe o nos guste programar o nos digan como debemos hacerlo :wink:
Creo que el caso que se expone aqui es algo imposible de encontrarse, referente a los GUI normalmente se soluciona todo mediante eventos, el evento lo recibe el propio control, con lo que en el evento de ese control ya se sabe que tipo de control es y sabemos lo que queremos hacer.

Sabias palabras. Yo soy de los de virtual. No me gusta siempre que pueda usar RTTI. De hecho solo me ha hecho falta cuando he diseñado mal la jerarquia de clases y tenia demasiada prisa para ponerme a reestructurar lo. El debate surgio en un principio xq alguen me dijo q eso no era OOP y q RTTI o getType si. Y he demostrado con citas de varios autores que es al contrario. Pero siempre he dicho q hay casos en q no qda mas c....s. En cuanto a la pregunta ya he dicho q no la entiendo xq como tu bien dices y yo tb he reseñado arriba en todos los GUIs que yo conozco incluyendo Java cada control tiene su propio actionListener o evento o como quieras llamarlo. Asi q o no entiendo la pregunta o la pregunta no está hecha bien o .....
Título: C++ y POO
Publicado por: shephiroth en 09 de Enero de 2007, 01:12:38 AM
Cita de: "Vicente""- si tienes un panel con 2 botones y un listbox, y quieres acceder al elemento seleccionado del listbox, crees que funciona el iterar sobre todos los controles contenidos en el panel preguntando por su selecteditem? O que te tocará preguntar por su tipo para ver si es un listbox?"

Este ejemplo tal cual esta expuesto me parece mal planteado. Si tienes un panel con varios botones y un listbox y quieres acceder al listbox, pues accedes directamente. Si tienes todos los controles vectorizados segun la clase base CWnd seguro que tienes necesidades de cosas raras (o getType como quieras), pero creo q eso se debe mas a una mala planificacion de tu clase que a una obligacion heredada del uso de POO. Pero si sigues pensando lo mismo, ponme un caso real, que quedandonos en medias pintas es normal que no nos entendamos.

Cita de: "Diferencial"Fran como resolverias el problema que ha planteado Vicente. (Java) Por ejemplo yo tengo una lista y varios botones en mi interfaz. Cada uno tiene asignado su metodo addActionCommand() en la misma clase que implementa ActionListener. Dentro del metodo actionPerformed() como sabes tu que objeto ha provocado el evento??

Por cierto se parece bastante al problema que se planteo desde el principio donde se quiere meter todo dentro del mismo vector.
Por fin, un ejemplo claro. Me aventuro mucho pq en java por lo que leo cambian las cosas mucho respecto de c, pero intentaré.

Que diferentes botones creen un evento y recaiga sobre una funcion comun para ambos me parece una locura. Yo cuando hago formularios los botones solo comparten funcion si no se hace referenia ninguna al control que lanzo el evento. Pero aun asi, si por alguna razon lo necesitase, no se si en java existe pero en los winforms existe una propiedad (heredada de Control) llamada FOCO, el cual lo tiene (salvo que el programador lo cambie a mano) el control que lanza el evento.

Aunque como digo mas arriba, me parece una mala programacion el que diferentes controles tengan eventos que apunten a una funcion comun la cual necesita diferenciar que control lanzo el evento.
Título: C++ y POO
Publicado por: zupervaca en 09 de Enero de 2007, 01:36:07 AM
Para solucionar el caso que indicais en el que una funcion puede ser llamada desde diferentes controles es que en los eventos de cada control se llama a esa funcion comun, la funcion solo puede tener cosas en comun que tienen los controles, los demas cambios se producen en los eventos de cada control.
Título: C++ y POO
Publicado por: Fran en 09 de Enero de 2007, 01:37:58 AM
Cita de: "shephiroth"
Cita de: "Vicente""- si tienes un panel con 2 botones y un listbox, y quieres acceder al elemento seleccionado del listbox, crees que funciona el iterar sobre todos los controles contenidos en el panel preguntando por su selecteditem? O que te tocará preguntar por su tipo para ver si es un listbox?"

Este ejemplo tal cual esta expuesto me parece mal planteado. Si tienes un panel con varios botones y un listbox y quieres acceder al listbox, pues accedes directamente. Si tienes todos los controles vectorizados segun la clase base CWnd seguro que tienes necesidades de cosas raras (o getType como quieras), pero creo q eso se debe mas a una mala planificacion de tu clase que a una obligacion heredada del uso de POO. Pero si sigues pensando lo mismo, ponme un caso real, que quedandonos en medias pintas es normal que no nos entendamos.

Cita de: "Diferencial"Fran como resolverias el problema que ha planteado Vicente. (Java) Por ejemplo yo tengo una lista y varios botones en mi interfaz. Cada uno tiene asignado su metodo addActionCommand() en la misma clase que implementa ActionListener. Dentro del metodo actionPerformed() como sabes tu que objeto ha provocado el evento??

Por cierto se parece bastante al problema que se planteo desde el principio donde se quiere meter todo dentro del mismo vector.
Por fin, un ejemplo claro. Me aventuro mucho pq en java por lo que leo cambian las cosas mucho respecto de c, pero intentaré.

Que diferentes botones creen un evento y recaiga sobre una funcion comun para ambos me parece una locura. Yo cuando hago formularios los botones solo comparten funcion si no se hace referenia ninguna al control que lanzo el evento. Pero aun asi, si por alguna razon lo necesitase, no se si en java existe pero en los winforms existe una propiedad (heredada de Control) llamada FOCO, el cual lo tiene (salvo que el programador lo cambie a mano) el control que lanza el evento.

Aunque como digo mas arriba, me parece una mala programacion el que diferentes controles tengan eventos que apunten a una funcion comun la cual necesita diferenciar que control lanzo el evento.

Es que si la pregunta es esa ( q es lo q me ha parecido entender) no ha lugar xq cada control tiene sus propios eventos (sus Listener). Luego no es necesario hacer nada de ese estilo. Y si lo haces, pues usa lo q queras, pero no se hace asi. Coincido contigo de q además es un chocho.
Título: C++ y POO
Publicado por: Jare en 09 de Enero de 2007, 01:42:41 AM
Preguntar si un determinado objeto es de una clase o no es un caso concreto de un problema más general: preguntar si un objeto tiene o no una propiedad o conjunto de propiedades. Estoy seguro de que todo el mundo ha hecho eso alguna vez. Basta de "chorradas" sobre si es "OOP" o no. :)
Título: C++ y POO
Publicado por: Lex en 09 de Enero de 2007, 02:26:07 AM
...
Título: C++ y POO
Publicado por: vincent en 09 de Enero de 2007, 08:13:45 AM
Lo que yo me pregunto es si a sukhur (quien hizo la pregunta inicial del post) le ha quedado algo claro de todo esto...
Título: C++ y POO
Publicado por: Vicente en 09 de Enero de 2007, 09:36:25 AM
Cita de: "shephiroth"Este ejemplo tal cual esta expuesto me parece mal planteado. Si tienes un panel con varios botones y un listbox y quieres acceder al listbox, pues accedes directamente. Si tienes todos los controles vectorizados segun la clase base CWnd seguro que tienes necesidades de cosas raras (o getType como quieras), pero creo q eso se debe mas a una mala planificacion de tu clase que a una obligacion heredada del uso de POO. Pero si sigues pensando lo mismo, ponme un caso real, que quedandonos en medias pintas es normal que no nos entendamos.

Imaginate que tienes una función que se llama "PonerEnModoLectura" que recibe un panel y recorre su colección de controles y si son TextBox los pone en ReadOnly = true (una propiedad que por ejemplo no tiene un Button). Para hacer eso necesito saber si un control es de verdad un TextBox, y como esa función vale para cualquier panel no puedo acceder directamente a variables declaradas por ahí.

Lo que le pasa en el problema que planteaba sukhur es lo mismo que se ha dicho con el ejemplo de la ventana: estaba metiendo varias cosas diferentes (Camiones y Motos) en un contenedor que tenia cosas de la clase base (Vehiculos). La ventana es igual porque tiene un contendor de controles pero en realidad dentro hay muchas cosas diferentes.

Pues en ese caso te toca castear. En el ejemplo de los Camiones y las Motos, si puedes modificar el código, pues podrías tomar como solución lo de la función virtual vacia (que a mi me sigue sin gustar), pero si no puedes el casteo no te lo quita nadie...

Un saludo!

Vicente

Edit: respecto a lo de Java, el caso que comentá Diferencial no es tan raro porque en Java para declarar un manejador de eventos te toca declarar una clase entera (no como en .NET), con lo cual no es raro declarar una clase con el actionListener y hacer un switch muy grande por el tipo, nombre o lo que sea del control para diferenciarlo. Porque si no si tienes 10 botones te tocaría declarar 10 clases (sin meternos en que podrías usar clases anónimas para implementar el listener).
Título: C++ y POO
Publicado por: Fran en 09 de Enero de 2007, 09:58:48 AM
Cita de: "Vicente"
Cita de: "shephiroth"Este ejemplo tal cual esta expuesto me parece mal planteado. Si tienes un panel con varios botones y un listbox y quieres acceder al listbox, pues accedes directamente. Si tienes todos los controles vectorizados segun la clase base CWnd seguro que tienes necesidades de cosas raras (o getType como quieras), pero creo q eso se debe mas a una mala planificacion de tu clase que a una obligacion heredada del uso de POO. Pero si sigues pensando lo mismo, ponme un caso real, que quedandonos en medias pintas es normal que no nos entendamos.

Imaginate que tienes una función que se llama "PonerEnModoLectura" que recibe un panel y recorre su colección de controles y si son TextBox los pone en ReadOnly = true (una propiedad que por ejemplo no tiene un Button). Para hacer eso necesito saber si un control es de verdad un TextBox, y como esa función vale para cualquier panel no puedo acceder directamente a variables declaradas por ahí.

Lo que le pasa en el problema que planteaba sukhur es lo mismo que se ha dicho con el ejemplo de la ventana: estaba metiendo varias cosas diferentes (Camiones y Motos) en un contenedor que tenia cosas de la clase base (Vehiculos). La ventana es igual porque tiene un contendor de controles pero en realidad dentro hay muchas cosas diferentes.

Pues en ese caso te toca castear. En el ejemplo de los Camiones y las Motos, si puedes modificar el código, pues podrías tomar como solución lo de la función virtual vacia (que a mi me sigue sin gustar), pero si no puedes el casteo no te lo quita nadie...

Un saludo!

Vicente

Edit: respecto a lo de Java, el caso que comentá Diferencial no es tan raro porque en Java para declarar un manejador de eventos te toca declarar una clase entera (no como en .NET), con lo cual no es raro declarar una clase con el actionListener y hacer un switch muy grande por el tipo, nombre o lo que sea del control para diferenciarlo. Porque si no si tienes 10 botones te tocaría declarar 10 clases (sin meternos en que podrías usar clases anónimas para implementar el listener).

Para hacer lo de los botones según el lenguaje hay mecanismos mas simples y mas rapidos. Por ejemplo en Delphi está el tag. Eso mismo puedes implementarlo en todos los demás. O las listas de comportamiento (q normalmente es lo q mucha gente hace para no tener q estar metiendo bucles en todos sitios para recorrer los controles de la pantalla y tenerlo todo centralizado).

En cuanto a lo de Java .... pues a mi no me ha hecho falta nunca un getType para implementar lo q dices. Xq cuando hay pocos contrales le pones a cada uno su EventListener q como bien sabrás es q en algunos casos como por ejemplo una barra de desplazamiento o un deslizador no te qda otra (xq además clarifica mucho más el código) pero es q en el caso de q quieras reducir el número lo q he visto muchas veces hecho (aunq yo no lo hago xq EN MI OPINIÓN enchocha mucho el código y lo q es peor no te deja reutilizarlo), pero repito lo q normalmente he visto hecho es crear un eventlistener del tipo q te haga falta para botones y luego solo tienes q identificar cual es y asi para cada tipo de control. Aunq para mi eso vale si solo tienes una pantallita (una aplicaciíon de una pantallita). Si tienes bastantes yo los hago uno a uno xq normalmente siempre una cosa te vale para otra y he podido siempre reusar mucho código definiendo un eventlistener propio para un tipo de control y o biuen creándome el control con ese eventlistener ya implementado como una clase nueva o bien creando el comportamiento si lo quiero implmentar en mas de un sitio xq es raro q no se repitan entradas de datos, etc en una aplicación y como tú dices habrái q copiar y pegar o reescribir continuamente el código amén de lo de RTTI (q es casi lo de menos)). Ejemplo a esto : una entrada en un text_box de un tipo de dato característico para validarlo y demás (una clave, una fecha (para controlar q se te mete con una máscara) etc...) ... Y asi todo. No hace falta para nada en ese caso. De hecho PARA MI lo único q hace es liar el tema programar asi.
Título: C++ y POO
Publicado por: Vicente en 09 de Enero de 2007, 11:15:16 AM
Lo de los botones supongo que te refieres a los TextBox del ReadOnly, y es solo un ejemplo, ejeeeemplo. Seguramente Jare con lo del "saber si un objeto tiene una propiedad" lo ha explicado mejor que yo.

[OT]
Respecto a lo de Java: reconozco que no recuerdo mucho Java porque hace años que no lo toco. Pero, si tienes 10 botones tus alternativas son (quitando las clases internas):

A) hacer 10 actionsListeners para ellos (usease declararte 10 clases, instanciar y levantar 10 clases en memoria, tener 10 ficheros de java más por ahí danzando, etc etc etc).
B) hacer 1 actionListener y dentro de ese actionListener tener un switch que diferencia entre los 10 botones (por nombre o como sea).
C) algo entre medias.

Lo de que el caso B solo vale para aplicaciones de una pantallita pues ni idea, porque nunca he hecho nada especialmente grande en Java. Pero vamos, el caso A no es precisamente barato...
[/OT]

Un saludo!

Vicente
Título: C++ y POO
Publicado por: Diferencial en 09 de Enero de 2007, 11:28:19 AM
Vicente mejor explicado imposible
Título: C++ y POO
Publicado por: Fran en 09 de Enero de 2007, 11:40:47 AM
Cita de: "Vicente"Lo de los botones supongo que te refieres a los TextBox del ReadOnly, y es solo un ejemplo, ejeeeemplo. Seguramente Jare con lo del "saber si un objeto tiene una propiedad" lo ha explicado mejor que yo.

[OT]
Respecto a lo de Java: reconozco que no recuerdo mucho Java porque hace años que no lo toco. Pero, si tienes 10 botones tus alternativas son (quitando las clases internas):

A) hacer 10 actionsListeners para ellos (usease declararte 10 clases, instanciar y levantar 10 clases en memoria, tener 10 ficheros de java más por ahí danzando, etc etc etc).
B) hacer 1 actionListener y dentro de ese actionListener tener un switch que diferencia entre los 10 botones (por nombre o como sea).
C) algo entre medias.

Lo de que el caso B solo vale para aplicaciones de una pantallita pues ni idea, porque nunca he hecho nada especialmente grande en Java. Pero vamos, el caso A no es precisamente barato...
[/OT]

Un saludo!

Vicente

Posyasta. Sigo sin tener razones objetivas para convencerme (y si he puesto bibliografia de prestigio q lo contraria) pero esto ha degenerado a una conversación de besugos (en los q me incluyo) en los q se ponen ejemplos de Java y no te acuerdas como funciona q no tiene nada q ver con lo primario. Los q querais usar RTTi hacedlo y ya está. A mi no me gusta y punto. Creo q hay modos menos costosos y más flexibles de hacerlo . Y aun asi si alguna vez tengo q hacerlo no tengo ningun problema en usarlo sin decir q es una patata.

Bye
Título: C++ y POO
Publicado por: chan en 10 de Enero de 2007, 04:32:11 PM
Creo que en general os estáis ofuscando un poco casi todos, es decir, yo creo que no existe una fórmula mágica que funcione perfectamente para todos los casos, por lo que en algunos será necesario utilizar RTTi y en otros será más aconsejable utilizar métodos virtuales.

Yo, viendo el problema y algunas respuestas que se han dado, tengo una duda:

1. Tenemos una clase base vehiculo.
2. Tenemos clases heredadas como moto, que implementan propiedades y funcionalidades que no existen en vehiculo.

,bien, si declaramos una variable de tipo vehiculo e intentamos agregarle los valores de moto (haciendo el casting correspondiente), ¿como%&%$ vamos a conservar los valores de la clase ampliada, si simplemente no existen en la clase padre a la que la estamos asignando?, es decir, de que sirve hacer ésto:

vehiculo v[0]= new moto('SE-3212-RR',105, 'Manillar aluminio',......);

, si dentro de vehiculo no vamos a poder contener algunas de las propiedades de moto, como por ejemplo el tipo de manillar='Manillar aluminio'.

Para lo único que veo útil en éste caso usar RTTi, es para hacer alguna operación básica común a todos los elementos que implementen a vehiculo, y creo que eso no es lo que se proponía en el problema; simplemente éste hombre tendrá que declararse tantos tipos como distintos objetos quiera instanciar: Moto miMoto; coche miCoche; ....
Título: C++ y POO
Publicado por: fiero en 10 de Enero de 2007, 05:00:45 PM
Hola chan,
El vector v es de punteros, no de clases.

saludos
Título: C++ y POO
Publicado por: chan en 10 de Enero de 2007, 05:30:15 PM
Citar
El vector v es de punteros, no de clases.

... por lo que al hacer la asignación realmente estamos guardando la dirección de memoria que hace referencia al objeto moto, y para poder usar sus métodos se le hace el casting:

(moto)v[0]->getTipoManillar();  

es eso, no?
Título: C++ y POO
Publicado por: fiero en 10 de Enero de 2007, 06:27:55 PM
Cita de: "chan"... por lo que al hacer la asignación realmente estamos guardando la dirección de memoria que hace referencia al objeto moto, y para poder usar sus métodos se le hace el casting:

(moto)v[0]->getTipoManillar();  

es eso, no?



((moto*)v[0])->getTipoManillar();
Título: C++ y POO
Publicado por: Pogacha en 10 de Enero de 2007, 11:08:51 PM
La POO se basa en llevar el problema a los dominios de la mente y no a los dominios de la codificación.
Un mensaje el cual debe ser referido a un tipo especifico hecho a un tipo generico es romper con la POO.
Preguntar que cilindrada tiene un vehiculo es romper con la POO.
Saludos
Título: C++ y POO
Publicado por: chan en 11 de Enero de 2007, 09:14:19 AM
ok, gracias por la aclaración fiero
Título: C++ y POO
Publicado por: Jare en 11 de Enero de 2007, 03:54:09 PM
Cita de: "Pogacha"La POO se basa en llevar el problema a los dominios de la mente y no a los dominios de la codificación.
:shock: Eso no tiene ningun sentido, y el que "pretende" tener no es cierto.
Título: C++ y POO
Publicado por: zupervaca en 11 de Enero de 2007, 06:33:42 PM
CitarPreguntar que cilindrada tiene un vehiculo es romper con la POO
Efectivamente, es lo que se lleva intentando explicar desde unas cuantas paginas, como dije anteriormente en este caso no queda mas "webs" que saber que tipo de objeto se esta tratando, pero este caso es imposible de encontrar en un proyecto real, sobre todo si tienes via libre para hacerlo como tu quieras.
Creo que el hilo no va a evolucionar mucho mas ya que ambos bandos tienen razon, por lo menos desde mi punto de vista, ademas si vierais el codigo final con el que se trabaja en una empresa no le dariais mucha importancia a esto :lol:
Título: C++ y POO
Publicado por: marcode en 11 de Enero de 2007, 08:47:43 PM
Yo creo que el ejercicio de sukhur es Programación Orientada a Objeto (uno solo).
Título: C++ y POO
Publicado por: shephiroth en 12 de Enero de 2007, 03:04:07 AM
Me parece asombroso que haya gente que siga pensando que RTTI es mejor que POO. Hay casos en los que RTTI es necesario (como ejemplo, los scripts q me deciais), pero no os empeñeis.

El ejercicio tal cual se puso no es que estuviera mal planteado, sino mal interpretado, y me explico. Si para lo unico q quiere los valores internos es para mostrarlos, es suficiente con que en la clase base haya una funcion virtual mostrar_reporte. Y nos olvidamos de rtti...un for y usar la virtual y a correr.

Respecto a algunos que os parece mal dejar funciones virtuales vacias, o poner funciones virtuales que solo utiliza una clase hija...y os parece bien una funcion virtual gettype que puede ser que nunca se use?? Me parece que es una idea un poco corta. Para que lo veais claro, se podrían utilizar los controles de un formulario. Anda que no hay eventos y eventos, cantidad de funciones virtuales que se dejan a expensas de que el usuario final pueda si quiere sobreescribir esos metodos y utilizarlos. A ver quien te dice a ti que aunque tu solo has usado esa funcion virtual en una clase hija, al futuro programador le viene de perlas y TODAS las hijas que crea utilizan dichas funciones.

No me quiero extender mas, e insisto RTTI sirve para lo q sirve, pero no es fundamental para POO, es necesario para lo q se necesita.

SALUDOS ^^
Título: C++ y POO
Publicado por: jaure en 12 de Enero de 2007, 09:06:44 AM
Cita de: "shephiroth"Me estas diciendo que los compiladores de c solo compilan lo que utilizas en vez de todo el codigo?? Bueno saberlo :)

P.D: Actualmente no estdio c en la uni, sino component pascal y java.


Tu estudias en la EUPLA?

Porque solo conozco a unos que en España usen componet pascal
Título: C++ y POO
Publicado por: Vicente en 12 de Enero de 2007, 09:30:53 AM
Cita de: "shephiroth"Para que lo veais claro, se podrían utilizar los controles de un formulario. Anda que no hay eventos y eventos, cantidad de funciones virtuales que se dejan a expensas de que el usuario final pueda si quiere sobreescribir esos metodos y utilizarlos.

[OT]Si hablas de los eventos de .NET, no tienen nada que ver. Un evento es un "wrapper" sobre un delegado multicast, y un delegado es una declaración de un tipo. Nada de una función virtual vacia para sobreescribir...[/OT]

Un saludo!

Vicente
Título: C++ y POO
Publicado por: Fran en 12 de Enero de 2007, 10:15:19 AM
Cita de: "shephiroth"Me parece asombroso que haya gente que siga pensando que RTTI es mejor que POO. Hay casos en los que RTTI es necesario (como ejemplo, los scripts q me deciais), pero no os empeñeis.

El ejercicio tal cual se puso no es que estuviera mal planteado, sino mal interpretado, y me explico. Si para lo unico q quiere los valores internos es para mostrarlos, es suficiente con que en la clase base haya una funcion virtual mostrar_reporte. Y nos olvidamos de rtti...un for y usar la virtual y a correr.

Respecto a algunos que os parece mal dejar funciones virtuales vacias, o poner funciones virtuales que solo utiliza una clase hija...y os parece bien una funcion virtual gettype que puede ser que nunca se use?? Me parece que es una idea un poco corta. Para que lo veais claro, se podrían utilizar los controles de un formulario. Anda que no hay eventos y eventos, cantidad de funciones virtuales que se dejan a expensas de que el usuario final pueda si quiere sobreescribir esos metodos y utilizarlos. A ver quien te dice a ti que aunque tu solo has usado esa funcion virtual en una clase hija, al futuro programador le viene de perlas y TODAS las hijas que crea utilizan dichas funciones.

No me quiero extender mas, e insisto RTTI sirve para lo q sirve, pero no es fundamental para POO, es necesario para lo q se necesita.

SALUDOS ^^

Totalmente de acuerdo. En mi caso esta forma tan OOP de hacer las cosas   me ha salvado mil millones de veces el cuerpo en PROGRAMACION REAL Y PROFESIONAL. No en programitas de voy a intentar hacerme mi MMORPG. Siempre y cuando digo siempre quiero decir sin excepción hay comportamientos no previstos (estilo esto quiero q lo haga igual q aqui, se me ha olvidado una entidad q es igual q esta,.... etc ) por el cliente, que este tipo de cosas te ayudan a solventar de una manera transparente y sencilla sin tener que retocar todo el programa. Además como bien dices, por ejemplo los eventos vacios para si quieres meter algo imagino q a los detractores de hacer cosas asi , les tienen que chirriar. A mi la programación hecha así, aprovechando con miras amplias y no con miras cortas la OOP me parece lo mejor del mundo. Por cierto , habeis oido hablar alguna vez del principio abierto-cerrado de Meyer? Y del de sustitucion de Liskov?

El de abierto cerrado dice que se puede cambiar un módulo sin cambiarlo. La clave es la abstracción. Los cambios en un sistema se hacen por este principio siempre añadiendo código. No cambiándolo. Este es uno de los principios básicos de la OOP. Y cualquier sistema q no cumpla esto está mal diseñado.

http://www.eventhelix.com/RealtimeMantra/Object_Oriented/open_closed_principle.htm

El de Liskov dice q cualquier cosa (sobre todo métodos) en una clase q tenga q ser consciente de qué clase es para poder funcionar viola este principio. Es antiOOP.

Pues miradlos y decidme q principios violan el hacerlo como decimos y no con RTTI xq la solucion RTTI viola unos cuantos principios de teóricos de la OOP como esos.

Como veis yo sigo dando teoria aceptada por todo el mundo. A ver si variais y dais teoria y no poesia ni ejemplos sin sentido. Esto es un debate  teórico. Asi q si quereis seguir seamos serios y aportemos teoría y pruebas q contradigan no opiniones ni ejemplos enrevesados que al final derivan en q no me acuerdo de esto. Si alguien quiere darlos q los formule  q se entiendan con mirarlos. No sean estilo la parte contratante de la primera parte...

Saludos :lol:
Título: C++ y POO
Publicado por: jaure en 12 de Enero de 2007, 10:47:26 AM
Creo que hay tonos un poco salidos de madre, nadie aquí tiene que demostrar nada al otro en cuestión de si se es mejor o peor programador.

Un poco más de humildad no viene mal, el mundo sería mejor.
Título: C++ y POO
Publicado por: Fran en 12 de Enero de 2007, 10:59:42 AM
Cita de: "jaure"Creo que hay tonos un poco salidos de madre, nadie aquí tiene que demostrar nada al otro en cuestión de si se es mejor o peor programador.

Un poco más de humildad no viene mal, el mundo sería mejor.

¿? No creo q aquí se trate de demostrar nada acerca de lo peor o mejor programador que se sea. De hecho hay gente escribiendo aquí a la q considero buena programadora por los trabajos q he visto. Simplemente se ha establecido un debate teórico acerca de un tema, desde el lado del RTTI se "dispararon" dos sentencias al principio del hilo : eso es una patata, y eso no es OOP y me he cansado de escribir y de demostrar mediante teoría q no lo es y q además lo q no es OOP es la RTTI. Lo "gracioso" de esto es q tengo claro q la otra gente no va a cambiar ni a dar brazo a torcer ni yo voy a cambiar de manera de programar (xq además de q me ha dado durante 13 años muy buen resultado, tengo claro q estoy en estandares). Pero bueno. Como entretenimiento las "tertulias" estan muy bien. En cualquier caso si he ofendido a alguien, pido disculpas.
Título: C++ y POO
Publicado por: Vicente en 12 de Enero de 2007, 11:10:31 AM
Cita de: "Fran"Asi q si quereis seguir seamos serios y aportemos teoría y pruebas q contradigan no opiniones ni ejemplos enrevesados que al final derivan en q no me acuerdo de esto.

Me doy por aludido :p Te invito a que me corrijas el ejemplo si estaba mal (así refresco mi Java). Si no respondes supongo que estará bien...

Respecto a los eventos, ya os he dicho que en .NET no son funciones vacias, son declaraciones de tipos, como quien declara:

private int i;

Eso es un evento en .NET (más o menos, si os interesa http://www.codeproject.com/useritems/howeventswork.asp es una buena explicación). Así que no me chirria, porque no declaran una función virtual vacia para que sobreescriba alguien.

Un saludo!

Vicente
Título: C++ y POO
Publicado por: Fran en 12 de Enero de 2007, 11:20:16 AM
Cita de: "Vicente"
Cita de: "Fran"Asi q si quereis seguir seamos serios y aportemos teoría y pruebas q contradigan no opiniones ni ejemplos enrevesados que al final derivan en q no me acuerdo de esto.

Me doy por aludido :p Te invito a que me corrijas el ejemplo si estaba mal (así refresco mi Java). Si no respondes supongo que estará bien...

Respecto a los eventos, ya os he dicho que en .NET no son funciones vacias, son declaraciones de tipos, como quien declara:

private int i;

Eso es un evento en .NET (más o menos, si os interesa http://www.codeproject.com/useritems/howeventswork.asp es una buena explicación). Así que no me chirria, porque no declaran una función virtual vacia para que sobreescriba alguien.

Un saludo!

Vicente

El ejemplo "me se" escapa ... :lol: No entiendo que tiene q ver con esto. Y no digo q no tenga nada q ver, digo q no veo YO la conexión. Pero desde luego es un buen ejemplo del principio abierto cerrado. Lo poco q he visto de C# me gusta.En cuanto a Java ya te dije que no he visto a nadie declarar una sola clase para todos los eventos de todos los controles de una pantalla. Xq si tienes 100 controles
a) Es un chocho
b) Es dificil q no se puede reusar codigo de esa o de otras pantallas.

En su lugar  se declara o reutiliza clase por evento o bien si es q no te gusta eso ( a mí si xq te permite reutilizar) declaras un evento para cada tipo de control y despues los refieres por el nombre. No hace falta para nada el casting.

Y por cierto, no todo va a ser debate, cuando digo que sé de programadores en este hilo a los que considero buenos ( y tengo claro q lo q yo considere no vale para nada) me refiero especialmente a ti y a tu trabajo en Hadd. Creo q estais haciendo un gran trabajo.
Título: C++ y POO
Publicado por: Vicente en 12 de Enero de 2007, 11:59:50 AM
Cita de: "Fran"El ejemplo "me se" escapa ... :lol: No entiendo que tiene q ver con esto. Y no digo q no tenga nada q ver, digo q no veo YO la conexión. Pero desde luego es un buen ejemplo del principio abierto cerrado.

El ejemplo venía a que con lo que hablábamos de RTTI al principio de los vehículos, necesitas hacer un if (o un switch -> if (tipo = TIPO) then...), igual que si declararas todos los controles al mismo listener (donde para saber que control realmente usaste tendrás que hacer un switch por el nombre del control o algo así para diferenciarlos).

El manejador realmente puede estar en otro sitio, simplemente en ese switch se pone la llamada a la función. La cosa es que por como es Java (o por como yo recuerdo que Java funcionaba), 100 controles manejados a la forma "POO pura" serían 100 ficheros, 100 clases,... Con lo cual ya no tengo tan claro que sea la mejor solución (desde el punto de vista teórico sí, desde el punto de vista de implementación ni idea porque no programo en Java :p).

Cita de: "Fran"En su lugar  se declara o reutiliza clase por evento o bien si es q no te gusta eso ( a mí si xq te permite reutilizar) declaras un evento para cada tipo de control y despues los refieres por el nombre. No hace falta para nada el casting.

El if por el nombre es lo mismo que el if por el tipo, solo que por otra propiedad, pero estamos en las mismas, necesitas alguna forma de diferenciar algo.

Cita de: "Fran"Y por cierto, no todo va a ser debate, cuando digo que sé de programadores en este hilo a los que considero buenos ( y tengo claro q lo q yo considere no vale para nada) me refiero especialmente a ti y a tu trabajo en Hadd. Creo q estais haciendo un gran trabajo.

Gracias :) Ahora solo falta que lo use la gente :p

Pero bueno, está claro que para gustos colores, lo mismo en C++ se usan las funciones virtuales porque el lenguaje es más propenso a eso, y a mi que estoy en C# me choca muchísimo... Un saludo!

Vicente
Título: C++ y POO
Publicado por: shephiroth en 12 de Enero de 2007, 01:26:53 PM
Cita de: "jaure"Tu estudias en la EUPLA?
Porque solo conozco a unos que en España usen componet pascal
Es evidente que si...y no se si tomarmelo a bien o a mal ^^;

Cita de: "Vicente"[OT]Si hablas de los eventos de .NET, no tienen nada que ver. Un evento es un "wrapper" sobre un delegado multicast, y un delegado es una declaración de un tipo. Nada de una función virtual vacia para sobreescribir...[/OT]
Totalmente cierto, pero hablamos de cosas diferentes. Los delegados son funciones miembros tipadas (espero haberme explicado). Me imagino que habras querido decir lo mismo con wrapper, pero esq no tengo ni idea de que es un wrapper...pero a lo que iva. No me refiero al las funciones que enlazas cuando creas un evento. Sino a todos los eventos PREDEFINIDOS en muchas clases .NET. Yo como utilizo winforms pues os hablo de lo que conozco, en MFC no se si rulara igual. En todos los controles (heredando de Control...q raro, verdad?? xDD) existen eventos predefinidos, que no tienes q tipar tu sino q estan ya creadas, y que la clase base se encarga de utilizar. Me estoy refiriendo a todas las funciones virtuales que empiezan por On.... Por ejemplo, si en vez de utilizar un ListBox, te creas una clase MiListBox, puedes utilizar la funcion OnChangeSelectedItem para recoger el evento SIN TENER QUE EXPECIFICARL EN NINGUN SITIO!!! Me referia a estas funciones virtuales.

Por cierto, q no son explusivas de los winforms. He trabajado un poco con sockets y las clases de sockets de .NET trabajan con los On. Seguro que .NET es mucho mas amplio y muchas mas clases utilizan este sistema.

Cita de: "Fran"El de Liskov dice q cualquier cosa (sobre todo métodos) en una clase q tenga q ser consciente de qué clase es para poder funcionar viola este principio. Es antiOOP.

Pues miradlos y decidme q principios violan el hacerlo como decimos y no con RTTI xq la solucion RTTI viola unos cuantos principios de teóricos de la OOP como esos.
Estoy deacuerdo en casi todo tu post, pero hay una cosa con la que no estoy deacuerdo. RTTI es util en algunos casos. Sobre que rtti viola principios teoricos de poo...cierto, los viola en las mayoria de los casos pero no en todos. Como dije en mi primer post (aunque en un tono desafortunado) hay mucha gente que se ha "mal-viciado" con su uso y ahora lo ven como una herramienta imprescindible, y ese es el error. Es util pero no imprescindible. Lo imprescindible es que disciernan entre "es una solucion" y "es la unica solucion", que no por llevarlo usando años significa que sea mejor (sino ande vamos a ir con el progreso xDD).

Cita de: "Fran"
Cita de: "jaure"Creo que hay tonos un poco salidos de madre, nadie aquí tiene que demostrar nada al otro en cuestión de si se es mejor o peor programador.

Un poco más de humildad no viene mal, el mundo sería mejor.

¿? No creo q aquí se trate de demostrar nada acerca de lo peor o mejor programador que se sea. De hecho hay gente escribiendo aquí a la q considero buena programadora por los trabajos q he visto. Simplemente se ha establecido un debate teórico acerca de un tema, desde el lado del RTTI se "dispararon" dos sentencias al principio del hilo : eso es una patata, y eso no es OOP y me he cansado de escribir y de demostrar mediante teoría q no lo es y q además lo q no es OOP es la RTTI. Lo "gracioso" de esto es q tengo claro q la otra gente no va a cambiar ni a dar brazo a torcer ni yo voy a cambiar de manera de programar (xq además de q me ha dado durante 13 años muy buen resultado, tengo claro q estoy en estandares). Pero bueno. Como entretenimiento las "tertulias" estan muy bien. En cualquier caso si he ofendido a alguien, pido disculpas.
Para jaure, si lo dices por mi primera respuesta en el post tienes toda la razon, pero te pediria que leyeses todo el post, en la tercera o cuarta pagina me disculpe por eso mismo. Si no lo dices por ese post, estoy totalmente deacuerdo con vicente...se ha planteado un debate que es bastante interesante. Sobre que nadie llegue a entender al otro...creo que te equivocas. Yo estoy aprendiendo mucho. Sigo defendiendo que OOP es mucho mejor que RTTI, pero no por eso no estoy aprendiendo.

SALUDOS ^^
Título: C++ y POO
Publicado por: jaure en 12 de Enero de 2007, 01:58:25 PM
Cita de: "shephiroth"
Cita de: "jaure"Tu estudias en la EUPLA?
Porque solo conozco a unos que en España usen componet pascal
Es evidente que si...y no se si tomarmelo a bien o a mal ^^;

Cita de: "Vicente"[OT]Si hablas de los eventos de .NET, no tienen nada que ver. Un evento es un "wrapper" sobre un delegado multicast, y un delegado es una declaración de un tipo. Nada de una función virtual vacia para sobreescribir...[/OT]
Totalmente cierto, pero hablamos de cosas diferentes. Los delegados son funciones miembros tipadas (espero haberme explicado). Me imagino que habras querido decir lo mismo con wrapper, pero esq no tengo ni idea de que es un wrapper...pero a lo que iva. No me refiero al las funciones que enlazas cuando creas un evento. Sino a todos los eventos PREDEFINIDOS en muchas clases .NET. Yo como utilizo winforms pues os hablo de lo que conozco, en MFC no se si rulara igual. En todos los controles (heredando de Control...q raro, verdad?? xDD) existen eventos predefinidos, que no tienes q tipar tu sino q estan ya creadas, y que la clase base se encarga de utilizar. Me estoy refiriendo a todas las funciones virtuales que empiezan por On.... Por ejemplo, si en vez de utilizar un ListBox, te creas una clase MiListBox, puedes utilizar la funcion OnChangeSelectedItem para recoger el evento SIN TENER QUE EXPECIFICARL EN NINGUN SITIO!!! Me referia a estas funciones virtuales.

Por cierto, q no son explusivas de los winforms. He trabajado un poco con sockets y las clases de sockets de .NET trabajan con los On. Seguro que .NET es mucho mas amplio y muchas mas clases utilizan este sistema.

Cita de: "Fran"El de Liskov dice q cualquier cosa (sobre todo métodos) en una clase q tenga q ser consciente de qué clase es para poder funcionar viola este principio. Es antiOOP.

Pues miradlos y decidme q principios violan el hacerlo como decimos y no con RTTI xq la solucion RTTI viola unos cuantos principios de teóricos de la OOP como esos.
Estoy deacuerdo en casi todo tu post, pero hay una cosa con la que no estoy deacuerdo. RTTI es util en algunos casos. Sobre que rtti viola principios teoricos de poo...cierto, los viola en las mayoria de los casos pero no en todos. Como dije en mi primer post (aunque en un tono desafortunado) hay mucha gente que se ha "mal-viciado" con su uso y ahora lo ven como una herramienta imprescindible, y ese es el error. Es util pero no imprescindible. Lo imprescindible es que disciernan entre "es una solucion" y "es la unica solucion", que no por llevarlo usando años significa que sea mejor (sino ande vamos a ir con el progreso xDD).

Cita de: "Fran"
Cita de: "jaure"Creo que hay tonos un poco salidos de madre, nadie aquí tiene que demostrar nada al otro en cuestión de si se es mejor o peor programador.

Un poco más de humildad no viene mal, el mundo sería mejor.

¿? No creo q aquí se trate de demostrar nada acerca de lo peor o mejor programador que se sea. De hecho hay gente escribiendo aquí a la q considero buena programadora por los trabajos q he visto. Simplemente se ha establecido un debate teórico acerca de un tema, desde el lado del RTTI se "dispararon" dos sentencias al principio del hilo : eso es una patata, y eso no es OOP y me he cansado de escribir y de demostrar mediante teoría q no lo es y q además lo q no es OOP es la RTTI. Lo "gracioso" de esto es q tengo claro q la otra gente no va a cambiar ni a dar brazo a torcer ni yo voy a cambiar de manera de programar (xq además de q me ha dado durante 13 años muy buen resultado, tengo claro q estoy en estandares). Pero bueno. Como entretenimiento las "tertulias" estan muy bien. En cualquier caso si he ofendido a alguien, pido disculpas.
Para jaure, si lo dices por mi primera respuesta en el post tienes toda la razon, pero te pediria que leyeses todo el post, en la tercera o cuarta pagina me disculpe por eso mismo. Si no lo dices por ese post, estoy totalmente deacuerdo con vicente...se ha planteado un debate que es bastante interesante. Sobre que nadie llegue a entender al otro...creo que te equivocas. Yo estoy aprendiendo mucho. Sigo defendiendo que OOP es mucho mejor que RTTI, pero no por eso no estoy aprendiendo.

SALUDOS ^^

Aquí, otro que ha ido allí, hace ya unos cuantos años, cuando empezo a hacerse algo con Java, pero mis prácticas de 1º eran integramente en component pascal y su blackbox (dios que quebraderos de cabeza...)

Hombre, a mal tampoco, hay mucho que raja de la EUPLA mal, yo hay cosas que no me gustaban, y sobre todo lo de los autobuses.

Me imagino que Falces seguirá por allí, y el de Sistemas lógicos, también tengo buenos recuerdos de ellos. Hay uno de Algebra que mejor no me lo encuentre por la calle.

Hombre no va para nadie concreto, solo que la discusión es interesante, y ver los argumentos de cada uno está bien, tengo claro que hay que usar ambas cosas dependiendo del caso, depende de lo que te quieras montar, hay veces que no merce la pena matarse mucho la cabeza, y otras es mejor hechar el resto y currarselo uno mucho para evitar luego quebraderos de cabeza ante posibles cambios.

Leí practicamente todo el post, y vi tus disculpas, solo es que en estos post enseguida se puede entrar en lo personal con comentarios que coloquialmente en persona no tienen trascendencia, pero escritos suele sonar todo más duro, o mal interpretarse.

Pero os aseguro que es interesante lo que decís, y que es verdad que de vez en cuando hay que repasar las bases de la POO, porque se cogen vicios del día a día, y de trabajar en proyectos que han sido programados y reprogramados 20 veces por diferentes personas, y hay que volver a los "origenes" de vez en cuando, para depurar estilo.

saludos
Título: C++ y POO
Publicado por: Vicente en 12 de Enero de 2007, 02:02:23 PM
Cita de: "shephiroth"Sino a todos los eventos PREDEFINIDOS en muchas clases .NET. Yo como utilizo winforms pues os hablo de lo que conozco, en MFC no se si rulara igual. En todos los controles (heredando de Control...q raro, verdad?? xDD) existen eventos predefinidos, que no tienes q tipar tu sino q estan ya creadas, y que la clase base se encarga de utilizar. Me estoy refiriendo a todas las funciones virtuales que empiezan por On.... Por ejemplo, si en vez de utilizar un ListBox, te creas una clase MiListBox, puedes utilizar la funcion OnChangeSelectedItem para recoger el evento SIN TENER QUE EXPECIFICARL EN NINGUN SITIO!!! Me referia a estas funciones virtuales.

Mmm, las funciones On no son eventos, lo que hacen es lanzar eventos (supongo que lo que harán es un if (Evento != null) Evento(e); pero tampoco me he puesto a desensamblar eso). Y no son métodos vacios (ya que hacen cosas).

Además, siguiendo con el tema, si te fijas, Control no define OnSelectedItemIndexChange (por ejemplo), si no que está definido a nivel de ListControl (la clase común para el ListBox y el ComboBox).

Esto es: en el framework de .NET, la función virtual OnSelectedItemIndexChange no está definida como vacía en Control y luego en ListControl ya se la sobreescribe con código. Está declarada directamente en ListControl, y si tienes un Control, no puedes acceder a ella sin un cast. No me meto en que sea mejor ni peor, simplemente digo que está hecho así.

Un saludo!

Vicente
Título: C++ y POO
Publicado por: Fran en 12 de Enero de 2007, 02:29:31 PM
[shephiroth]

Estoy deacuerdo en casi todo tu post, pero hay una cosa con la que no estoy deacuerdo. RTTI es util en algunos casos. Sobre que rtti viola principios teoricos de poo...cierto, los viola en las mayoria de los casos pero no en todos. Como dije en mi primer post (aunque en un tono desafortunado) hay mucha gente que se ha "mal-viciado" con su uso y ahora lo ven como una herramienta imprescindible, y ese es el error. Es util pero no imprescindible. Lo imprescindible es que disciernan entre "es una solucion" y "es la unica solucion", que no por llevarlo usando años significa que sea mejor (sino ande vamos a ir con el progreso xDD).

[\shephiroth]

Llevo diciendo todo el post q hay algunos casos en los q es casi inevitable. (Sobre todo cuando te falta tiempo para corregir una metida de pata muchas veces). Pero  PARA MI es un vicio adquirido de quien ha pasado de Estructura pura a OOP. Ya todo lo ve como un clavo. No se molesta en ver si hay algo mas que martillos.
Título: C++ y POO
Publicado por: shephiroth en 12 de Enero de 2007, 04:54:09 PM
Jaure:
Si, eduardo y jabo siguen dando clases xDD. Respecto a Algebra, llamalo casualidad, pero es la unica asignatura que no tengo el nombre del profesor xDD. Respecto a quebraderos de cabeza, despues de cobol el component pascal no es tan complicado.

Vicente:
Tienes razon, no todos los On se heredan directamente de Control. Estuve hablando de varias cosas y las lie. Con los metodos vituales On me referia a la "historia" de poner metodos virtuales vacíos...alguien comento que era mala idea eso de ir dejando metodos virtuales vacíos, y es un ejemplo muy claro de la funcionalidad y utilidad de los metodos virtuales.

Fran:
Creo q pensamos lo mismo ^_^
Título: C++ y POO
Publicado por: zupervaca en 12 de Enero de 2007, 06:49:20 PM
Este hilo es la caña jeje, sigo pensando que los dos bandos teneis razon a vuestra manera, ejemplo: si juntamos churros con merinas (o como decis algunos por aqui) el gettype es necesario, pero no por ello el usar funciones virtuales vacias esta mal, ya que como se ha dicho si el objetivo del ejercicio es mostrar en pantalla los valores se podria hacer una funcion virutal pura en la clase base que fuera pintar datos de la de clase.
He estado mirando codigo de la libreria multiplataforma que tengo ya que yo me acordaba de que en algun sitio tenia funciones virtuales vacias, es en la clase Texture de direct3d9, el motivo es que para opengl me hacia falta un par de eventos cuando se cambia la calidad de la textura, pero en direct3d9 no me hace falta, no obstante son dos funciones (eventos) que tienen algo en comun, que es algo totalmente diferente a tener una funcion virtual preguntando si un coche tiene manillar.
En definitiva creo que la base de la programacion orientada a objetos es que las clases bases desconocen a sus hijas y segun se van creando clases hijas las bases las desconocen aun mas, ademas cuando una clase base es creada y dada por finiquitada nunca mas se vuelve a tocar con lo que si se agrega un nuevo vehiculo preguntando si tiene alas al tocar la clase base estariamos rompiendo con esta filosofia (que no tiene por que ser la correcta tampoco :wink:)

Un claro ejemplo de juntar churros con merinas es meter los enemigos en la misma lista que los jugadores, si se hace esto no queda mas remedio que usar gettytpe, en cambio la forma correcta es poner una lista de enemigos y otra de jugadores. (Aunque si nos ponemos tontos podemos hacer una clase base que sepa controlar enemigos y jugadores sin gettype, es solo para un ejemplo).
Si se tiene una lista de enemigos individual se podran sacar funciones y eventos comunes para ellos y como es logico algun enemigo puede tener un evento vacio ya que puede que no tenga que hacer nada en ese caso, por ejemplo: un enemigo tiene movimiento y otro siempre esta estatico, en el evento de OnMove uno tendria codigo y el otro no, es decir, uno tiene la funcion virtual con codigo y el otro sin nada.
Ya para terminar, lo que quiero decir es que gettype se usa en casos muy raros y la mayoria de las veces por un mal plateamiento y las funciones virtuales vacias estan bien, pero siempre y cuando sean cosas comunes para las clases hijas, por lo menos es mi forma de ver la poo.
Título: C++ y POO
Publicado por: marcode en 12 de Enero de 2007, 08:30:13 PM
Estaría bien que los detractores del GetType explicasen cómo se haría para seleccionar aquellos objetos que nos interesan, por ejemplo para mostrar las imágenes o sacar una media de precios de un determinado tipo de vehiculo, o ver un listado de las características de los vehículos sin que me diga que el maletero de una moto mide cero metros.
Título: C++ y POO
Publicado por: zupervaca en 12 de Enero de 2007, 08:35:28 PM
Cita de: "marcode"Estaría bien que los detractores del GetType explicasen cómo se haría para seleccionar aquellos objetos que nos interesan, por ejemplo para mostrar las imágenes o sacar una media de precios de un determinado tipo de vehiculo, o ver un listado de las características de los vehículos sin que me diga que el maletero de una moto mide cero metros.
Aun mejor, veamos si eres capaz de meter en la misma tabla de la base de datos para un tipo de vehiculos los centimetros del maletero y para otros no, la solucion a este problema (si se quieren meter varios tipos de vehiculos en la misma tabla como es el caso) es un campo en el que se indican las propiedades del vehiculo.
Ademas las consultas tipo listado en la bases de datos se hacen mediante controles tipo rejilla, que tenga o no centimetros de maletero la columna de centimetros del maletero estara ahi.
Creo que has buscado un mal ejemplo :wink:
Título: C++ y POO
Publicado por: marcode en 12 de Enero de 2007, 09:09:36 PM
Puse dos por si acaso  :wink:

El otro es que quieres obtener la media del precio de todos los vehiculos de la clase coche.

Por poner otro más raro, que haya que saber que vehículos tienen que pasar la ITV este año. Aquí dependiendo de un tipo u otro varía el periodo de revisión de cada uno. Seguro que se podrían poner otros en los que no queden más narices que saber con qué estás tratando.
Título: C++ y POO
Publicado por: Vicente en 12 de Enero de 2007, 09:34:29 PM
Cita de: "shephiroth"Jaure:
Vicente:
Tienes razon, no todos los On se heredan directamente de Control. Estuve hablando de varias cosas y las lie. Con los metodos vituales On me referia a la "historia" de poner metodos virtuales vacíos...alguien comento que era mala idea eso de ir dejando metodos virtuales vacíos, y es un ejemplo muy claro de la funcionalidad y utilidad de los metodos virtuales.

Yo, yo dije que era mala idea dejar métodos virtuales vacios :p (vamos a dejarlo en que a mi no me gusta eso para evitar volver a lo de siempre). Yo no tengo nada en contra de los métodos virtuales, solo de los que están vacios. Los OnNombreEvento que comentas, NO están vacios ;)

Yo lo veo como que cuando declaras un método abstracto o en una interfaz es porque ese método es común a todas las clases hijas (una interesección) y no a solo alguna clase hija (una unión).

De todas formas, fijate como cambian las mentalidades, en Java todo método es virtual por defecto, en cambio en .NET es justo al reves, para que sea virtual lo tienes que decir tu explícitamente...

Un saludo!

Vicente
Título: C++ y POO
Publicado por: zupervaca en 12 de Enero de 2007, 09:35:32 PM
Yo en vez de por tipo lo pondria por fecha, poniendo un campo fecha que indicara cuando pasar la itv, mas que nada por si acaso hay casos especiales. No obstante estas poniendo un ejercicio en el que indicas que por "webs" hay que saber el tipo de vehiculo que se quiere mostrar, con un ejercicio en el que se haga una busqueda por tipo de vehiculo ya tienes el campo tipo de vehiculo obligado, de hay que a mi me guste poner funcionalidad extra tipo getType aunque yo no vaya a usarla, yo es que realmente no veo el problema en tener getType y no usarlo y/o tener funciones virtuales vacias :?

Editado: Pero date cuenta que realizar una busqueda por tipo no tiene nada que ver con la poo.
Título: C++ y POO
Publicado por: shephiroth en 13 de Enero de 2007, 12:32:31 AM
Buenas.

Cita de: "marcode"Estaría bien que los detractores del GetType explicasen cómo se haría para seleccionar aquellos objetos que nos interesan, por ejemplo para mostrar las imágenes o sacar una media de precios de un determinado tipo de vehiculo, o ver un listado de las características de los vehículos sin que me diga que el maletero de una moto mide cero metros.
Para responderte a la pregunta en violeta hay una pregunta obligatoria, para qué necesitas los datos. Si los necesitas solo para mostrarlos en pantalla, una funcion virtual de mostrar. Si quieres operar solo con una de las clases hijas podrías usar una funcion estatica y que la clase tenga por medio de una lista dinamica o algo parecido consciencia de todos los objetos de dicha clase.

"un listado de las características de los vehículos sin que me diga que el maletero de una moto mide cero metros" acaso esto no es el enunciado perfecto de "funcion virtual y que hereden las hijas"?? Aclarate ;)

Aunque me repita lo siento, pero para responderte tienes q decir exactamente para qué necesitas esos datos. La mayoria de los problemas que planteais se pueden solucionar sin tener que usar rtti.

Cita de: "marcode"Puse dos por si acaso  :wink:

El otro es que quieres obtener la media del precio de todos los vehiculos de la clase coche.

Por poner otro más raro, que haya que saber que vehículos tienen que pasar la ITV este año. Aquí dependiendo de un tipo u otro varía el periodo de revisión de cada uno. Seguro que se podrían poner otros en los que no queden más narices que saber con qué estás tratando.

...me lo parece a mi o estas poniendo ejemplos de una POO CLARISIMA. Funcion virtual bool necesitaItv(); y con la variable int tiempoRevisionItv. Las hijas establecen el valor de tiempoRevisionItv, al tiempo que ponen el codigo que necesita para saber si necesita o no la itv...es mas, si la clase base tiene tanto el tiempoUltimaItv como tiempoRevisionItv no necesitarias nisiquiera redefinirla en las hijas xDD.
Título: C++ y POO
Publicado por: Jare en 13 de Enero de 2007, 03:52:29 AM
Cita de: "shephiroth"Si los necesitas solo para mostrarlos en pantalla, una funcion virtual de mostrar. Si quieres operar solo con una de las clases hijas podrías usar una funcion estatica y que la clase tenga por medio de una lista dinamica o algo parecido consciencia de todos los objetos de dicha clase.
¿Las clases de la jerarquía de vehiculos necesitan saber cómo queremos (y qué necesitamos para) pintarlas en pantalla? Creamos un acomplamiento extra con nuestro sistema de pintado, que no es muy agradable de cara a la reusabilidad.

"Pasale un interfaz a la función de pintar, y así tu te lo implementas para tus funciones de pintado concretas" dirá alguno. Pero claro, para que mi interfaz pueda recibir los datos de cualquiera de las clases para usarlos como YO quiera, la función "pintar" tendrá que pasarselos de alguna forma simbólica y genérica, por ejemplo un mapa indexado por cadenas del tipo "Cilindrada" y "Consumo". No es que sea muy óptimo...

Mi implementación del interfaz de pintado tendrá que ir consultando cada elemento del mapa de datos que me da el vehículo, y hacer un... ¿switch/case o cadena de IFs? Y eso aún sería fácil si todos los datos consultables son del mismo tipo, números por ejemplo. ¿Y si algunos son floats, otros cadenas, y otros son a su vez contenedores de otros objetos, por ejemplo el campo "Cargamento"?

Eso solamente para el problema de pintarlos. Si quiero hacer una "librería de vehiculos" para que otra gente la use, tengo que preveer todos los posibles usos que la gente querrá hacer con esos vehiculos, y preparar un interfaz para cada funcionalidad. Lo siento, pero mi bola de cristal está sin pilas.

La solución de implementar una lista estática que contenga las instancias de cada clase no es que ayude mucho, ya que:

- Introduce costes extras de gestión y memoria.

- Sólo tiene sentido en clases que no tengan a su vez otras derivadas (lo que podría no ser aplicable), ya que el mismo objeto aparecería en varias listas estáticas diferentes. También hace poco viable que yo derive nuevas clases especializadas a partir de las ya existentes. Supongo que los constructores de cada clase tendrán que recibir un parámetro "bool bRegisterInStaticList" que por defecto sea true, pero que las derivadas lo pasen como false al constructor de su clase padre.

- Asume que sólo tengo una colección de vehículos sobre la que quiero iterar, o bien me obliga a asegurarme de que cada vehículo de la lista estática está en mi contenedor concreto, subiendo el coste del algoritmo de O(n) a O(n^2).

- Me obliga de igual forma a conocer todas las clases posibles, para acceder a la lista estática de cada una de ellas. Si añado nuevas clases, tengo que modificar cada algoritmo que haya implementado sobre la colección. Que es exactamente el mismo problema que tenía con los mecanismos tipo RTTI, pero con todos los problemas adicionales ya descritos.

Lo de las funciones virtuales vacías en la base no resulta muy aplicable cuando la clase base me la dan ya hecha en una librería que yo quiero extender con nuevas clases (que incluyen datos no previstos en la librería original).

En serio... de verdad os creeis que el RTTI se metió en C++ porque la mayoría de los desarrolladores son vagos o idiotas? Existen muchos problemas para los cuales RTTI es realmente la mejor solución. El que diga que esos problemas no te los encuentras en el mundo laboral, no sabe muy bien de lo que habla.

Si quieres crear una librería de objetos especializada, genérica, flexible y extensible, realmente necesitas un mecanismo de este tipo o limitarás sus posibles usos. La gente que se encontraba con este problema se inventaban su propio getType(), y al final el lenguaje incorporó una forma común de hacerlo.
Título: C++ y POO
Publicado por: shephiroth en 13 de Enero de 2007, 04:41:51 AM
Cita de: "Jare"
Cita de: "shephiroth"Si los necesitas solo para mostrarlos en pantalla, una funcion virtual de mostrar. Si quieres operar solo con una de las clases hijas podrías usar una funcion estatica y que la clase tenga por medio de una lista dinamica o algo parecido consciencia de todos los objetos de dicha clase.
¿Las clases de la jerarquía de vehiculos necesitan saber cómo queremos (y qué necesitamos para) pintarlas en pantalla? Creamos un acomplamiento extra con nuestro sistema de pintado, que no es muy agradable de cara a la reusabilidad..
A ver, no entendi muy bien. Si tienes una funcion virtual pintar en la clase base te librara de todo rtti, pues acabara directamente en la funcion pintar de la clase que es el objeto, en la cual tiene acceso a sus variables reales y puedes codificar un metodo adaptado para ese tipo de objeto.

Cita de: "Jare""Pasale un interfaz a la función de pintar, y así tu te lo implementas para tus funciones de pintado concretas" dirá alguno. Pero claro, para que mi interfaz pueda recibir los datos de cualquiera de las clases para usarlos como YO quiera, la función "pintar" tendrá que pasarselos de alguna forma simbólica y genérica, por ejemplo un mapa indexado por cadenas del tipo "Cilindrada" y "Consumo". No es que sea muy óptimo..
No se exactamente q es lo q quieres hacer. Lo unico que se me ocurre es q crees q las funciones virtuales no pueden recibir parametros, pq sino no entiendo esto. Si tu necesitas pasar como parametro la posicion de pantalla la puedes pasar directamente. Si tu problema radica en q antes de pintar tienes q utilizar funciones individuales de cada subclase, puede q el problema sea tan facil de solucionar como no agrupar peras con manzanas ;)

Cita de: "Jare"Mi implementación del interfaz de pintado tendrá que ir consultando cada elemento del mapa de datos que me da el vehículo, y hacer un... ¿switch/case o cadena de IFs? Y eso aún sería fácil si todos los datos consultables son del mismo tipo, números por ejemplo. ¿Y si algunos son floats, otros cadenas, y otros son a su vez contenedores de otros objetos, por ejemplo el campo "Cargamento"?

Eso solamente para el problema de pintarlos. Si quiero hacer una "librería de vehiculos" para que otra gente la use, tengo que preveer todos los posibles usos que la gente querrá hacer con esos vehiculos, y preparar un interfaz para cada funcionalidad. Lo siento, pero mi bola de cristal está sin pilas.
Aqui no coincidimos. Lo siento, pero cuando haces una librería no puedes dejar al programador al libre albedrío. Tienes q darle la funcionalidad que tu quieras, pero tienes q darla de forma eficiente no de forma eficaz. Si cuando haces la libreria le obligas al programador a estar todo el rato preguntando por el tipo puede que sea eficaz tu libreria, pues cumple con su cometido, pero eficiencia nula.

Cita de: "Jare"
La solución de implementar una lista estática que contenga las instancias de cada clase no es que ayude mucho, ya que:

- Introduce costes extras de gestión y memoria.
gestion no se, rtti no es barato. Memoria si, pero no demasiada. 4 bytes por objeto no es mucho (en mobiles puede q si, en pc no).

Cita de: "Jare"
- Sólo tiene sentido en clases que no tengan a su vez otras derivadas (lo que podría no ser aplicable), ya que el mismo objeto aparecería en varias listas estáticas diferentes. También hace poco viable que yo derive nuevas clases especializadas a partir de las ya existentes. Supongo que los constructores de cada clase tendrán que recibir un parámetro "bool bRegisterInStaticList" que por defecto sea true, pero que las derivadas lo pasen como false al constructor de su clase padre.
Hmmm, para clases derivadas no lo se...ademas que c y jva heredan de forma diferente. Pero partiendo de que entendiste mal lo de las listas no hago mucho caso a esto ^^;

Cita de: "Jare"- Asume que sólo tengo una colección de vehículos sobre la que quiero iterar, o bien me obliga a asegurarme de que cada vehículo de la lista estática está en mi contenedor concreto, subiendo el coste del algoritmo de O(n) a O(n^2).
Si, en esto tienes razon. Pero partiendo de la misma idea, pq haces una coleccion sobre la clase base, y no una de cada clase hija??? Haciendo una por hija perderias claridad en el codigo por tener q iterar por mas de una coleccion, pero ganarias el olvidarte de rtti y poo.....pero claro, es mas comodo una coleccion.

Cita de: "Jare"- Me obliga de igual forma a conocer todas las clases posibles, para acceder a la lista estática de cada una de ellas. Si añado nuevas clases, tengo que modificar cada algoritmo que haya implementado sobre la colección. Que es exactamente el mismo problema que tenía con los mecanismos tipo RTTI, pero con todos los problemas adicionales ya descritos.
NO, NO, NO, NO, NO Y MIL VECES NO. Aqui no me entendiste en absoluto. No me refiero en la clase base crear una lista por cada uno de sus tipos. Me referia a crear una lista estatica en cada clase HIJA. De esta forma podrias acceder directamente hija::funcion. Al crear una nueva clase no necesitarias cambiar ningun codigo existente, solo tendrías que clonar el comportamiento de la lista.


Cita de: "Jare"Lo de las funciones virtuales vacías en la base no resulta muy aplicable cuando la clase base me la dan ya hecha en una librería que yo quiero extender con nuevas clases (que incluyen datos no previstos en la librería original).
Aqui te doy la razon 100%.

Cita de: "Jare"En serio... de verdad os creeis que el RTTI se metió en C++ porque la mayoría de los desarrolladores son vagos o idiotas? Existen muchos problemas para los cuales RTTI es realmente la mejor solución. El que diga que esos problemas no te los encuentras en el mundo laboral, no sabe muy bien de lo que habla.
No se cuantas veces lo habre dicho ya, YAH CASOS EN LOS Q RTTI ES UTIL, otras veces NOOOOOOOOOOOOO.


Cita de: "Jare"Si quieres crear una librería de objetos especializada, genérica, flexible y extensible, realmente necesitas un mecanismo de este tipo o limitarás sus posibles usos. La gente que se encontraba con este problema se inventaban su propio getType(), y al final el lenguaje incorporó una forma común de hacerlo.
Aqui tampoco comparto tu opinion. Si una libreria esta limitada una de dos:
1- No se le quiso dar mas funcionalidad.
2- No se le supo dar mas funcionalidad.

Para mi q ninguna de las dos depende ni de poo ni de rtti.....

SALUDOS
Título: C++ y POO
Publicado por: Jare en 13 de Enero de 2007, 05:58:28 AM
Cita de: "shephiroth"A ver, no entendi muy bien..
Si piensas que YO hago una librería de clases para vehículos, y que tú quieres usarla en tu aplicación (de cuyo pintado y necesidades yo no sé ni puedo saber nada), entonces verás a qué me refiero.
CitarNO, NO, NO, NO, NO Y MIL VECES NO. Aqui no me entendiste en absoluto. No me refiero en la clase base crear una lista por cada uno de sus tipos. Me referia a crear una lista estatica en cada clase HIJA. De esta forma podrias acceder directamente hija::funcion. Al crear una nueva clase no necesitarias cambiar ningun codigo existente, solo tendrías que clonar el comportamiento de la lista.
¿Y quién es el que accede a cada una de esas listas? Recuerda la idea de que la librería de vehículos no puede ni debe saber nada sobre lo el uso concreto que la aplicación quiere hacer de ella.
Título: C++ y POO
Publicado por: Fran en 13 de Enero de 2007, 08:26:33 AM
Cita de: "marcode"Puse dos por si acaso  :wink:

El otro es que quieres obtener la media del precio de todos los vehiculos de la clase coche.

Por poner otro más raro, que haya que saber que vehículos tienen que pasar la ITV este año. Aquí dependiendo de un tipo u otro varía el periodo de revisión de cada uno. Seguro que se podrían poner otros en los que no queden más narices que saber con qué estás tratando.

Joder, este si q es de huevo

Este es muy facil. Implementas el método virtual en la clase vehiculo getPlazoRevision lo pones por ejmpllo por defecto a 4 si no quieres redefinirlo en los coches y en las motos y si no lo pones a 0 y lo redefines hay tb y en el resto de vehiculos (ej. camiones) lo pones a lo q sea p.e. 1. Despues en la clase base pones un método

clase base (lo pongo todo en pseudocodigo por no particularizar en ningun lenguaje xq esto es valido para Java,Delphi,C++,SmallTalk....)

Vehiculo{
.....
 virtual getPlazoRevision(){result=4}
 boolean getMeTocaLaRevision (dtFecha del tipo DateTime)
.....
}

(cocheparticular y moto no los redefino xq ya me valen  o si no, el de vehiculo lo pongo a 0 y estos dos a 4)

Camion{
 override getPlazoRevision(){result=1}//o el tiempo q sea
}

Taxi{
 override getPlazoRevision(){result=3}//o el tiempo q sea
}

Autobus{
 override getPlazoRevision(){result=2}//o el tiempo q sea
}


en el vehiculo

boolean getMeTocaLaRevision (dtFecha del tipo DateTime)
{
 result= pasarAAnyos(dtFecha-getFechaAlta())>=getPlazoRevision()
}

y ya está.  Sin getType ni RTTI ni nada

Ese es un ejemplo desafortunado para la RTTI xq muestra claramente donde es util la OOP, virtuales, herencia, etc... Es de libro para hacerlo con funciones virtuales. Si haces esto con getType , no digo q esté mal, pero programas estructuradamente sin OOP y sin nada. Si mañana te acuerdas q se te han olvidado las bicicletas con RTTI tendrias q modificar la clase base (un case, antiOOP) si lo haces con virtuales, si le has puesto en la base tiempoderevision=0 no tendiras q hacer nada, si le has puesto 4, declararias esto y ya esta

Bicicleta{
 override getPlazoRevision(){result=0}//o el tiempo q sea
}

No tocas la clase base->no hay efectos colaterales no previstos. Solo tienes q hacer overrride de un método en la clase q estás creando, y lo mejor. No obligas a nadie a conocer el resto de la jerarquia para meter una funcionalidad nueva.
Título: C++ y POO
Publicado por: marcode en 13 de Enero de 2007, 04:47:23 PM
Cita de: "shephiroth"
"un listado de las características de los vehículos sin que me diga que el maletero de una moto mide cero metros" acaso esto no es el enunciado perfecto de "funcion virtual y que hereden las hijas"?? Aclarate :wink:
Aclárame tú cómo hacerlo con una función virtual, por ejemplo: Necesito averiguar de la lista de vehículos en un momento dado, cuál es el que tiene el maletero más pequeño.


El problema de obtener el precio medio de los coches todavía creo que no ha sido resuelto sin usar el GetType, Aquí va:

int precioSuma = 0; int n = 0;

for (int i=0;i<100;i++)
{
if (Vehiculo[i]->GetType() == COCHE) {
precioSuma + = Vehiculo[i]->GetPrice();
n++;
}

}

int precioMedioCoches = precioSuma/n;


Estoy usando el "Type" como una propiedad más del objeto,  al fin y al cabo también puedes tener GetModel, GetCategory, GetClass, etc. No veo que hay de malo. Si además me interesan sólo los vehículos de 5 puertas haría:

if (Vehiculo[i]->GetType() == COCHE &&
Vehiculo[i]->GetPuertas() == CINCO_PUERTAS) { ....


Y en cuanto a los otros ejemplos en el que se da la solución de ir añadiendo más y más funciones virtuales (como comenta Fran),  ¿que pasa cuando no se puede modificar la clase base por la razón que sea?, por ejemplo porque solo tengas el C.Objeto, o porque el diseñador no le apetece que le meta mano todo programador que quiera resolver su problema puntual.

¿Y cuando se necesita iterar una cantidad exagerada de objetos como pudieran ser partículas por ejemplo para calcular la fuerza de gravedad que ejercen unas sobre otras?, olvídate de usar funciones virtuales.

De todos modos no discutiré si la POO auténtica es de una forma u otra, (no estudié lo suficiente), solo discuto si realmente es eficaz seguirla estrictamente.
Título: C++ y POO
Publicado por: Fran en 13 de Enero de 2007, 05:57:00 PM
Cita de: "marcode"

Y en cuanto a los otros ejemplos en el que se da la solución de ir añadiendo más y más funciones virtuales (como comenta Fran),  ¿que pasa cuando no se puede modificar la clase base por la razón que sea?, por ejemplo porque solo tengas el C.Objeto, o porque el diseñador no le apetece que le meta mano todo programador que quiera resolver su problema puntual.

¿Y cuando se necesita iterar una cantidad exagerada de objetos como pudieran ser partículas por ejemplo para calcular la fuerza de gravedad que ejercen unas sobre otras?, olvídate de usar funciones virtuales.


¿?  Quizás no me he explicado bien. Es q con esa solución (con la q yo he dado) no necesitas tocar para nada la clase base . Nadie tiene q tocarla para resolver el programa añadas lo q añadas. Ni siquiera tienes q saber como funciona. Ahi está lo grande. Y en el caso de particulas, mejor, no tienes que saber de qué tipo es ni nada de nada. Simplemente por ejemplo redefinir su método masa() o carga() en funcion del tipo de partícula que sea y ya está. Nada más.
Título: C++ y POO
Publicado por: marcode en 13 de Enero de 2007, 06:15:27 PM

Vehiculo{
.....
virtual getPlazoRevision(){result=4}
boolean getMeTocaLaRevision (dtFecha del tipo DateTime)
.....
}


Estas añadiendo esto para un problema puntual, pero ¿si te surjen mil problemas vas a añadir mil funciones virtuales?

En cuanto a las partículas, no todas tienen masa o carga, si tengo 5 protones y 1000 electrones no quiero calcular su atracción cero haciendo 1005*1005 operaciones, sólo quiero calcular la de los 5 protones.

De todos modos es mi opinión personal de cómo me parece mejor usar la POO en C++ (será porque vengo del C).
Título: C++ y POO
Publicado por: Fran en 13 de Enero de 2007, 07:02:20 PM
Cita de: "marcode"
Vehiculo{
.....
virtual getPlazoRevision(){result=4}
boolean getMeTocaLaRevision (dtFecha del tipo DateTime)
.....
}


Estas añadiendo esto para un problema puntual, pero ¿si te surjen mil problemas vas a añadir mil funciones virtuales?


Claro. Mil o 500 o 1500. Las q hagan falta.Todavia no conozco el programa que resuelva mil problemas sin programarlo.

Cita de: "marcode"

En cuanto a las partículas, no todas tienen masa o carga, si tengo 5 protones y 1000 electrones no quiero calcular su atracción cero haciendo 1005*1005 operaciones, sólo quiero calcular la de los 5 protones.

De todos modos es mi opinión personal de cómo me parece mejor usar la POO en C++ (será porque vengo del C).

No sé cual es el problema de los electrones y protones. Si lo propones lo veriamos. En cualquier caso ambos tienen carga q yo sepa y masa (aunq la de uno si no recuerdo mal es infinitamente más grande q la otra ¿o no era así?. De todos modos todos por ejemplo tendrían efecto electromagnético sobre los demás asi que no entiendo como quieres resolver el problema si no haces 1005*1005 / 2 calculos...
Título: C++ y POO
Publicado por: shephiroth en 13 de Enero de 2007, 07:57:34 PM
Cita de: "marcode"
Cita de: "shephiroth"
"un listado de las características de los vehículos sin que me diga que el maletero de una moto mide cero metros" acaso esto no es el enunciado perfecto de "funcion virtual y que hereden las hijas"?? Aclarate :wink:
Aclárame tú cómo hacerlo con una función virtual, por ejemplo: Necesito averiguar de la lista de vehículos en un momento dado, cuál es el que tiene el maletero más pequeño.

El problema de obtener el precio medio de los coches todavía creo que no ha sido resuelto sin usar el GetType
Sobre el maletero mas pequeño, depende para q lo necesites. Como puse en un post anterior quizas te interese tener mas de un contenedor para tus objetos. La idea de poder juntar en un contenedor clases hijas esta ahi, pero no es obligatorio juntarlas siempre.

Sobre el precio medio, yo me decantaría sobre una funcion statica en la clase hija y una lista dynamica...aunque lo puesto arriba aqui tambien opera...haberlas hay miles de formas usando poo, otra cosa es q nisiquiera intentes buscarlas.

Cita de: "marcode"Y en cuanto a los otros ejemplos en el que se da la solución de ir añadiendo más y más funciones virtuales (como comenta Fran),  ¿que pasa cuando no se puede modificar la clase base por la razón que sea?, por ejemplo porque solo tengas el C.Objeto, o porque el diseñador no le apetece que le meta mano todo programador que quiera resolver su problema puntual.

¿Y cuando se necesita iterar una cantidad exagerada de objetos como pudieran ser partículas por ejemplo para calcular la fuerza de gravedad que ejercen unas sobre otras?, olvídate de usar funciones virtuales.
Cuando solo tienes CObjeto, te creas tus bases intermedias CControl CListas CVehiculo CLoquetedelagana añadiendoles las funcionalidades que necesitas, y basandote en esas te creas tus hijas CCamion CMoto CBoton CListBox .....

Sobre cuando tienes un sistema de particulas...aparte de que no se mucho, yo no liaria herencia en un sistema....lo mas seguro crearia una clase base del sistema, y un sistema hijo con cada objeto q necesitase...y por supuesto las funciones virtuales SI aparecerian en los sistemas hijos.

Cita de: "Fran"
Cita de: "marcode"
Vehiculo{
.....
virtual getPlazoRevision(){result=4}
boolean getMeTocaLaRevision (dtFecha del tipo DateTime)
.....
}


Estas añadiendo esto para un problema puntual, pero ¿si te surjen mil problemas vas a añadir mil funciones virtuales?


Claro. Mil o 500 o 1500. Las q hagan falta.Todavia no conozco el programa que resuelva mil problemas sin programarlo.
Que gran verdad :)
Título: C++ y POO
Publicado por: marcode en 14 de Enero de 2007, 06:13:05 PM
Cita de: "Fran"
No sé cual es el problema de los electrones y protones. Si lo propones lo veriamos. En cualquier caso ambos tienen carga q yo sepa y masa (aunq la de uno si no recuerdo mal es infinitamente más grande q la otra ¿o no era así?. De todos modos todos por ejemplo tendrían efecto electromagnético sobre los demás asi que no entiendo como quieres resolver el problema si no haces 1005*1005 / 2 calculos...

Aquí está el kit de la cuestión, si yo quiero reutilizar tus clases de partículas me estas obligando a calcular la atracción gravitatoria de los electrones porque sí tienen masa. Pero yo quiero en un momento determinado del programa despreciar la masa de los electrones porque son un 1/1.840 con respecto al proton, y no quiero hacer un millon de llamadas a funciones virtuales.

Quiero listas de punteros a los objetos que me interesen y a ser posible con funciones inline, es más, quiero listas de punteros a propiedades de algunos objetos, no entiendo porque debo ceñirme a una determinada metodología (por muy elegante que sea) si de algún modo estuviera perdiendo eficacia.

Creo que llevar a estos extremos la POO es encerrarlo todo en una caja muy bonita que puede que no le guste más que al que la diseño, espero no encontrarme nunca con una librería de una clase con 1000 funciones virtuales para cada uno de los problemas que se le hayan ocurrido que se pueden dar, y luego encima me tenga que volver loco para encontrar o hacer lo que yo quiero. Problemas que por lo general puedo resolver con 2 o 3 líneas y que no necesito incorporar a la clase. Entre otras cosas porque suelo crear otras clases que forman grupos donde guardo y reutilizo los problemas, en el caso de las partículas pudiera ser las clases Sistema Solar, Atomos, agua, humo, etc. Que tienen un comportamiento no sólo individual, si no colectivo. Me niego en rotundo a meter en la propia clase base de particulas todas las peculiaridades de todo lo que puedo considerar una partícula y sus diferentes aplicaciones, problemas, comportamientos o posibilidades que por mi parte dependiendo de casa situación y de cada programador pueden ser infinitas.
Título: C++ y POO
Publicado por: shephiroth en 14 de Enero de 2007, 10:56:58 PM
Buenas.

Me parece que estais liando mucho el rizo Marcode. En el ultimo post hablas de calidad, flexibilidad, reutilizacion de codigo.....y esto no depende de la metodologia utilizada, sino del codigo en si.
Título: C++ y POO
Publicado por: Fran en 14 de Enero de 2007, 11:37:55 PM
Cita de: "marcode"
Cita de: "Fran"
No sé cual es el problema de los electrones y protones. Si lo propones lo veriamos. En cualquier caso ambos tienen carga q yo sepa y masa (aunq la de uno si no recuerdo mal es infinitamente más grande q la otra ¿o no era así?. De todos modos todos por ejemplo tendrían efecto electromagnético sobre los demás asi que no entiendo como quieres resolver el problema si no haces 1005*1005 / 2 calculos...

Aquí está el kit de la cuestión, si yo quiero reutilizar tus clases de partículas me estas obligando a calcular la atracción gravitatoria de los electrones porque sí tienen masa. Pero yo quiero en un momento determinado del programa despreciar la masa de los electrones porque son un 1/1.840 con respecto al proton, y no quiero hacer un millon de llamadas a funciones virtuales.

Quiero listas de punteros a los objetos que me interesen y a ser posible con funciones inline, es más, quiero listas de punteros a propiedades de algunos objetos, no entiendo porque debo ceñirme a una determinada metodología (por muy elegante que sea) si de algún modo estuviera perdiendo eficacia.

Creo que llevar a estos extremos la POO es encerrarlo todo en una caja muy bonita que puede que no le guste más que al que la diseño, espero no encontrarme nunca con una librería de una clase con 1000 funciones virtuales para cada uno de los problemas que se le hayan ocurrido que se pueden dar, y luego encima me tenga que volver loco para encontrar o hacer lo que yo quiero. Problemas que por lo general puedo resolver con 2 o 3 líneas y que no necesito incorporar a la clase. Entre otras cosas porque suelo crear otras clases que forman grupos donde guardo y reutilizo los problemas, en el caso de las partículas pudiera ser las clases Sistema Solar, Atomos, agua, humo, etc. Que tienen un comportamiento no sólo individual, si no colectivo. Me niego en rotundo a meter en la propia clase base de particulas todas las peculiaridades de todo lo que puedo considerar una partícula y sus diferentes aplicaciones, problemas, comportamientos o posibilidades que por mi parte dependiendo de casa situación y de cada programador pueden ser infinitas.

Sinceramente el problema q expones tiene muchas soluciones evidentes desde el punto de vista de OOP que son muy efectivas y puedes plantear eso. Pero vamos, aquí nadie está obligando a usar OOP. Simplemente estabamos hablando de la ortodoxia de usar funciones virtuales vs RTTi y creo que eso no tiene discusion y de si se pueden solucionar prácticamente todos los casos sin recurrir a RTTi. Evidentemente para cualquier problema hay muchas soluciones y solo una es la óptima. Y ésta no tiene xq ser el uso sin excusas de la OOP pura. Creo que esa salida no tiene nada que ver con el tema del post.
Título: C++ y POO
Publicado por: fiero en 15 de Enero de 2007, 12:33:07 AM
Cita de: "Fran"Evidentemente para cualquier problema hay muchas soluciones y solo una es la óptima.

Creo que en programación no hay una "solución óptima". Y esa es la razón por la que este hilo tiene 9 páginas ya. Porque hay gente que se empeña en que sólo hay una forma óptima de hacer las cosas y no es así. Se puede optimizar el consumo de recursos, el tamaño del programa, la velocidad de ejecución, el tiempo de programación, la legibilidad del código fuente, la modularidad del código fuente, la rehusabilidad del código, etc, etc, etc.... Se puede optimizar para cada una de esas cosas, pero NO PARA TODO a la vez, por tanto, no existe una única manera óptima de hacer nada.

un saludo
Título: C++ y POO
Publicado por: Fran en 15 de Enero de 2007, 09:23:17 AM
Cita de: "fiero"
Cita de: "Fran"Evidentemente para cualquier problema hay muchas soluciones y solo una es la óptima.

Creo que en programación no hay una "solución óptima". Y esa es la razón por la que este hilo tiene 9 páginas ya. Porque hay gente que se empeña en que sólo hay una forma óptima de hacer las cosas y no es así. Se puede optimizar el consumo de recursos, el tamaño del programa, la velocidad de ejecución, el tiempo de programación, la legibilidad del código fuente, la modularidad del código fuente, la rehusabilidad del código, etc, etc, etc.... Se puede optimizar para cada una de esas cosas, pero NO PARA TODO a la vez, por tanto, no existe una única manera óptima de hacer nada.

un saludo

No estoy de acuerdo. En todo, hay cosas muy buenas pero una de ellas es la mejor aunq sea por muy poco. Y eso no quiere decir q sea la mejor en todo. Quiere decir que comparando ventajas e inconvenientes y puntuando con criterios de empresa, es la mejor aunque en algunas cosas no lo sea. Esa es la óptima. Pero vamos no nos vamos a poner a eso ahora. En el caso que nos ocupa lo de las funciones viertuales lleva la mejor puntuación en mantenibilidad, legibilidad y ortodoxia. Es posible (habría q medirlo) que en velocidad no lo sea. El tamaño si no hablamos de diferencias de 100MB para arriba hoy para mi no es un criterio. Si además gana en velocidad pues no hay nada más q hablar y si no dependiendo de cada empresa posiblemente tb lo sea. En la mia lo es. El q corra un 10% menos es despreciable a cambio de que sea facil de mantener, legible y escalable
Título: C++ y POO
Publicado por: Vicente en 15 de Enero de 2007, 09:54:31 AM
Me hizo gracia encontrarme esto de casualidad leyendo sobre D:

http://www.prowiki.org/wiki4d/wiki.cgi?LanguagesVersusD

Y que en el apartado OOP tengan:

- Dynamic class loading
- Reflection/Introspection

Ta claro que cada cual piensa lo que quiere :p Un saludo!

Vicente
Título: C++ y POO
Publicado por: Fran en 15 de Enero de 2007, 10:14:53 AM
Cita de: "Vicente"Me hizo gracia encontrarme esto de casualidad leyendo sobre D:

http://www.prowiki.org/wiki4d/wiki.cgi?LanguagesVersusD

Y que en el apartado OOP tengan:

- Dynamic class loading
- Reflection/Introspection

Ta claro que cada cual piensa lo que quiere :p Un saludo!

Vicente

Vicente. Te me escapas para variar  :lol:  :lol:  :lol:  :lol:  :lol:
Título: C++ y POO
Publicado por: Vicente en 15 de Enero de 2007, 10:44:01 AM
Como andábamos debatiendo de si RTTI es más o menos POO, pues me ha hecho gracia ver como dentro de características POO de lenguajes incluían la Reflexion.

En el Ave Fenix acabo de leer otro comentario que puede ser interesante sobre el tema:

http://www.elavefenix.net/Noticias06.aspx

Es la noticia de "Anders Hejlsberg rechaza el criticismo sobre C# 3.0". Supongo que se habrá criticado a los métodos extensionales: métodos que se añaden a una estructura o a una clase sellada (cosas que en teoría no se pueden modificar, porque de un struct no se puede heredar y una clase sellada, pues eso, es sellada :p).

Un saludo!

Vicente
Título: C++ y POO
Publicado por: Fran en 15 de Enero de 2007, 12:20:01 PM
Cita de: "Vicente"Como andábamos debatiendo de si RTTI es más o menos POO, pues me ha hecho gracia ver como dentro de características POO de lenguajes incluían la Reflexion.

En el Ave Fenix acabo de leer otro comentario que puede ser interesante sobre el tema:

http://www.elavefenix.net/Noticias06.aspx

Es la noticia de "Anders Hejlsberg rechaza el criticismo sobre C# 3.0". Supongo que se habrá criticado a los métodos extensionales: métodos que se añaden a una estructura o a una clase sellada (cosas que en teoría no se pueden modificar, porque de un struct no se puede heredar y una clase sellada, pues eso, es sellada :p).

Un saludo!

Vicente

Lo he leido y sigo sin entender q tiene q ver. Por ciertlo, lo del equipo óptimo para Vista es de descojono
Título: C++ y POO
Publicado por: Vicente en 15 de Enero de 2007, 12:39:01 PM
Ya no tiene que ver tanto con lo de virtuales vacios vs RTTI, si no con lo que se ha comentado también de la "pureza" de la POO (RTTI es POO-- como decías tú, pues en esa línea).

Un saludo!

Vicente
Título: C++ y POO
Publicado por: Fran en 15 de Enero de 2007, 01:02:53 PM
Cita de: "Vicente"Ya no tiene que ver tanto con lo de virtuales vacios vs RTTI, si no con lo que se ha comentado también de la "pureza" de la POO (RTTI es POO-- como decías tú, pues en esa línea).

Un saludo!

Vicente

Hombre. Vamos a ver. Si lo q quieres decirme es q RTTI está incluido , es cierto. Que se incluyó en contra de la opinión de los creadores de C++ y de muchos "puristas" x presiones de los programadores tb - Q es a lo q os referis Anders y tú, aunq él no habla de RTTi-. Q a mi no me parece ni mal ni bien. Tb. Pero q con lo q empezó el post fué con que RTTi era mejor y era OOP y crear funciones virtuales vacias no, creo q ha qdado demostrado que es más puro desde el p. de vista de OOP lo de las funciones virtuales aunq estén vacias y q no son ninguna patata. Pero q para gustos colores, estoy de acuerdo. Quien trabaje conmigo desde luego   tiene prohibido hacer cosas asi, pero no por nada, sino xq luego cualquier modificación necesita mil comprobaciones y modificaciones - no xq considere q no sea OOP pura, eso me da igual-
Título: C++ y POO
Publicado por: marcode en 15 de Enero de 2007, 01:17:18 PM
un momento, que va a opinar el especialista:

Cita de: "Bruce Eckel"
Si el problema consiste en averiguar el tipo exacto de todos los objetos, hay que volver a pensar porque posiblemente no se estén usando las funciones virtuales de forma apropiada. Sin embargo, hay algunas situaciones en las cuales el diseño funciona mejor (o no hay otra elección) si se conoce el tipo exacto de todos los objetos, por ejemplo aquellos incluidos en un contenedor genérico. Este es el problema de la runtime type identificatión o RTTI (identificación de tipos en tiempo de ejecucion).
Título: C++ y POO
Publicado por: Fran en 15 de Enero de 2007, 01:41:11 PM
Cita de: "marcode"un momento, que va a opinar el especialista:

Cita de: "Bruce Eckel"
Si el problema consiste en averiguar el tipo exacto de todos los objetos, hay que volver a pensar porque posiblemente no se estén usando las funciones virtuales de forma apropiada. Sin embargo, hay algunas situaciones en las cuales el diseño funciona mejor (o no hay otra elección) si se conoce el tipo exacto de todos los objetos, por ejemplo aquellos incluidos en un contenedor genérico. Este es el problema de la runtime type identificatión o RTTI (identificación de tipos en tiempo de ejecucion).

Me qdo con q si se usa es xq no se stán usando de manera apropiada las funciones virtuales.

Per cojo tb un libro suyo y lo q dice de RTTi:

http://home1.stofanet.dk/vores_hjemme/book2/IndexXTOC.htm

9: Run-time type identification

Run-time type identification (RTTI) lets you find the exact type of an object when you have only a pointer or reference to the base type.

This can be thought of as a "secondary" feature in C++, a pragmatism to help out when you get into messy situations. Normally, you'll want to intentionally ignore the exact type of an object and let the virtual function mechanism implement the correct behavior for that type. But occasionally it's useful to know the exact type of an object for which you only have a base pointer. Often this information allows you to perform a special-case operation more efficiently or prevent a base-class interface from becoming ungainly. It happens enough that most class libraries contain virtual functions to produce run-time type information. When exception handling was added to C++, it required the exact type information about objects. It became an easy next step to build access to that information into the language.

This chapter explains what RTTI is for and how to use it. In addition, it explains the why and how of the new C++ cast syntax, which has the same appearance as RTTI.

Por cierto. El ejemplo q ponde de Highlight es para matarlo. Hay una manera muy muy sencilla para evitar usar RTTi. Aunq tb dice que la primera aproximación de un novato o algo asi es hacerlo como él describe...
Título: C++ y POO
Publicado por: jaure en 15 de Enero de 2007, 01:50:26 PM
Cita de: "marcode"un momento, que va a opinar el especialista:

Cita de: "Bruce Eckel"
Si el problema consiste en averiguar el tipo exacto de todos los objetos, hay que volver a pensar porque posiblemente no se estén usando las funciones virtuales de forma apropiada. Sin embargo, hay algunas situaciones en las cuales el diseño funciona mejor (o no hay otra elección) si se conoce el tipo exacto de todos los objetos, por ejemplo aquellos incluidos en un contenedor genérico. Este es el problema de la runtime type identificatión o RTTI (identificación de tipos en tiempo de ejecucion).

A mi me ha quedado mu claro.
Título: C++ y POO
Publicado por: Vicente en 15 de Enero de 2007, 02:04:07 PM
Cita de: "Fran"
Cita de: "marcode"un momento, que va a opinar el especialista:

Cita de: "Bruce Eckel"
Si el problema consiste en averiguar el tipo exacto de todos los objetos, hay que volver a pensar porque posiblemente no se estén usando las funciones virtuales de forma apropiada. Sin embargo, hay algunas situaciones en las cuales el diseño funciona mejor (o no hay otra elección) si se conoce el tipo exacto de todos los objetos, por ejemplo aquellos incluidos en un contenedor genérico. Este es el problema de la runtime type identificatión o RTTI (identificación de tipos en tiempo de ejecucion).

Me qdo con q si se usa es xq no se stán usando de manera apropiada las funciones virtuales.

Yo me quedo mejor con el "por ejemplo aquellos incluidos en un contenedor genérico", que es el problema que tratabamos de resolver. Aunque de tu post el "prevent a base-class interface from becoming ungainly" también está muy bien :)

Un saludo!

Vicente
Título: C++ y POO
Publicado por: Fran en 15 de Enero de 2007, 02:30:32 PM
Cita de: "Vicente"
Cita de: "Fran"
Cita de: "marcode"un momento, que va a opinar el especialista:

Cita de: "Bruce Eckel"
Si el problema consiste en averiguar el tipo exacto de todos los objetos, hay que volver a pensar porque posiblemente no se estén usando las funciones virtuales de forma apropiada. Sin embargo, hay algunas situaciones en las cuales el diseño funciona mejor (o no hay otra elección) si se conoce el tipo exacto de todos los objetos, por ejemplo aquellos incluidos en un contenedor genérico. Este es el problema de la runtime type identificatión o RTTI (identificación de tipos en tiempo de ejecucion).

Me qdo con q si se usa es xq no se stán usando de manera apropiada las funciones virtuales.

Yo me quedo mejor con el "por ejemplo aquellos incluidos en un contenedor genérico", que es el problema que tratabamos de resolver. Aunque de tu post el "prevent a base-class interface from becoming ungainly" también está muy bien :)

Un saludo!

Vicente

:lol:  :lol:  Yo me qdo como toy. Despues de todo el post no solo me reafirmo sino q si cabe stoy mas convencido q al ppio. de lo q defendí. Asi q cada uno q se qde con lo q mas le apetezca.