PDA

View Full Version : [C++ estremo] derivare classe template da un'ADT non template + polimorfismo


BountyKiller
09-08-2006, 15:45
(serve per lavoro) mi è venuta quest'idea;
Vorrei sapere se esistono controindicazioni derivando una classe template da una classe astratta NON TEMPLATE e usando il polimorfismo (nella fattispecie usare una puntatore a classe (astratta) per istanziare istanziazioni del template e biding dinamico sulle istanze delle istanziazioni......)
compilare compila....ma non tutto cioè che compila funziona (mentre cioè che funziona sicuramente compila :rolleyes: ).

BountyKiller
09-08-2006, 16:03
dimenticavo: nella classe template derivata c'è un template dell'STL che va istanziato con lo stesso tipo che istanzia la classe template derivata

71104
09-08-2006, 21:07
compilare compila....ma non tutto cioè che compila funziona (mentre cioè che funziona sicuramente compila :rolleyes: ). e allora tu controlla che funzioni, così automaticamente compila anche :Prrr:

BountyKiller
10-08-2006, 08:38
penso di esserci riuscito.....
finora non ho trovato controindicazioni.

BountyKiller
29-08-2006, 09:40
confermo che funziona e che al momento non vedo altri modi per utilizzare il polimorfismo con classi template.....se la classe base (adt o no) è anch'essa una classe template non è possibile istanziare un 'istanziazione template di classe derivata utilizzando un puntatore alla classe base template (almeno così afferma stoutrup...... con le classi non template invece si può, ovviamente)

AngeL)
29-08-2006, 09:51
istanziare istanziazioni del template e biding dinamico sulle istanze delle istanziazioni
:huh:

BountyKiller
29-08-2006, 10:31
"il c++ è un linguaggio a riga di comando...come può gestire la grafica ??"

non la scorderò mai :Prrr:

Marco Giunio Silano
29-08-2006, 10:36
"il c++ è un linguaggio a riga di comando...come può gestire la grafica ??"

:D
Premetto che oggi sono stanco, ma non capisco questo 3d... sembra un monologo di pensieri :what: :uh:

AngeL)
29-08-2006, 10:38
"il c++ è un linguaggio a riga di comando...come può gestire la grafica ??"

non la scorderò mai :Prrr:
non ricordavo che c'eri anche tu :muro:

Marco Giunio Silano
29-08-2006, 11:07
"il c++ è un linguaggio a riga di comando...come può gestire la grafica ??"

Se usi la macchina da scrivere può essere un problema ;)

BountyKiller
29-08-2006, 12:12
:D
Premetto che oggi sono stanco, ma non capisco questo 3d... sembra un monologo di pensieri :what: :uh:

era una richiesta ai guru di questa sezione per sapere se avevano mai provato a fare quello che ho fatto io e che non ho trovato in nessun libro..... in particolare mi interessava sapere se c'erano controindicazioni di qualche tipo e pare di no (pare perchè nessuno ha risposto)

tomminno
29-08-2006, 16:00
era una richiesta ai guru di questa sezione per sapere se avevano mai provato a fare quello che ho fatto io e che non ho trovato in nessun libro..... in particolare mi interessava sapere se c'erano controindicazioni di qualche tipo e pare di no (pare perchè nessuno ha risposto)

Se non ho capito male è più o meno quello che ho fatto io per istanziare a runtime una classe template, nel mio caso un Buffer che al suo interno contiene una Queue. Io per ora non ho trovato controindicazioni di sorta.
Tra l'altro mi sembra un qualcosa che può risultare utile in diverse occasioni, non capisco perchè su internet non si trovi praticamente niente a riguardo.
Anch'io avevo chiesto tempo fa sul forum informazioni sull'argomento, ma non ottenni risposta.

BountyKiller
29-08-2006, 16:51
a me ha risparmiato di scrivere una ventina di classi praticamente tutte uguali....davvero una buona cosa....penso tu possa facilmente immaginare la difficoltà di gestire così tante classi in caso di bachetti o aggiunte..... i template a volte sono veramente utilissimi.....
resta da capire perchè non si possa utilizzare il polimorfismo con una classe base template...questo ancora non sono riuscito a capirlo....

Marco Giunio Silano
30-08-2006, 08:07
era una richiesta ai guru di questa sezione per sapere se avevano mai provato a fare quello che ho fatto io e che non ho trovato in nessun libro..... in particolare mi interessava sapere se c'erano controindicazioni di qualche tipo e pare di no (pare perchè nessuno ha risposto)

eheheh capisco, cmq seguo curioso l'evolversi della questione ;)

BountyKiller
06-09-2006, 15:47
confermo dopo ulteriori test che l'idea funziona, l'unica cosa che non mi piace tanto è il fatto che il tipo di ritorno e i parametri dei metodi virtuali puri devono essere dei void* (almeno io non ho trovato altri modi di "fregare" il compilatore ) invece del parametro della classe template derivata (come verrebbe naturale pensare), e questo mi costringe a fare un sacco di cast.... magari dopo posto un po' di codice (non posso postare quello originale perchè è roba di lavoro e sono tenuto al riserbo... :stordita: ) adattato per far capire qual'è il problema....

