Visualizzazione dei risultati da 1 a 9 su 9
  1. #1
    Utente di HTML.it L'avatar di zuffff
    Registrato dal
    Sep 2004
    Messaggi
    40

    [c++] costruttori di copia classi derivate

    Ho creato la classe atleta:

    codice:
    class atleta
    {
    	char *nome,*cognome;
    	int peso;
    public:
    	atleta() {nome=NULL;cognome=NULL;};
    	atleta(char *n,char *c,int p);
    	atleta(const atleta &obj);
    	~atleta();
    };
    successivamente derivo da questa la classa calciatore:

    codice:
    class calciatore : public atleta
    {
    	char *ruolo;
    	int stipendio;
    public:
    	calciatore():atleta(){ruolo=NULL;};
    	calciatore(char *n,char *c,char *r,int p, int s);
    	calciatore(const calciatore &obj);
    	~calciatore();
    };
    il costruttore di copia di atleta è:

    codice:
    atleta::atleta(const atleta &obj)
    {
    	nome=new char[strlen(obj.nome)+1];
    	if(!nome)
    		exit(1);
    	cognome=new char[strlen(obj.cognome)+1];
    	if(!nome)
    		exit(1);
    	peso=obj.peso;
    }
    il problema è il seguente:
    nel costruttore di copia di calciatore voglio sfruttare il costruttore di copia di atleta senza riscrivere i parametri uno per uno. come faccio?
    grazie
    La teoria è quando si sa tutto ma non funziona niente.
    La pratica è quando funziona tutto ma non si sa il perché.
    In ogni caso si finisce sempre con il coniugare la teoria con la pratica:
    non funziona niente e non si sa il perché.
    (Albert Einstein)

  2. #2
    Hai provato con ?
    codice:
      calciatore::calciatore(const calciatore &obj)
       : atleta(obj)
      {
      }

  3. #3
    Utente di HTML.it L'avatar di zuffff
    Registrato dal
    Sep 2004
    Messaggi
    40
    non ci avevo proprio pensato grazie
    visto che ci sei mi dici il distruttore?
    thanks
    La teoria è quando si sa tutto ma non funziona niente.
    La pratica è quando funziona tutto ma non si sa il perché.
    In ogni caso si finisce sempre con il coniugare la teoria con la pratica:
    non funziona niente e non si sa il perché.
    (Albert Einstein)

  4. #4
    Se intendi dire che vuoi richiamare il distruttore di atleta dal distruttore di calciatore...lo fa il compilatore in automatico ma devi definire il distruttore come virtual:
    codice:
    virtual ~atleta();
    Non serve il virtual nelle classi derivate.
    Prova un po'

  5. #5
    Utente di HTML.it L'avatar di zuffff
    Registrato dal
    Sep 2004
    Messaggi
    40
    grazie
    La teoria è quando si sa tutto ma non funziona niente.
    La pratica è quando funziona tutto ma non si sa il perché.
    In ogni caso si finisce sempre con il coniugare la teoria con la pratica:
    non funziona niente e non si sa il perché.
    (Albert Einstein)

  6. #6
    Utente di HTML.it L'avatar di zuffff
    Registrato dal
    Sep 2004
    Messaggi
    40
    Originariamente inviato da fastcoder
    Se intendi dire che vuoi richiamare il distruttore di atleta dal distruttore di calciatore...lo fa il compilatore in automatico ma devi definire il distruttore come virtual:
    codice:
    virtual ~atleta();
    Non serve il virtual nelle classi derivate.
    Prova un po'
    ho provato ma eseguendo il debug vedo che di fatto chiama solo il distrutore di calciatore

    codice:
    calciatore::~calciatore()
    {
    	if (ruolo) delete [] ruolo;
    }
    il distruttore di atleta non viene chiamato anche se definito come virtual
    codice:
    atleta::~atleta()
    {
    	if (nome) delete [] nome;
    	if (cognome) delete [] cognome;
    }
    inoltre visto che sei disponibile volevo sapere se esiste un modo migliore per definire l'operatore = di calciatore :

    codice:
    calciatore calciatore::operator=(calciatore obj)
    {
    	atleta *p;
    	p=this;evitando di scivere queste istruzioni per chiamare l'operatore = di atleta
    	*p=obj;
    	if(strlen(obj.ruolo)>strlen(ruolo))
    	{
    		delete [] ruolo;
    	    ruolo=new char [strlen(obj.ruolo)+1];
    		if(!ruolo)
    			exit(1);
    	}
    	strcpy(ruolo,obj.ruolo);
    	return *this;
    }
    grazie ancora
    La teoria è quando si sa tutto ma non funziona niente.
    La pratica è quando funziona tutto ma non si sa il perché.
    In ogni caso si finisce sempre con il coniugare la teoria con la pratica:
    non funziona niente e non si sa il perché.
    (Albert Einstein)

  7. #7
    Sinceramente è strano...ho provato con il visual studio questo esempio ed i distruttori vengono chiamati nell'ordine corretto.
    codice:
    // test.cpp : definisce il punto di ingresso dell'applicazione console.
    //
    
    #include "stdafx.h"
    #include <windows.h>
    
    class clsTest
    {
    private:
      int a;
    public:
      clsTest(int _a)
      {
        a = _a;
      }
      clsTest(clsTest &s)
      {
        a = s.a;
      }
      virtual ~clsTest()
      {
        printf("clsTest destructor\r\n");
      }
      bool someFunc(CHAR *s)
      {
        printf("OK: %d\r\n", a);
        return true;
      }
    };
    
    class clsTest1 : public clsTest
    {
    public:
      clsTest1() : clsTest(5)
      {
      }
      clsTest1(clsTest1 &s)
        : clsTest(s)
      {
      }
      ~clsTest1()
      {
        printf("clsTest1 destructor\r\n");
      }
    };
    
    int _tmain(int argc, _TCHAR* argv[])
    {
      {
        clsTest1 tmp_t1;
        clsTest1 tmp_t2(tmp_t1);
    
        tmp_t1.someFunc("");
        tmp_t2.someFunc("");
      }
      getchar();
    
      return 0;
    }
    Direi che l'operatore non e' corretto. Prima di tutto deve accettare un const reference altrimenti si mette a chiamare costruttori di copia inutilmente per creare oggetti temporanei; per lo stesso motivo deve ritornare un reference all'oggetto. Quindi:
    codice:
    calciatore &calciatore::operator=(const calciatore &obj)
    {
    	atleta *p;
    	p=this;evitando di scivere queste istruzioni per chiamare l'operatore = di atleta
    	*p=obj;
    	if(strlen(obj.ruolo)>strlen(ruolo))
    	{
    		delete [] ruolo;
    	    ruolo=new char [strlen(obj.ruolo)+1];
    		if(!ruolo)
    			exit(1);
    	}
    	strcpy(ruolo,obj.ruolo);
    	return *this;
    }
    Poi sinceramente non capisco l'uso di p. Se è per richiamare l'operatore= di atleta puoi chiamarlo direttamente così:
    codice:
    calciatore &calciatore::operator=(const calciatore &obj)
    {
            atleta::operator=(obj);
    	if(strlen(obj.ruolo)>strlen(ruolo))
    	{
    		delete [] ruolo;
    	    ruolo=new char [strlen(obj.ruolo)+1];
    		if(!ruolo)
    			exit(1);
    	}
    	strcpy(ruolo,obj.ruolo);
    	return *this;
    }
    un operatore non è altro che una normale funzione se non per il fatto che il compilatore sa come chiamarla in maniera implicita. Con l'operatore di scope non fai altro che forzare la chiamata dell'operator= di atleta.

  8. #8
    Utente di HTML.it L'avatar di zuffff
    Registrato dal
    Sep 2004
    Messaggi
    40
    ok, funziona;
    però non capisco l'utilità di dichiarare il distruttore di atleta virtual; mi sembra che funzioni anche senza.
    inoltre (date le mie scarse conoscenze) non capisco bene come funzione questa istruzione
    atleta:perator=(obj); anche se funziona perfettamente. Nn dovrebbe restituire un valore?

    infine è corretto anche scrivere
    atleta *p;
    p=this;
    *p=obj;
    al posto di atleta:perator=(obj);
    anche se di fatto è meno elegante.
    grazie
    La teoria è quando si sa tutto ma non funziona niente.
    La pratica è quando funziona tutto ma non si sa il perché.
    In ogni caso si finisce sempre con il coniugare la teoria con la pratica:
    non funziona niente e non si sa il perché.
    (Albert Einstein)

  9. #9
    Sì, funziona anche senza il virtual...erano reminescenze di tempi lontani in cui (non so bene se con Delphi o il C++) se non dichiaravo il distruttore virtual non veniva chiamato. Probabilmente con i nuovi conpilatori va come deve andare (cioè senza il virtual)
    Certo che ritorna un valore...un reference alla porte di atleta presente in calciatore...il fatto che però lo ritorni non significa nulla...non lo usi perchè in effetti quello che ti interessa non è il valore di ritorno ma l'operazione dell'operatore
    Scrivere
    codice:
    atleta *p;
    p=this;
    *p=obj;
    credo che sia la stessa cosa...prendi la parte atleta di calciatore e poi richiami l'operatore ==. Credo che sia la stessa cosa (se funziona )


Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.