[C++] Programma con costruttore di copia non compila
Salve a tutti! Negli esercizi pre-esame, mi sono imbattuto in una traccia in cui si chiede di gestire polimorfismo a run-time ed ereditarietà multipla con annesso problema del diamante su 4 classi che istanziano e gestiscono array a 2D dinamici. Allego il sorgente relativo a "matrice4", che eredita da "matrice3" e "matrice2":
I sorgenti per le altre classi "matrice1", "matrice2" e "matrice3" sono tutti uguali (a parte i dovuti pedici 1, 2 e 3), tranne che per i metodi [inline]void dealloc();[/inline] e [inline]void stampa();[/inline] e per l'implementazione di overload del costruttore di copia [inline]matrice4(const matrice4 &o)[/inline], inseriti nell'implementazione di "matrice4".
Arrivando al dunque, nel sorgente del main ho questo:
Facendo partire il programma, compilatore mi dà errore:
note: no match for 'operator=' (operand types are 'matrice4' and 'matrice1')
note: candidate is: matrice4& matrice4::operator=(const matrice4&)
note: no known conversion for argument 1 from 'matrice1' to 'const matrice4&'
Ho pensato si riferisse a [inline]m5=m1[/inline], quindi ho modificato con [inline]m5=m4[/inline], per rispettare le richieste del costruttore di copia, dato che richiede un argomento di tipo [inline]matrice4&[/inline]. Fatto ciò, il compilatore ha cominciato a darmi diversi errori del tipo:
undefined reference to `matrice1::matrice1(int, int, float)' e così via, tutti uguali
A cosa può essere dovuto questo comportamento? Vi ringrazio in anticipo
#ifndef matrice4_hpp #define matrice4_hpp #include <iostream> #include "matrice1.hpp" #include "matrice2.hpp" #include "matrice3.hpp" using namespace std; class matrice4: public matrice2, public matrice3 { protected: int r4; int c4; float ele4; int **M4; public: matrice4(); ~matrice4(); matrice4(int,int,float); void dealloc(); void stampa(); matrice4 (const matrice4&); matrice4 operator++(int); }; matrice4::matrice4() { cout << "matrice4 costruita\n"; } matrice4::~matrice4() { cout << "matrice4 distrutta\n"; } matrice4::matrice4(int R, int C, float ELE) { r4=R; c4=C; ele4=ELE; int i,j; M4=new int*[r4]; for(i=0;i<r4;i++) { M4[i]=new int[c4]; } for(i=0;i<r4;i++) { for(j=0;j<c4;j++) { M4[i][j]=ele4; } } } void matrice4::dealloc() { for(int i=0;i<r4;i++) delete[] M4[i]; delete[] M4; } void matrice4::stampa() { int i,j; for(i=0;i<r4;i++) { for(j=0;j<c4;j++) { cout << M4[i][j]; } } } matrice4::matrice4(const matrice4 &o) { r4=o.r4; c4=o.c4; ele4=o.ele4; int i,j; M4=new int*[r4]; for(i=0;i<r4;i++) { M4[i]=new int[c4]; } for(i=0;i<r4;i++) { for(j=0;j<c4;j++) { M4[i][j]=o.M4[i][j]; } } } matrice4 matrice4::operator++(int A) { int i,j; for(i=0;i<r4;i++) { for(j=0;j<c4;j++) { M4[i][j]=M4[i][j]+1; } } return *this; }
I sorgenti per le altre classi "matrice1", "matrice2" e "matrice3" sono tutti uguali (a parte i dovuti pedici 1, 2 e 3), tranne che per i metodi [inline]void dealloc();[/inline] e [inline]void stampa();[/inline] e per l'implementazione di overload del costruttore di copia [inline]matrice4(const matrice4 &o)[/inline], inseriti nell'implementazione di "matrice4".
Arrivando al dunque, nel sorgente del main ho questo:
// N.B. M è di tipo matrice1*, puntatore a oggetto base a cui assegnare l'indirizzo degli altri oggetti per il polimorfismo // m1 è di tipo matrice1 (ignoro il resto del codice perché non importante) matrice4 m5; m5=m1; m5++; M=&m5; M->stampa(); M->dealloc();
Facendo partire il programma, compilatore mi dà errore:
note: no match for 'operator=' (operand types are 'matrice4' and 'matrice1')
note: candidate is: matrice4& matrice4::operator=(const matrice4&)
note: no known conversion for argument 1 from 'matrice1' to 'const matrice4&'
Ho pensato si riferisse a [inline]m5=m1[/inline], quindi ho modificato con [inline]m5=m4[/inline], per rispettare le richieste del costruttore di copia, dato che richiede un argomento di tipo [inline]matrice4&[/inline]. Fatto ciò, il compilatore ha cominciato a darmi diversi errori del tipo:
undefined reference to `matrice1::matrice1(int, int, float)' e così via, tutti uguali
A cosa può essere dovuto questo comportamento? Vi ringrazio in anticipo
Risposte
Non esiste alcuna conversione da matrice1 a matrice4. Il polimorfismo permette semplicemente di usare puntatori alla classe base su istanze di una classe derivata, ma non c'è alcun modo per passare da una istanza della classe base a una della classe derivata. Non è neanche possibile (senza un cast esplicito) passare da un puntatore alla classe genitore ad uno alla classe figlia.
Potresti scrivere il testo dell'esercizio?