Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Problema con polimorfismo en C++

Iniciado por Manu343726, 10 de Septiembre de 2012, 02:47:56 PM

« anterior - próximo »

Manu343726

Buenas

Me está costando un poco acostumbrarme a las "peculiaridades" de C++ (Soy consciente de que me quedan muchas más por sufrir). Ésto me pasa por venir del maravilloso mundo de .NET, de la abstracción, y del garbage-collector. Pero bueno...

El caso es que estaba trabajando con un array de objetos, el tipico caso al que estoy acostumbrado de tener una clase base, diferentes objetos de clases derivadas de ésta, y empaquetarlos todos en un array de tipo la clase base.
Dejando aparte el tema del polimorfismo a base de funciones virtuales, overrides, etc etc; ya me da problemas únicamente recorriendo el array.

Incluso en un caso mas sencillo, en el que el array es de la clase base, y está relleno con objetos de la misma clase derivada.

Creo entender donde está el problema: Si mal no recuerdo, C++ trata a los arrays como punteros, y la sintaxis Array equivale a Array+(i*sizeof(TipoArray)); En mi caso el tamaño de la clase base es menor que el de la derivada, y por tanto en vez de saltar de elemento a elemento, salto poco menos de un objeto cada vez.

Existe alguna manera de trabajar con arrays de manera polimorfica igual que se haría en C#/VB.NET ???

Gracias

Gallo

#1
No acabo de entender tu post, exactamente como estás definiendo el array? y como estás asignando valores? Estas suponiendo demasiadas cosas y equivalencias entre C++ y C# que son erroneas.

Base arrayBases[50];    //50 objetos inicializados de tipo Base, imposible asignar derivados de Base.

Base* array[50];   //50 punteros no inicializados a objetos tipo Base no instanciados, a los cuales se les puede asignar punteros de clases derivadas de Base. ej:
array[0] = new DerivadoDeBase();
array[1] = new Base();
array[2] = new DerivadoDeDerviadoDeBase();

array[0]->metodoVirtualDefinidoEnBaseYDerivado(); //ejecutara el metodo definido en DerivadoDeBase
array[0]->metodoNOVirtualDefinidoEnBaseYDerivado(); //ejecutará el metodo definido en Base
array[0]->metodoDefinidoSoloEnDerivado(); //no compilará
dynamic_cast<DerivadoDeBase*>(array[0])->metodoDefinidoSoloEnDerivado();  //ejecutará el método propio de DerivadoDeBase

El primero coloca 50 objetos Base consecutivos en memoria estática, el segundo coloca 50 punteros pero los objetos se van instanciando en diferntes sitios del heap.

Quizá sea mejor que mires las clases de la STL que suelen ofrecer las ventajas que dan los lenguajes managed como C#, mirate por ejemplo std::vector y similares.


Manu343726

muchas gracias Gallo. Igual si que estoy mezclando demasiado C#. Ahora que me lo dices, si que recuerdo el tema de no poder instanciar objetos de clases derivadas, pero si apuntarlos con punteros de clase base. Gracias de nuevo.

adrigm

Tío no utilices arrays a palo seco para estas cosas usa la STL y en concreto los vectores

std::vector<ClaseBase> mi_lista;

mi_lista.push_back(ObjetoClaseDerivada);

o de las mil formas que hay de rellenar y trabajar con vectores.

http://www.cplusplus.com/reference/stl/vector/

http://razonartificial.com/ - Blog personal sobre desarrollo de videojuegos

gdl

Cita de: adrigm en 25 de Septiembre de 2012, 11:27:42 AM
Tío no utilices arrays a palo seco para estas cosas usa la STL y en concreto los vectores

std::vector<ClaseBase> mi_lista;

mi_lista.push_back(ObjetoClaseDerivada);

o de las mil formas que hay de rellenar y trabajar con vectores.

http://www.cplusplus.com/reference/stl/vector/

No hagas eso que std::vector tiene semántica de paso por valor y vas a hacerle un slice a los objetos que va a provocar bugs difíciles de encontrar. Si quieres tener un vector de objetos de clases derivadas, usa un puntero smart del tipo std::unique_ptr o std::shared_ptr que ya se encargan de destruir los objetos ellos solitos cuando se destruye el vector.

Gallo

#5
Antes de empezar a usar la STL  tan a saco mejor aprender algo mas de c++, mas que nada una lib no es para ejecutar código mágico el cual desconocemos que hace si no  para ahorrarnos la implementación nosotros.

Usa std o cualquier otra lib o framework solo cuando sepas que serias capaz de hacer lo mismo si quisieras con tu propio código pero pretendes ahorrar tiempo en pensar la solución e implementarla o al menos que sepas como está diseñado por dentro aunque no conozcas todos los detalles técnicos. Usar una lib/API sin saber lo que hace por dentro hará que la utilices mal en muchas ocasiones o directamente te pierdas intentando conseguir un resultado.






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.