Raccoglitori di rifiuti e riferimenti / riferimenti

1

Sono un po 'confuso su entrambi i puntatori e riferimento. Dal mio punto di vista, gli indicatori sono indirizzi nella memoria. Se passo una variabile usando i puntatori e il riferimento a una funzione, qualsiasi manipolazione della variabile nella funzione cambierà la variabile originale.

Ho letto online che il passaggio per riferimento non è incoraggiato perché può ottenere facilmente un codice disordinato. Leggo anche qui ( link ), che dovremmo evitare i puntatori se noi possiamo.

La mia domanda è quando dovrebbero essere usati puntatori e riferimenti? So che i puntatori sono usati in Xcode per riferimenti forti e conteggio dei riferimenti. Dal momento che linguaggi di livello superiore come c # hanno un garbage collector, vuol dire che non dovremmo mai usare puntatori e riferimenti in essi?

    
posta user1555300 31.07.2013 - 05:00
fonte

3 risposte

4

I am a little confused on both pointers and reference. From my understanding pointers are addresses in memory.

In generale, sono entrambi gli indirizzi in memoria. Di solito si parla di indicatori se l'aritmetica può essere fatta su di essi e di riferimenti se non, ma ci sono alcune varianti specifiche della lingua.

If I pass a variable using pointers and reference to a function, any manipulations of the variable in the function will change the original variable.

Sì.

Ma ci sono tre motivi per passare qualcosa per riferimento:

  1. Per evitare di copiare grandi quantità di dati nello stack.
  2. Per modificare la variabile originale.
  3. Per supportare il polimorfismo, poiché il codice generato non sa in anticipo quanto grande sarà l'oggetto e come copiarlo correttamente.

Il codice che utilizza la seconda opzione è sempre più difficile da leggere rispetto al codice che utilizza i valori restituiti e, se non viene utilizzato in modo coerente, è un modo sicuro per creare confusione reale. Per distinguere questo caso dagli altri due C ++ ha il modificatore const . Sfortunatamente Java e C # non lo fanno (e i loro autori non sembrano capire perché è utile, potrebbero avere qualcosa a che fare con il fatto che molte persone vendono const in C / C ++ come strumento di ottimizzazione che certamente non è ).

I read online that passing by reference is not encouraged because it can get messy code easily.

Le lingue di alto livello contengono tutto per riferimento, a causa del motivo 3 sopra. Possono passare il riferimento per valore (proprio come passare il puntatore in C, la funzione non può cambiare dove punta il puntatore, ma può cambiare il contenuto dell'oggetto puntato) o per riferimento (cioè puntatore-puntatore; la funzione può fare in modo che la variabile punti a oggetti diversi), ma è sempre un riferimento all'oggetto reale.

Java lo fa tranne i tipi numerici primitivi e C # lo fa per tutto ciò che è class .

Ma passare per riferimento per la ragione 2 sopra è davvero scoraggiato. Normalmente uno non si aspetta che la funzione modifichi gli argomenti, quindi meglio non farlo.

I also read here (https://stackoverflow.com/questions/7058339/c-when-to-use-references-vs-pointers), that we should avoid pointers if we can.

Questo è C ++ - specifico. I riferimenti non possono essere impostati su nullptr ( 0 nel vecchio C ++) quindi non devi controllare e i riferimenti non possono essere delete d, quindi non devi pensare se dovresti.

My question is when should pointers and reference be used?

Ovunque debbano essere.

I know pointers are used in Xcode for strong references and reference counting. Since, higher level languages like c# have garbage collector, does that mean we shouldn't ever use pointers and reference in them?

Le lingue gestite (C #, Java, ...) non hanno affatto i puntatori. I puntatori consentono l'accesso alla memoria non elaborata e ciò interferirebbe con il runtime gestito. Quindi non li hanno (C # fa, nello speciale, "unsave", estensione, per consentire l'interfacciamento con semplici vecchie librerie C).

Ma i riferimenti non possono essere non utilizzati in essi. Tutto è un riferimento. Perché la memoria allocata può essere gestita solo da puntatore / riferimento. E a causa del polimorfismo. Quindi tutte le variabili dei tipi di oggetto sono riferimenti in Java e C # e tutte le variabili sono riferimenti in qualsiasi cosa digitata dinamicamente come smalltalk, perl, python, ruby, javascript ecc.

    
risposta data 31.07.2013 - 10:01
fonte
1

Penso a un puntatore come ciò che viene restituito da "alloc" o equivalente. Nei sistemi reali, è in genere un riferimento a un blocco di memoria, ma non necessariamente. Passando i puntatori in giro completamente kosher, anche se la manipolazione non è stata prospettata degli oggetti puntati può essere disordinato.

Penso a un riferimento come puntatore che ho creato anziché allocare e per il quale "libero" non sarebbe appropriato. Usali estremamente cautamente, per esempio per restituire più valori da una funzione. È estremamente pericoloso da trattare un riferimento come un puntatore appropriato, perché se maltrattato il puntatore diventa una bomba ad orologeria, ad esempio prendendo un riferimento a una struttura allocata nello stack e consentendone il mantenimento quando il frame dello stack a cui fa riferimento viene recuperato.

    
risposta data 31.07.2013 - 08:03
fonte
1

Ci sono 3 ragioni principali per usare un puntatore

  1. In realtà vuoi modificare le cose che hai passato. Ad esempio, in una funzione di scambio, ti piacerebbe davvero scambiare le variabili con le tue date e non solo con le loro copie. Un esempio più comune qui è il this pointer / reference in C ++, C #, Java, ecc.

  2. Per qualsiasi ragione, copiare la tua argomentazione non è fattibile. Ad esempio, non vuoi copiare un intero nuovo elenco di 100000 elementi, è troppo lento. O se hai qualcosa che non dovrebbe essere copiato, come un mutex o qualche altra risorsa preziosa.

  3. Questo è molto meno comune ma a volte vuoi essere in grado di raggiungere e toccare effettivamente un pezzo di memoria casuale o un registro. Questo è molto raro ma abbastanza possibile nel codice abbastanza basso.

In questi casi, passa un riferimento ove possibile e un puntatore altrimenti. Generalmente preferisci i riferimenti ai puntatori, laddove possibile, poiché un puntatore può essere nullo.

    
risposta data 31.07.2013 - 08:50
fonte

Leggi altre domande sui tag