Foros - Stratos

Programadores => General Programadores => Mensaje iniciado por: O2 en 30 de Enero de 2003, 02:16:56 AM

Título: Funciones y parametros
Publicado por: O2 en 30 de Enero de 2003, 02:16:56 AM
                                Necesito una funcion que pueda recibir diferentes tipos de punteros (concretamente punteros a diferentes tipos de clases)

Puedo hacer esto en una sola funcion mediante templates o algo asi?

Me explico mejor:

En vez de tener que usar un monton de versiones diferentes de la misma funcion:





void Function(CClassType1* p);

void Function(CClassType2* p);

...





Una funcion que pueda recibir punteros de varios tipos de clase, y sepa diferenciarlos y reconocerlos.

Como podria hacerlo?

Gracias de antemano!                                
Título: Funciones y parametros
Publicado por: metaxas en 30 de Enero de 2003, 12:51:26 PM
                                Fácil, te he hecho un pequeño ejemplo:



template<class T> int Function(T *ptr)

{

   return ptr->DoSomething();

}





class I

{

   public:

       virtual int DoSomething() = 0;

};





class A : public I

{

   public:

       virtual int DoSomething()

       {

           return 0;

       }

};





class B : public I

{

   public:

        virtual int DoSomething()

        {

            return 1;

        }

};



int main(int argc, char* argv[])

{

   A a;

   B b;

   int value1 = Function(&a); // value1 vale 0

   int value2 = Function(&b); // value2 vale 1



   return 0;

}


Para el tema de identificar el tipo, en vez de eso lo mejor es que hagas heredar las distintas clases de un interfaz común con las funciones que necesitas y las implementes en cada clase, como en el ejemplo.

Metaxas                                
Título: Funciones y parametros
Publicado por: O2 en 30 de Enero de 2003, 05:32:15 PM
                                Que ocurriria si en tu ejemplo llamamos a Function con un puntero a un objeto que no tenga un metodo DoSomethig(); ?

Daria un error el compilador o petaria el programa?

Como podemos asegurarnos de que solo pueda llamarse a Function con unos determinados tipos de clases?

Gracias Metaxas!                                
Título: Funciones y parametros
Publicado por: Repoker en 30 de Enero de 2003, 05:38:16 PM
                               

#include <iostream.h>



template<class T> int Function(T *ptr)

{

   return ptr->DoSomething();

}





class I

{

   public:

       virtual int DoSomething() = 0;

};





class A : public I

{

   public:

       virtual int DoSomething()

       {

  cout << "Llamada clase A" << endl;

           return 0;

       }

};





class B : public I

{

   public:

        virtual int DoSomething()

        {

   cout << "Llamada clase B" << endl;

            return 1;

        }

};



int main(int argc, char* argv[])

{

   A a;

   B b;

   

cout << "+++ Llamadas estaticas +++" << endl;



int value1 = Function(&a); // value1 vale 0

   int value2 = Function(&b); // value2 vale 1



cout << endl;

cout << "+++ Llamadas dinamicas +++" << endl;



I* pointer;



pointer = new A;

pointer->DoSomething();



pointer = new B;

pointer->DoSomething();



   return 0;

}



Aqui tienes lo mismo pero usando llamadas dinámicas en vez de estáticas.                                
Título: Funciones y parametros
Publicado por: metaxas en 30 de Enero de 2003, 07:04:55 PM
                                O2, daría un error de compilación porque el objeto no tiene ese método. Respecto a tu última pregunta, precisamente en el ejemplo sólo puede llamarse a Function con un determinado tipo de clases, en concreto aquellas clases que implementan el interfaz. De esta forma, si pasases otras sabes en tiempo de compilación que estás pasando un puntero a un objeto que no es del tipo adecuado.

Metaxas                                
Título: Funciones y parametros
Publicado por: O2 en 30 de Enero de 2003, 07:13:50 PM
                                Estupendo!

