Domanda

Ho imparato in Collegio che è sempre gratis i tuoi Oggetti inutilizzati, ma non come è realmente in grado di farlo.Per esempio strutturare il codice a destra e così via.Ci sono regole generali su come gestire i puntatori in C++?

Sto attualmente non è consentito utilizzare il boost.Io sono a bastone per puro c++ perché il framework che sto utilizzando vieta qualsiasi uso di farmaci generici.

È stato utile?

Soluzione

Ho lavorato con incorporato sistema operativo Symbian, che ha avuto un ottimo sistema per questo, basato interamente su developer convenzioni.

  1. Un solo oggetto non avranno mai un puntatore.Per impostazione predefinita, questo è il creatore.
  2. La proprietà può essere trasmesso.Per indicare il passaggio di proprietà, l'oggetto viene passato come puntatore nella firma del metodo (ad es.void Foo(Bar *zonk);).
  3. Il proprietario deciderà se eliminare l'oggetto.
  4. Il passaggio di un oggetto a un metodo solo per l'uso, l'oggetto passato come riferimento nella firma del metodo (ad es.void Foo(Bat &zonk);).
  5. Non-proprietario classi possono memorizzare i riferimenti (mai puntatori a oggetti che vengono dati solo quando essi possono essere certi che il proprietario non distruggere durante l'uso.

In sostanza, se una classe si usa semplicemente qualcosa, si utilizza un riferimento.Se una classe è proprietario di qualcosa, si utilizza un puntatore.

Questo ha funzionato benissimo ed è un piacere da usare.I problemi di memoria sono stati molto rari.

Altri suggerimenti

Regole:

  1. Ove possibile, utilizzare un puntatore intelligente.Boost ha alcune quelli buoni.
  2. Se si non è possibile utilizzare un puntatore intelligente, null fuori il puntatore del mouse dopo l'eliminazione.
  3. Mai lavorare ovunque, che non permette di utilizzare la regola 1.

Se qualcuno non consente la regola 1, ricordatevi che se si afferra il codice di qualcun altro, cambiare i nomi delle variabili e cancellare le note di copyright, nessuno mai notato.A meno che non si tratta di un progetto per la scuola, in cui effettivamente verificare che tipo di imbrogli con strumenti sofisticati.Vedi anche, questa domanda.

Vorrei aggiungere un'altra regola qui:

  • Non nuovo/eliminare un oggetto quando un oggetto automatico farà bene.

Abbiamo trovato che i programmatori che sono nuovi per C++, o i programmatori provenienti da linguaggi come Java, sembrano conoscere nuovi e ossessivamente usarlo ogni volta che si desidera creare qualsiasi oggetto, a prescindere dal contesto.Ciò è particolarmente pericoloso quando un oggetto viene creato localmente all'interno di una funzione puramente per fare qualcosa di utile.Utilizzando di nuovo in questo modo possono essere dannosi per le prestazioni e può rendere tutto troppo facile per introdurre stupide perdite di memoria quando il corrispondente eliminare è dimenticato.Sì, puntatori intelligenti possono aiutare con questi ultimi, ma non risolvere i problemi di prestazioni (supponendo che new/delete o un equivalente è utilizzato dietro le quinte).È interessante notare che (beh, forse), abbiamo trovato che elimina spesso tende ad essere più costoso di nuovo quando si utilizza Visual C++.

Parte di questa confusione nasce anche dal fatto che le funzioni che chiamano potrebbe prendere puntatori, o anche smart puntatori come argomenti (quando i riferimenti forse sarebbe meglio/più chiaro).Questo li fa pensare che hanno bisogno di "creare" un puntatore (un sacco di persone sembrano pensare che questo è ciò che nuovo non) per essere in grado di passare un puntatore a una funzione.Chiaramente, questo richiede un po ' di regole su come le Api sono scritti per rendere convenzioni di chiamata esplicita, che sono rinforzati con chiara i commenti forniti con il prototipo di funzione.

Nel caso generale (gestione delle risorse, in cui la risorsa non è necessariamente memoria), è necessario avere familiarità con il RAII modello.Questo è uno dei più importanti pezzi di informazioni per gli sviluppatori C++.

In generale, evitare di allocare dal mucchio meno che non è necessario.Se necessario, utilizzare il conteggio dei riferimenti per gli oggetti che sono di lunga durata e hanno bisogno di essere condivisi tra le diverse parti del codice.

A volte è necessario allocare gli oggetti in modo dinamico, ma solo entro un certo lasso di tempo.Per esempio, in un progetto precedente, avevo bisogno di creare una complessa rappresentazione in memoria di uno schema di database-fondamentalmente un complesso grafico ciclico di oggetti.Tuttavia, il grafico era necessario solo per la durata della connessione al database, dopo di che tutti i nodi può essere liberato in un colpo solo.In questo tipo di scenario, un buon modello da utilizzare è qualcosa che io chiamo il "GC locale idioma." Non so se ha un nome "ufficiale", in quanto è qualcosa che ho visto solo nel mio codice, e nel Cacao (vedere NSAutoreleasePool Apple Cacao di riferimento).

In sintesi, si crea un "collezionista" oggetto che mantiene i puntatori agli oggetti temporanei che si alloca risorse nuove.Di solito è legato ad alcune ambito del programma, una statico ambito di applicazione (ad es.-- come una pila assegnati oggetto che implementa l'RAII idioma) o dinamico (ad es.-- legati al ciclo di vita di una connessione di database, come nel mio precedente progetto).Quando il "collezionista" oggetto viene liberato, il suo distruttore libera tutti gli oggetti che punti alla.

Inoltre, come DrPizza penso che la restrizione di non utilizzare i modelli è troppo dura.Tuttavia, dopo aver fatto un sacco di sviluppo su antiche versioni di Solaris, AIX, HP-UX e solo recentemente - sì, queste piattaforme sono ancora vivi nella Fortuna 50), posso dirti che se davvero a cuore la portabilità, si devono utilizzare i modelli meno possibile.Il loro utilizzo per i contenitori e i puntatori intelligenti dovrebbe essere ok, anche se (che per me ha funzionato).Senza modelli la tecnica che ho descritto è più difficili da implementare.Sarebbe necessario che tutti gli oggetti gestiti da "collettore" derivano da una classe base comune.

G ' day,

Suggerisco di leggere le relative sezioni di "effective C++" di Scott Meyers.Di facile lettura e si copre alcuni interessanti trucchi per intercettare gli incauti.

Anche io sono incuriosito dalla mancanza di modelli.Quindi non STL o Boost.Wow.

BTW Raggiungere un accordo sulla base di convenzioni è un'ottima idea.Come è mettere tutti d'accordo sulle convenzioni per gli ALLAGAMENTI.BTW L'ultima edizione di " effective C++ non ha l'ottimo capitolo sulle ALLUVIONI, le convenzioni, la prima edizione che è un peccato, ad esempio,convenzioni tra pubblico e l'ereditarietà virtuale sempre modelli di una "isa" rapporto.

Rob

  • Quando si devono gestire la memoria manualmente, assicurarsi di chiamare eliminare nella stessa ambito di applicazione/funzione/classe/modulo, che mai si applica prima, ad es.:
  • Lasciare che il chiamante di una funzione di allocare la memoria che è riempito da esso, non tornare di nuovo sui puntatori.
  • Sempre chiamata eliminare nello stesso exe/dll, come è chiamato di nuovo, perché altrimenti si possono avere problemi con l'heap corruzioni (differenti e incompatibili librerie di runtime).

si potrebbe derivare tutto da una classe di base per implementare il puntatore intelligente come funzionalità (utilizzando ref()/unref() metodi e di un contatore.

Tutti i punti evidenziati da @Timbo sono importanti durante la progettazione che la classe base.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top