2010-05-01 12 views
15

Stavo solo riflettendo sul numero di domande che riguardano i "tre grandi" (costruttore di copie, operatore di assegnazione e distruttore) o problemi causati da non essere implementati correttamente, quando ho pensato che non potevo ricorda l'ultima volta che li ho implementati io stesso. Un rapido accenno ai miei due progetti più attivi indica che li implemento tutti e tre in una sola classe su circa 150.Con quale frequenza realizzi i tre grandi?

Ciò non vuol dire che non attui/dichiaro uno o più di essi - ovviamente le classi base necessitano di un distruttore virtuale, e un gran numero delle mie classi proibisce di copiare usando il codec privato & assegnazione per idioma. Ma completamente implementato, c'è questa singola classe solitaria, che fa un conteggio dei riferimenti.

Quindi mi chiedevo di essere insolito in questo? Quanto spesso implementate tutte e tre queste funzioni? Esiste qualche schema per le classi in cui le implementate?

+2

Leggere questa domanda mi rende così felice che non devo scrivere in C++! (Naturalmente, questo probabilmente spiega perché ho difficoltà a modificare il C++ degli altri.) –

+6

-1 @Norman Non c'è bisogno di andare contro C++. Se non devi scrivere codice C++ vai ad altra domanda. Non ho mai capito le persone che, poiché non usano qualcosa, vogliono che nessuno le usi e viceversa. –

+4

@Norman L'avrei pensato (e le risposte) sono incoraggianti - raramente hai bisogno di svolgere un compito complesso. –

risposta

2

Penso che sia raro che siano necessari tutti e tre. La maggior parte delle classi che richiedono un distruttore esplicito non sono realmente adatte alla copia.

È solo una progettazione migliore utilizzare membri autodistruggenti (che di solito non richiedono elementi come la copiatura) di un grande distruttore esplicito.

+0

L'idioma pImpl è un controesempio comunemente utilizzato. –

+0

std :: auto_ptr lo gestisce. – Puppy

+0

DeadMG: sei sicuro? – Joshua

1

Come te, quasi mai.

Ma io non sono legato all'approccio STL della programmazione in cui si copia tutto dentro e intorno in contenitori - in genere se non è un primitivo, userò un puntatore, intelligente o meno.

Uso principalmente i pattern RAII, evitando così la scrittura di distruttori. Anche se, metto corpi vuoti nel mio file .cc per aiutare a mantenere il codice in esaurimento.

E, come te, li dichiarerò privati ​​e non implementati per evitare invocazioni accidentali.

+4

Eh? I distruttori sono la pietra angolare di RAII. O intendi che usi esclusivamente le classi RAII scritte da altri? –

+0

I corpi delle funzioni vuoti causano meno ingombro del codice se si trovano nel file di intestazione in modo che possano essere allineati. Ma non riesco a immaginare perché definire un distruttore vuoto. – Potatoswatter

+0

@Ben Voigt, ovviamente sì, i distruttori sono fondamentali per Raii ... ma di solito non ho bisogno di scrivere le mie classi RAII, e quando uso i membri di Ravi, non ho bisogno di ripulirli nei distruttori. – Stephen

1

Raramente li implemento, ma spesso li dichiaro privati ​​(copia i costruttori e gli operatori assignemt, cioè).

0

La maggior parte delle volte, quasi mai. Questo perché i membri che vengono utilizzati (riferimento basato su smart ptr, ecc.) Implementano già la semantica corretta, oppure l'oggetto non è copiato.

Alcuni modelli arrivano quando mi ritrovo attuare questi:

  1. distruttiva copia, cioè modello mossa come auto_ptr o bloccare
  2. dispose modello che difficilmente tutti viene in su in C++, ma ho usato è circa tre volte nella mia carriera (e solo una settimana fa infatti)
  3. modello Pimpl, in cui il pimpl è dichiarato fwd nell'intestazione e gestito da un ptr intelligente. Quindi il dtor vuoto va nel file .cc ma continua a classificarsi come "non generatore generato"

E un altro banale che stampa "Sono stato distrutto" quando penso che potrei avere un riferimento circolare da qualche parte e voglio solo assicurarsi.

0

Dipende davvero da che tipo di problemi si sta lavorando. Ho lavorato a un nuovo progetto negli ultimi mesi e penso che ogni classe erediti da boost :: noncopyable. Nove mesi fa ho lavorato su un progetto diverso che utilizzava i POD un bel po 'e io ho sfruttato l'operatore di copy e ctor automatico.Se stai usando boost :: shared_ptr (e dovresti esserlo), al giorno d'oggi dovrebbe essere raro scrivere il tuo operatore di copyctor o di assegnazione.

0

Qualsiasi classe proprietaria di alcuni puntatori, i membri devono definire queste tre operazioni per implementare la copia profonda (vedere here per una descrizione approfondita).

+0

Non si tratta di possedere i puntatori, ma di possedere ciò che indicano. Una classe può contenere un puntatore senza proprietà e in questo caso probabilmente non ha bisogno dei tre grandi. E io sono molto anti-termine "copia profonda" - c'è solo un tipo di operazione di copia - quella corretta. –

+0

@Neil Butterworth: in precedenza hai commentato una mia risposta che il termine "copia profonda" non è di grande utilità. (Vedi qui: http://stackoverflow.com/questions/2657810/2657824#2657824) In quell'altra discussione non hai detto esplicitamente che "esiste un solo tipo di operazione di copia, quella corretta". Sono curioso: quale sarebbe? Quello corretto in un caso particolare o una soluzione generale? – stakx

+0

@stakx Quello corretto per la classe particolare, che potrebbe essere profondo, superficiale o più probabile da qualche parte nel mezzo. –

Problemi correlati