ogni suggerimento sarà bene accetto, avevo intenzione di wrappare questi cast con un'ulteriore derivazione , ma questo è un palliativo perchè i cast ci sono sempre!

marco.r
06-09-2006, 23:17
(serve per lavoro) mi è venuta quest'idea;
Vorrei sapere se esistono controindicazioni derivando una classe template da una classe astratta NON TEMPLATE e usando il polimorfismo (nella fattispecie usare una puntatore a classe (astratta) per istanziare istanziazioni del template e biding dinamico sulle istanze delle istanziazioni......)
compilare compila....ma non tutto cioè che compila funziona (mentre cioè che funziona sicuramente compila :rolleyes: ).
Vediamo se ho capito il problema:
tu ha una classe base non template come la seguente

class Base {
virtual void* foo() = 0;
};

e vuoi derivarla nel seguente modo

template <typename T>
class Derived<T> : Base {
void* foo(){ /* blah */ }
};

per fare cose come la seguente

vector<Base*> v(10);
v[0] = new Derived<int>();
v[1] = new Derived<float>();
...
v[1]->foo();

Ho capito bene ? In questo caso non ci sono problemi nel farlo
Il problema del dover ritornare void* e' dovuto al fatto che le funzioni devono avere lo stesso tipo, forse potresti usare una classe base comune (nel tuo caso probabilmente proprio Base) al posto di void*.

class Base {
virtual Base* foo(Base*) = 0;
};

template <typename T>
class Derived<T> : Base {
Base* foo(Base* arg);
};

vector<Base*> v(10);
v[0] = new Derived<int>();
v[1] = new Derived<float>();
...
v[1]->foo(0);

O forse mi sfugge qualcosa (come e' probabile, non son sicuro di aver capito bene cosa intendi per "puntatore a classe") ? :mbe:
[disclaimer]: E' un bel po' che non programmo regolarmente in C++, perdonate eventuali errori e/o omissioni nel codice :p

BountyKiller
07-09-2006, 09:06
il problema è esattamente quello, e anch'io avevo pensato alla tua stessa soluzione prima di accorgermi che in quel modo modo si instaura un fenomeno ricorsivo infinito... appena ho tempo posto un codicillo che illustra il problema


Vediamo se ho capito il problema:
tu ha una classe base non template come la seguente

class Base {
virtual void* foo() = 0;
};

e vuoi derivarla nel seguente modo

template <typename T>
class Derived<T> : Base {
void* foo(){ /* blah */ }
};

per fare cose come la seguente

vector<Base*> v(10);
v[0] = new Derived<int>();
v[1] = new Derived<float>();
...
v[1]->foo();

Ho capito bene ? In questo caso non ci sono problemi nel farlo
Il problema del dover ritornare void* e' dovuto al fatto che le funzioni devono avere lo stesso tipo, forse potresti usare una classe base comune (nel tuo caso probabilmente proprio Base) al posto di void*.

class Base {
virtual Base* foo(Base*) = 0;
};

template <typename T>
class Derived<T> : Base {
Base* foo(Base* arg);
};

vector<Base*> v(10);
v[0] = new Derived<int>();
v[1] = new Derived<float>();
...
v[1]->foo(0);

O forse mi sfugge qualcosa (come e' probabile, non son sicuro di aver capito bene cosa intendi per "puntatore a classe") ? :mbe:
[disclaimer]: E' un bel po' che non programmo regolarmente in C++, perdonate eventuali errori e/o omissioni nel codice :p

tomminno
20-09-2006, 15:35
confermo dopo ulteriori test che l'idea funziona, l'unica cosa che non mi piace tanto è il fatto che il tipo di ritorno e i parametri dei metodi virtuali puri devono essere dei void* (almeno io non ho trovato altri modi di "fregare" il compilatore ) invece del parametro della classe template derivata (come verrebbe naturale pensare), e questo mi costringe a fare un sacco di cast.... magari dopo posto un po' di codice (non posso postare quello originale perchè è roba di lavoro e sono tenuto al riserbo... :stordita: ) adattato per far capire qual'è il problema....

ogni suggerimento sarà bene accetto, avevo intenzione di wrappare questi cast con un'ulteriore derivazione , ma questo è un palliativo perchè i cast ci sono sempre!

Mi ero dimenticato del thread...

Questa è la soluzione che ho adottato io:

class Base
{
private:
Base * mDerived;
public:
template <typename T> int Get(T*x, int nElements)
{
return ((Derived<T>*) mDerived)->Extract(x, nElements);
}
}

template <class T> class BaseT : public Base
{
private:
queue<T> mQueue;
public:
int Extract(T * x, int nElements)
{
//estrai da mQueue nElements se possibile, inseriscili in x e ritorna il numero di elementi estratti dalla coda.
}
}


Non mi è venuto in mente niente di meglio per cercare di istanziare una classe template a run-time.
Rimane sempre un cast al tipo della classe derivata, ma viene automaticamente determinato dal metodo template invocato. Senza cast non mi riesce.

BountyKiller
25-09-2006, 11:20
eccomi qua...sono rientrato dopo due settimane di ferie :cool: