[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?