Telefonino.net network
 
| HOMEPAGE | INDICE FORUM | REGOLAMENTO | ::. NEI PREFERITI .:: | RSS Forum | RSS News | NEWS web | NEWS software |
| PUBBLICITA' | | ARTICOLI | WIN XP | VISTA | WIN 7 | REGISTRI | SOFTWARE | MANUALI | RECENSIONI | LINUX | HUMOR | HARDWARE | DOWNLOAD | | CERCA nel FORUM » |

Torna indietro   WinTricks Forum > Software > Programmazione

Notices

Rispondi
 
Strumenti discussione
Vecchio 29-06-2004, 18.54.27   #1
GiulioCesare
Senior Member
 
L'avatar di GiulioCesare
 
Registrato: 02-04-2003
Loc.: Roma
Messaggi: 313
GiulioCesare promette bene
Costruttore di copia C++

Salve ragazzi sono alle prese con lo studio del costruttore di copia, se il mio libro non si sbaglia, i casi in cui è opportuno usarlo sono 3: quando un oggetto inizializza esplicitamente un altro oggetto, quando la copia di un oggetto viene passata come paramentro ad una funzione e quando viene generato un oggetto temporaneo, più comunemente come valore di restituzione. Premesso questo devo implementare una lista che si ritrovi in una delle 3 situazioni prima citate, per così utilizzare un costruttore di copia, ma non riesco a creare una situazione per metterlo in atto. Cosa vuol dire che un oggetto inizializza esplicitamente un altro, a cosa serve passare la copia di un oggetto ad una funzione e soprattutto perchè dovrei restituire un oggetto in una funzione? Spero che qualcuno vorrà aiutarmi a capire meglio come e perchè usare un costruttore di copia, grazie
GiulioCesare non è collegato   Rispondi citando
Vecchio 30-06-2004, 11.38.45   #2
P8257 WebMaster
Gold Member
 
Registrato: 07-01-2002
Loc.: Milano
Messaggi: 2.863
P8257 WebMaster promette bene
Ciao,
L'argomento è abbastanza complesso e capisco che molti manuali non diano l'esatta visione della cosa .. soprattutto a livello di "utilità" infatti dal tuo post si intende che forse più che il procedimento per utilizzarlo, non ne hai compreso l'utilità .. ed è invece molto importante.

Provo a fare un po' di chiarezza.

Partiamo da un esempio pratico:

Mettiamo il caso che io abbia una classe "Studente" con diversi metodi, attributi ecc. implementata a grandi linee come questa:

Codice:
class Studente
{
   public:
      Studente(char *, int);
      ~Studente();

      int Metodo1(...);
      void Metodo2(...);
}

Studente::Studente(char *Nome, int Anni) // constr.
{
   bla bla bla...
}

Studente::~Studente() // destr.
{
   delete[] _name;
}

Studente::Metodo1(...)
{
   bla bla bla...
}

Studente::Metodo2(...)
{
   bla bla bla...
}
Come potrai notare è solo un modello...

Ora passo alla creazione di un oggetto seguendo la logica del costruttore:

Codice:
Studente Primo("Marco", 12);
ed opero con l'oggetto...

Codice:
Mario.Metodo1(...);
Mario.Metodo2(...);
Fin qui .. tutto normale.. il mio oggetto fino a questo momento, si è fatto carico di svolgere operazioni a seconda della sua implementazione senza dare fastidio...

Supponiamo però che io abbia bisogno di creare un oggetto "parallelo" a questo con caratteristiche praticamente identiche sul quale però devo fare altre operazioni ..

per esempio potrei avere un altro oggetto studente di nome "Secondo" di età 12 ma su cui io non decida di applicare il "Metodo2" implementato nella mia classe e su cui io voglia agire diversamente.

Qualcuno potrebbe pensare di creare un oggetto a sé.. ma questo implica dover richiamare il costruttore, istanziare di nuovo le strutture interne della classe e sprecare tempo e risorse .. la potenza del C invece mi permette di costruire una copia esatta (copia bit per bit) dell'oggetto già istanziato e già allocato.

Qualcuno per logica potrebbe pensare che una cosa del genere si possa scrivere se voglio costruire una copia di Primo chiamata Secondo:

Codice:
Studente.Secondo(&Primo);
Cosa c'é di male?... qualcuno dirà.. : richiamo il costruttore e gli passo direttamente l'area di memoria contenente l'istanza di Primo, cosiche si possa costruire il secondo oggetto:

