Newsgroup: it.comp.lang.c++
Titolo: Polimorfismo

 Dove sbaglio? C'e' una soluzione alternativa?
Si tratta di un errore abbastanza comune, a giudicare dai post ho visto in
passato sull'argomento. Un container standard di T contiene oggetti che
sono esattamente di tipo T. I metodi che consentono l'inserimento di
valori, accettando argomenti di tipo T&, funzionano ovviamente con oggetti
di classi derivate, ma dopo il primo costruttore copia o assegnamento nel
container non resterà traccia dell'oggetto originario. Se poi la classe
base Function avesse avuto metodi virtuali puri, vector<Function> non
sarebbe stata neppure instanziabile.
L'alternativa è usare un vector di puntatori a Function. Se poi vuoi una
semantica analoga a qualla di vector<T> e preservare comunque il
polimorfismo, puoi adottare una soluzione come quella ho abbozzato sotto
(priva di molti dettagli che andrebbero implementati):
 template< class I >
 struct ptr_iterator
 {
  typedef iterator_traits<I>::value_type    ptr_value_type; 
  typedef iterator_traits<ptr_value_type>   ptr_value_it_traits;
  typedef typename ptr_value_it_traits::value_type   value_type;
  I	i_;
  ptr_iterator(const I& i ) : i_(i) { }
  value_type&	operator*() 	{ return *(*i_); }//nota la doppia deref.
  value_type*	operator->() 	{ return  *i_; 	}
  operator++()	{ ++curr_; }
  bool operator==(const ptr_iterator& i ) const { return i_==i.i_;}
 };
 template< class T >
 class pvector
 {
  typedef vector<T*>	vector_type;
  typedef ptr_iterator< typename vector_type::iterator > iterator;
  typedef typename iterator::value_type	 value_type;
 
  vector_type	v_;
  public:	
  iterator	begin() { return iterator( v_.begin() ); }
  iterator	end() { return iterator( v_.end() ); }
  template<class T0>
   void push_back( const T0& t )
   {  v_.push_back( new T0(t) ); // creo copia allocata dinamicamente
    }
  value_type& operator[](int i) { return *(v_[i]); }
 
  ~pvector() { /* qui dovremmo ciclare in v_ e deallocare gli elementi*/ }
 };
A questo punto siamo in grado di compilare qualcosa di molto simile al tuo
codice iniziale ed ottenere anche l'effetto desiderato:
 
 int main() {
   pvector<Function> vct;
    F1 f1;
    F2 f2;
    vct.push_back(f1);
    vct.push_back(f2);
    cout<<(vct[0])(2)<<endl;  // stampa 6!
    cout<<(vct[1])(2)<<endl;  // stampa 10!
  return 0;
 };
Max

Salve,
ho il problema di dover creare un vector di funzioni (di una variabile) con
un operatore per la valutazione in un punto.Pensavo di sfruttare
l'ereditarieta' come segue ma come output ottengo Nan anziche' 6.
class Function {
 public:
          virtual double operator()(double x){}
};
class F1:public Function {
 public:
   virtual double operator()(double x){return 3.*x;}
};
class F2:public Function {
 public:
   virtual double operator()(double x){return 5.*x;}
};


Ciao Cristian,
prova cosi´:
#include <vector>
#include <iostream>
using namespace std;
class Function
{
public:
          virtual double operator()(double x){return 10.0*x;}
};
class F1:public Function {
public:
   virtual double operator()(double x){return 3.0*x;}
};
class F2:public Function {
public:
   virtual double operator()(double x){return 5.0*x;}
};
int main()
{
   vector<Function *> vct;
   F1 f1;
   F2 f2;
   Function *f;
   vct.push_back(&f1);
   vct.push_back(&f2);
   for (int i = 0; i < 2; i++)
   {
      f = vct[i];
      cout<< (*f)(2)<<endl;
   }
   return 0;
};
Mauro

Vi ringrazio moltissimo per i suggerimenti.