Todo solucionado. Muchas gracias a Metaxas y Repoker!!                                
Título: Funciones y parametros
Publicado por: ethernet en 30 de Enero de 2003, 07:47:57 PM
No es necesario el template, o usas template o usas metodos virtuales.

o sea


template <typename T> void func(T* p){

  p->funcion();

}





o bien



class Itfce {

public: virtual void  ifunc() = 0;

};

class B:public Itfce{  

void ifunc(){ std::cout << "holas";}

};

void funcion(Itfce *p){

p->ifunc();



}





Oh, boh,h epuestolo mismo  que repoker pero el  con codigo de ejemplo xDD. :_))
aunque las dos cosas juntas tb deben funcionar :DD

saludos
Título: Funciones y parametros
Publicado por: Juan Mellado en 30 de Enero de 2003, 08:34:19 PM
                                Nota: Al código de Repoker le falta un par de "delete pointer".

Quisquilloso soy :loco:                                
Título: Funciones y parametros
Publicado por: Repoker en 30 de Enero de 2003, 11:59:45 PM
                                Perdón perdón .. :P                                
Título: Funciones y parametros
Publicado por: O2 en 01 de Febrero de 2003, 06:34:47 PM
                                Queda todo aclarado, Gracias a todos :)                                
Título: Funciones y parametros
Publicado por: O2 en 03 de Febrero de 2003, 04:03:39 PM
                                Bueno, aclarado lo de los templates, ahora tengo otra duda :(

Necesito tener una lista enlazada de punteros a diferentes tipos de clases, de forma que solo necesite tener una variable PunterosAClases* Punteros; para referirme a todos los tipos de clases que pretendo.

Funcionaria con una union?



union uClassPointer

{

     ClassType1*,

     ClassType2*,

     ClassType3*,

};



Luego podria crear una lista enlazada de uClassPointer's y acceder a diferentes metodos y variables de diferentes clases mediante los punteros?

No se si lo que digo es completamente imposible :P

Gracias de nuevo!!                                
Título: Funciones y parametros
Publicado por: metaxas en 05 de Febrero de 2003, 11:39:28 AM
                                Una forma de hacerlo, si no fueran muchas las clases distintas que puedes tener, sería hacer heredar esas clases de un interfaz común, obligando a implementar un método que devuelva el tipo al que pertenece la clase. En la lista guardarías punteros a la clase base común (el interfaz), y al pedir un elemento de la lista le pedirías el tipo y harías un cast al tipo adecuado en tiempo de ejecución, de esta forma:




#include <list>





enum { AType = 0, BType = 1 };





class IBase

{



public:

 

 virtual unsigned int GetType() = 0;

};





class A : public IBase

{

   

public:



unsigned int GetType()

{

    return AType;

}



void FuncA() {};

};





class B : public IBase

{

   

public:



unsigned int GetType()

{

    return BType;

}



void FuncB() {};

};







int main(int argc, char* argv[])

{

std::list<IBase *> ptrList;



A a;

B b;

ptrList.push_back(&a);

ptrList.push_back(&b);



IBase *ptrBase = ptrList.front();

unsigned int type = ptrBase->GetType();



switch (type)

{

 case AType: A *ptrA;

       ptrA = dynamic_cast<A *> (ptrBase);

       ptrA->FuncA();

       break;



 case BType: B *ptrB;

       ptrB = dynamic_cast<B *> (ptrBase);

       ptrB->FuncB();

       break;



 default: break;

}



return 0;

}


Acuérdate de compilarlo con el RTTI activado para que te funcione el dynamic_cast


Metaxas                                
Título: Funciones y parametros
Publicado por: O2 en 05 de Febrero de 2003, 12:14:13 PM
                                Gracias Metaxas! Algo asi estaba haciendo, pero no terminaba de cuajarlo.

Bueno, son bastantes tipos de clases, e ira en aumento, pero creo que es una buena forma de hacerlo.

Thnks de nuevo!