PDA

Visualizza la versione completa : [C++] Come si crea un costruttore di copia per una classe derivata?


19semplicemente
29-06-2005, 16:04
salve...
vi espongo il problema..

ho tre classi.. A B e C

C eredita da A e B

ho definito costruttori per A, B e C e un costruttore di copia per C.

però... il compilatore mi da sempre questo errore:

error C2512: 'A' : no appropriate default constructor available
error C2512: 'B' : no appropriate default constructor available

cosa sbaglio??

grazie

netarrow
29-06-2005, 17:48
mostra del codice

:ciauz:

19semplicemente
29-06-2005, 17:53
// classe club (base)
class club {
char squadra[80];
char serie[2];


public:
club(char *sq, char *se) {
strcpy(squadra, sq);
strcpy(serie,se);
}


club(const club &l){
strcpy(squadra, l.squadra);
}
};


//classe ing (derivata da giocatore)
class engage {
int anno_inizio;
int anno_fine;
double inga;

public:

engage(int ai, int af, double ing){
anno_inizio = ai;
anno_fine = af;
inga = ing;
}

engage(const engage &o){
}

double getengage() { return (inga / (anno_inizio-anno_fine));}

};


//classe giocatore (derivata da club)
class giocatore : public club, public engage {

char nome[50];
char cognome[50];
char data_nascita[20];
char luogo_nascita[50];

public:


giocatore(char *sq, char *se, int ai, int af, double ing, char *n, char *c,char *dn, char *ln) : club(sq, se), engage(ai, af, ing){

strcpy(nome,n);
strcpy(cognome,c);
strcpy(data_nascita,dn);
strcpy(luogo_nascita,ln);
}


giocatore(const giocatore &ogg) {

}


char *getname(){return nome;}
char *getcogn() {return cognome;}

friend void stampa_engage(giocatore obj);
};


ostream &operator << (ostream &stream, giocatore obj){

stream << obj.getname() << " " << obj.getcogn() << "\n";

return stream;
}


void stampa_engage(giocatore obj){

cout << "il suo ingo annuo è di: " << obj.getengage();
}

int main(){
// giocatore maldini("Milan", "A", 2000, 2006, 20000000, "Paolo", "Maldini", "12 Aprile 1975", "Milano");



return 0;
}

netarrow
29-06-2005, 19:02
usa CODE la next time, la prima cosa che ho notato è che dichiari e implementi subito.

In teoria si deve fare



class Classe {

public:
Classe();
virtual ~Classe();
int m1();
int m2();
private:
int i;
double a;

};


e dopo creare le implementazioni:



Classe::Classe() {
//code
}

int Classe::m1() {
//code
}


Meglio se metti i protopiti in un file .h



edit:
poi c'è un altro "errore", che è più che altro un illogicheria, un giocatore non estende il suo stipendio e il suo club :confused:
Quando erediti c'è una relazione di tipo "is a", ma in questo caso un Club rispetto al giocatore ha una relazione di tipo "has a" perchè il primo possiede il secondo, mentre lo stipendio lo si potrebbe astrarre in più modi, essendo cmq una cosa che il giocatore "ha", sarebbe da usare solo incapsulamento qui non ereditarietà. Per esercizi come questi non da problemi, ma per progetti più grandi sbagliare questa fase di impostazione del progetto ti fa crollare tutto dopo :zizi:

:ciauz:

19semplicemente
29-06-2005, 19:16
il problema mi si presenta anche con due classi...

praticamente se A è una derivata di B...e sia per A che per B creo un costruttore di copia.. poi lui mi dice che non c'è un costruttore appropriato per A.

dovrei forse usare una sintassi particolare quando dichiaro il costruttore di copia di una classe derivata, come si fa nel caso del costruttore normale?

grazie

netarrow
29-06-2005, 20:18
Sembra essere risolto, il problema era che alcuni costruttori non avevano niente dentro e mancavo la chiamata al costruttore della superclasse(o non so il termine tecnico in C++).

Ho diviso in due file per gestire meglio il tuo codice che era al quanto disortinato:

Classi.h


#include <iostream.h>
#include <string.h>

// classe club (base)
class club {
protected:
char squadra[80];
char serie[2];
public:
club(char *sq, char *se);
club( club &l);
};
//FINE dichiarazioni


club::club(char *sq, char *se) {
strcpy(squadra, sq);
strcpy(serie,se);

}

club::club( club &l) {
strcpy(squadra, l.squadra);
}
//FINE club




//classe engage
class engage {
protected:
int anno_inizio;
int anno_fine;
double inga;
public:
engage(int ai, int af, double ing);
engage(const engage &o);
double getengage();
};
//FINE dichiarazioni


engage::engage(int ai, int af, double ing) {
anno_inizio = ai;
anno_fine = af;
inga = ing;
}

engage::engage(const engage &o) {
anno_inizio = o.anno_inizio;
anno_fine = o.anno_fine;
inga = o.inga;
}

double engage::getengage() {
return (inga / (anno_fine-anno_inizio));
}
//FINE engage





