2012-06-10 9 views

risposta

31

Motivo n. 1 per scegliere struct vs class: le classi hanno ereditarietà, struct no. Se hai bisogno di polimorfismo, devi usare le classi.

Motivo n. 2: le strutture sono in genere tipi di valore (anche se è possibile renderli tipi di riferimento se ci si lavora). Le classi sono sempre tipi di riferimento. Quindi, se vuoi un tipo di valore, scegli una struttura. Se vuoi un tipo di riferimento, è più facile andare con una classe.

Motivo n. 3: Se si dispone di un tipo con molti membri di dati, probabilmente si vorrà un tipo di riferimento (per evitare una copia eccessiva), nel qual caso probabilmente si scegli una classe.

Motivo n. 4: Se si desidera la distruzione deterministica del proprio tipo, sarà necessario che sia una struttura in pila. Nulla sull'heap GC ha una distruzione deterministica, e i distruttori/finalizzatori di cose sull'heap GC potrebbero non essere mai eseguiti. Se vengono raccolti dal GC, i loro finalizzatori verranno eseguiti, ma altrimenti non lo faranno. Quindi, se vuoi che il tuo tipo venga automaticamente distrutto quando lascia l'ambito, devi usare una struct e metterlo in pila.

Per quanto riguarda il vostro caso particolare, i contenitori dovrebbero normalmente essere tipi di riferimento (copiare tutti i loro elementi ogni volta che ne passate uno in giro sarebbe follemente costoso), e un Stack è un contenitore, quindi vorrete usa una classe a meno che tu non abbia il problema di farne una struttura conteggiata, che è decisamente più efficace. Ha solo il vantaggio di garantire che il suo distruttore funzionerà quando non verrà più utilizzato.

Su una nota a margine, se si crea un contenitore che è una classe, probabilmente si vorrà renderlo definitivo in modo che le sue varie funzioni possano essere inline (e non saranno virtuali se quella classe non lo fa t derivano da qualsiasi cosa diversa da Object e non sono funzioni che ha Object), che può essere importante per qualcosa come un contenitore in cui le prestazioni possono sicuramente avere importanza.

+0

Supponiamo che la classe contenitore memorizzi tutti i valori in un tipo di nodo: se lo imposto come struct, ogni volta che rimuovo un nodo e il nodo stesso contiene un valore di riferimento (oggetto di una classe), verrà cancellato anche il riferimento? Esempio: Elenco! Oggetto lisObj; ... Oggetto ogg = nuovo oggetto; lisObj.add (obj) lisObj.remove (Obj); // obj esiste ancora? – Fred

+0

Solo per curiosità, quanto completa è la libreria Phobo per quanto riguarda i contenitori? Cosa ha e cosa manca? – Fred

+1

Tutto ciò che è stato assegnato con il nuovo è garbage collection. Se vuoi liberare qualcosa nello heap in un momento specifico, usa malloc e gratis per gestire la loro memoria. Per quanto riguarda i container di Phobos, sono in std.container, e al momento sono piuttosto scarsi, perché l'allocatore personalizzato viene ancora risolto, e stiamo aspettando che ciò avvenga prima di scrivere tutti i contenitori, perché altrimenti risulterebbe nel rifare un sacco di lavoro quando aggiungiamo gli allocatori personalizzati. Se i tipi built-in e std.container non sono sufficienti, dai un'occhiata a http://www.dsource.org/projects/dcollections –

5

Leggi "D"iving Into the D Programming Language

In D si ottiene le strutture e poi si arriva classi. Condividono molti servizi ma hanno carte differenti: le strutture sono tipi di valore, mentre le classi sono pensate per il polimorfismo dinamico e sono accessibili solo per riferimento. In questo modo confusioni, errori relativi alle affettazioni e commenti à la // No! NON ereditare! non esiste. Quando si progetta un tipo, si decide in anticipo se sarà un valore monomorfico o un riferimento polimorfico. C++ è famoso per la definizione di tipi di genere ambigui, ma il loro uso è raro, soggetto a errori e abbastanza discutibile da meritare semplicemente di eluderlo in base alla progettazione.

per il tipo Stack, si sono probabilmente meglio fuori che definisce un interface prima e poi le implementazioni della stessa (utilizzando class) in modo che non tie-in una particolare implementazione della vostra Stack tipo alla sua interfaccia.

+1

La definizione di un'interfaccia non è necessaria, poiché esiste una digitazione anatra (con controlli in fase di compilazione).Ad esempio, gli intervalli D possono essere utilizzati senza interfacce e in genere vengono implementati come strutture. –

+0

@ RomanD.Boiko: Ti riferisci ai modelli? Inoltre, 'interface's ha alcuni vantaggi. – dirkgently

+0

Sì, argomenti del modello vincolati. Ci sono vantaggi per entrambi gli approcci, ho appena affermato che l'uso delle interfacce non è necessario per evitare l'accoppiamento. –