[C++] Programma con costruttore di copia non compila

robe921
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":

#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
apatriarca
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.

vict85
Potresti scrivere il testo dell'esercizio?

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.