//classe giocatore
class giocatore : public club, public engage {
protected:
char nome[50];
char cognome[50];
char data_nascita[20];
char luogo_nascita[50];

public:
friend void stampa_engage(giocatore obj);
giocatore(char *sq, char *se, int ai, int af, double ing,
char *n, char *c,char *dn, char *ln);
giocatore(giocatore &ogg);
char *getname();
char *getcogn();
};
//FINE dichiarazioni


giocatore::giocatore(char *sq, char *se, int ai, int af, double ing,
char *n, char *c,char *dn,
char *ln) : club(sq, se), engage(ai, af, ing) {

strcpy(nome,n);
strcpy(cognome,c);
strcpy(data_nascita,dn);
strcpy(luogo_nascita,ln);
}

giocatore::giocatore(giocatore &ogg) : club(ogg.squadra, ogg.serie),
engage(ogg.anno_inizio, ogg.anno_fine,
ogg.inga) {
strcpy(nome,ogg.nome);
strcpy(cognome,ogg.cognome);
strcpy(data_nascita, ogg.data_nascita);
strcpy(luogo_nascita, ogg.data_nascita);
}

char* giocatore::getname() {
return nome;
}

char* giocatore::getcogn() {
return cognome;
}

void stampa_engage(giocatore obj){
cout << "il suo ingo annuo è di: " << obj.getengage();
}
//FINE giocatore


e naturalmente un file cpp che ho originalmente chiamato a.cpp

a.cpp


#include "Classi.h"


int main() {

giocatore maldini("Milan", "A", 2000, 2006,
5000000, "Paolo", "Maldini",
"12 Aprile 1975", "Milano");

cout << maldini.getcogn() << endl;
cout << maldini.getengage() << endl;
cout << maldini.getname() << endl;

return 0;
}



Ho provato compila con 0 errori 0 warning e funziona quando lo provo.

:ciauz:

19semplicemente
29-06-2005, 21:16
scusami.. ho inserito una funzione friend per controllare quando avviene la chiamata ai costruttori di copia..
ma praticamente... non li chiama :bhò:
mi sa che occorre inserire per forza const.. ci ho provato ma mi da errore...



#include <iostream.h>
#include <string.h> // classe club (base)
class club {
protected:
char squadra[80];
char serie[2];
public:
club(char *sq, char *se);
club(const club &l);
};
//FINE dichiarazioni


club::club(char *sq, char *se) {
strcpy(squadra, sq);
strcpy(serie,se);

}

club::club(const club &l) {
strcpy(squadra, l.squadra);
cout << "costruttore di copia club";
}
//FINE club




//classe engage
class engage {
protected:
int anno_inizio;
int anno_fine;
double inga;
public:
engage(int ai, int af, double ing);
engage(const engage &o);
double getengage();
};
//FINE dichiarazioni


engage::engage(int ai, int af, double ing) {
anno_inizio = ai;
anno_fine = af;
inga = ing;
}

engage::engage(const engage &o) {
anno_inizio = o.anno_inizio;
anno_fine = o.anno_fine;
inga = o.inga;
cout << "costruttore di copia engage";
}

double engage::getengage() {
return (inga / (anno_fine-anno_inizio));
}
//FINE engage





//classe giocatore
class giocatore : public club, public engage {
protected:
char nome[50];
char cognome[50];
char data_nascita[20];
char luogo_nascita[50];

public:
friend void stampa_engage(giocatore obj);
giocatore(char *sq, char *se, int ai, int af, double ing,
char *n, char *c,char *dn, char *ln);

giocatore(giocatore &ogg);

char *getname();
char *getcogn();

friend void funzione(giocatore obj);

};
//FINE dichiarazioni

void funzione(giocatore obj){
cout << obj.anno_fine;
}

giocatore::giocatore(char *sq, char *se, int ai, int af, double ing,
char *n, char *c,char *dn, char *ln) :
club(sq, se), engage(ai, af, ing) {

strcpy(nome,n);
strcpy(cognome,c);
strcpy(data_nascita,dn);
strcpy(luogo_nascita,ln);
}

giocatore::giocatore( giocatore &ogg) : club(ogg.squadra, ogg.serie),
engage(ogg.anno_inizio,
ogg.anno_fine,
ogg.inga) {

strcpy(nome,ogg.nome);
strcpy(cognome,ogg.cognome);
strcpy(data_nascita, ogg.data_nascita);
strcpy(luogo_nascita, ogg.data_nascita);
}

char* giocatore::getname() {
return nome;
}

char* giocatore::getcogn() {
return cognome;
}

void stampa_engage(giocatore obj){
cout << "il suo ingo annuo è di: " << obj.getengage();
}
//FINE giocatore

int main() {

giocatore maldini("Milan", "A", 2000, 2006,
5000000, "Paolo", "Maldini",
"12 Aprile 1975", "Milano");



cout << maldini.getcogn() << endl;
cout << maldini.getengage() << endl;
cout << maldini.getname() << endl;

funzione(maldini);

return 0;
}

19semplicemente
30-06-2005, 09:38
ok... ho trovato come risolvere... grazie cmq

Loading