in realtà il risultato di questa espressione è UNA CATASTROFE perché vado a consegnare a Secondo direttamente la copia originale dell'oggetto Primo, l'oggetto Secondo continua quindi ad esistere anche se Primo dovesse per qualche motivo essere distrutto .. e se Primo fosse distrutto gli effetti sarebbero catastrofici in quanto Secondo punterebbe ad un'area di memoria non più referenziata.. questa espressione è quindi da DIMENTICARE.

Per ovviare a questo c'é il costruttore di copia appunto, cioè un'entità a che esegua una copia indpnedente dell'oggetto e non mi faccia lavorare più sull'originale:

Codice:
Studente(Studente &nome);
In questo caso, il costruttore Studente prende come parametro una nuova istanza dell'oggetto studente che verrà creata ancora prima di eseguire il costruttore stesso che poi procederà a completare l'opera.
In questo caso staremo sicuri che andremo ad operare con una copia indipendente e del tutto identica all'oggetto Primo... senza andare ad "intaccare" la versione originale.

Passare oggetti tra funzioni, chiamate ecc. è molto utile perché un oggetto conserva in se tutte le caratteristiche date dall'implementazione di classe e dall'applicazione in esso dei metodi consentiti.

Spero di non averti fatto fare confusione, questa è la mia visione del costruttore di copia .. io lo uso moderatamente (c'é il rischio di perdere traccia degli oggetti, soprattutto in fase di distruzione) .. ma ti assicuro che è molto importante e provvidenziale a volte.

Bye

Ultima modifica di P8257 WebMaster : 30-06-2004 alle ore 11.44.55
P8257 WebMaster non è collegato   Rispondi citando
Vecchio 30-06-2004, 11.41.44   #3
P8257 WebMaster
Gold Member
 
Registrato: 07-01-2002
Loc.: Milano
Messaggi: 2.863
P8257 WebMaster promette bene
La faccina "bastonata" leggasi: "::" naturalmente.

Non si potrebbe togliere il parsing delle emoticon nelle sezioni del tag CODE ?

Bye
P8257 WebMaster non è collegato   Rispondi citando
Vecchio 30-06-2004, 16.55.33   #4
GiulioCesare
Senior Member
 
L'avatar di GiulioCesare
 
Registrato: 02-04-2003
Loc.: Roma
Messaggi: 313
GiulioCesare promette bene
Ok grazie della spiegazione, ho provato ad implementare un costruttore di copia, in un programma con una lista e qui sono nati altri dubbi, devo fare una copia per ogni nodo ed elemento della lista, se è così significherebbe comunque dover creare un'altra lista? Ho provato a buttare giù un pò di codice, ma presenta degli errori, spero che qualcuno vorrà aiutarmi a capirli

#include <iostream>
using namespace std;
struct nodo
{
int dato;
struct nodo* next;
};
typedef struct nodo NODO;

class lista
{
private:
NODO* testa;
NODO* testa2;
NODO* scan;


public:
lista();
lista(const lista &ob);
~lista();
void creazione();
void canc();
void mostra();
};

lista::lista()
{
testa=NULL; testa2=NULL;
}

lista::lista(const lista &ob)
{
NODO* aux=testa; NODO* fine; NODO* scan;

while(aux)
{
scan= new (NODO);
*scan.dato=*ob.scan;
ob.scan=ob.scan.next;
aux=aux->next;
if(!testa2)
testa2=scan;
else
fine->next=scan;
fine=scan;
}


}

lista::~lista()
{
NODO* aux;

while(testa)
{
aux=testa;
testa=testa->next;
delete (aux);
}
}

void lista::creazione()
{
NODO* aux,fine;
int x;

cout<<"Inserire numero"<<endl;
cin>>x;

while(x)
{
aux= new (NODO);
aux->dato=x;
aux->next=NULL;
if(!testa)
testa=aux;
else
fine->next=aux;
fine=aux;
cout<<"Inserire numero"<<endl;
cin>>x;
}
}

void lista::canc()
{
NODO* aux=testa;

testa=testa->next;
delete(aux);
}

void lista::mostra()
{
NODO* aux=testa;

while(aux)
{
cout<<aux->dato<<endl;
aux=aux->next;
}
cout<<endl;
}

void mostra2(lista ob)
{

ob.mostra();
}

int main()
{
lista lista1,lista2;



lista1.creazione();
lista1.canc();
lista1.mostra();

lista2=lista1;

mostra2(lista2);

lista1.canc();

mostra2(lista2);





return 0;
}
GiulioCesare non è collegato   Rispondi citando
Vecchio 30-06-2004, 17.37.09   #5
P8257 WebMaster
Gold Member
 
Registrato: 07-01-2002
Loc.: Milano
Messaggi: 2.863
P8257 WebMaster promette bene
Ci sono un po' di errori di sinstassi anche .. l'hai buttato giù tu o l'hai copiato da qualche manuale?

Se puoi postare i messaggi di errore sarebbe meglio (per tutti quelli che vogliono darti una mano, me compreso), grazie.

Bye
P8257 WebMaster non è collegato   Rispondi citando
Vecchio 30-06-2004, 17.46.24   #6
GiulioCesare
Senior Member
 
L'avatar di GiulioCesare
 
Registrato: 02-04-2003
Loc.: Roma
Messaggi: 313
GiulioCesare promette bene
Ovviamente il codice l'ho fatto io, ecco gli errori che il compilatore segnala

copia.cpp: In copy constructor `lista::lista(const lista&)':
copia.cpp:39: request for member `dato' in `scan', which is of non-aggregate type `NODO*'
copia.cpp:40: request for member `next' in `ob->lista::scan', which is of non-aggregate type `NODO*'
copia.cpp: In member function `void lista::creazione()':
copia.cpp:80: base operand of `->' has non-pointer type `NODO'
copia.cpp:81: no match for `NODO& = NODO*&' operator
copia.cpp:4: candidates are: nodo& nodo:perator=(const nodo&)
GiulioCesare non è collegato   Rispondi citando
Vecchio 01-07-2004, 10.24.45   #7
P8257 WebMaster
Gold Member
 
Registrato: 07-01-2002
Loc.: Milano
Messaggi: 2.863
P8257 WebMaster promette bene
copia.cpp:39: request for member `dato' in `scan', which is of non-aggregate type `NODO*'

Nella definizione del tipo struttura, 'dato' non è un tipo aggregato a NODO, la struttura presenta una ricorsione interna in quanto contiene già "nodo", definici la struttura in maniera più lineare, il nome della struttura dopo la sua definizione evitando riferimenti interni prima della chiusura del "typedef".

Bye
P8257 WebMaster non è collegato   Rispondi citando
Vecchio 01-07-2004, 10.27.12   #8
P8257 WebMaster
Gold Member
 
Registrato: 07-01-2002
Loc.: Milano
Messaggi: 2.863
P8257 WebMaster promette bene
copia.cpp:40: request for member `next' in `ob->lista::scan', which is of non-aggregate type `NODO*'

Stessa cosa, membro non aggregato, riferimento a "next" prima del completamento della sua definizione.

Bye
P8257 WebMaster non è collegato   Rispondi citando
Vecchio 01-07-2004, 10.31.25   #9
P8257 WebMaster
Gold Member
 
Registrato: 07-01-2002
Loc.: Milano
Messaggi: 2.863
P8257 WebMaster promette bene
copia.cpp:80: base operand of `->' has non-pointer type `NODO'

Se costruisci NODO, non hai un puntatore in ritorno, opera direttamente con l'operatore '.'

Bye
P8257 WebMaster non è collegato   Rispondi citando
Rispondi


Utenti attualmente attivi che stanno leggendo questa discussione: 1 (0 utenti e 1 ospiti)
 
Strumenti discussione

Regole di scrittura
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is ON
Gli smilies sono ON
[IMG] è ON
Il codice HTML è OFF

Vai al forum

Discussioni simili
Discussione Autore discussione Forum Risposte Ultimo messaggio
Masterizzare una copia di back up del s.o. fisiologohifi Masterizzazione Giochi Games 6 14-12-2006 17.15.20
RIAA: ma quale diritto di copia? Macao Segnalazioni Web 0 20-02-2006 01.15.03
perchè il masterizzatore non copia più? AIUTO haliaeetus Hardware e Overclock 1 10-12-2005 21.44.08
Copia privata, si può ??? Macao Segnalazioni Web 12 15-10-2004 19.17.23
vecchi trucchi ma su xp? top gun Windows 7/Vista/XP/ 2003 13 02-03-2004 11.31.48

Orario GMT +2. Ora sono le: 00.09.37.


E' vietata la riproduzione, anche solo in parte, di contenuti e grafica.
Copyright © 1999-2017 Edizioni Master S.p.A. p.iva: 02105820787 • Tutti i diritti sono riservati
L'editore NON si assume nessuna responsabilità dei contenuti pubblicati sul forum in quanto redatti direttamente dagli utenti.
Questi ultimi sono responsabili dei contenuti da loro riportati nelle discussioni del forum
Powered by vBulletin - 2010 Copyright © Jelsoft Enterprises Limited.