È un punto cruciale, ma IMHO merita di essere compreso.
Tutte le lingue OO fanno sempre copie di riferimenti e non copiano mai un oggetto "invisibilmente". Sarebbe molto più difficile scrivere programmi se le lingue OO funzionassero diversamente. Ad esempio, funzioni e metodi non potrebbero mai aggiornare un oggetto. Java e la maggior parte dei linguaggi OO sarebbero quasi impossibili da usare senza una significativa complessità aggiunta.
Un oggetto in un programma dovrebbe avere un significato. Ad esempio rappresenta qualcosa di specifico nel mondo fisico reale. Di solito ha senso avere molti riferimenti alla stessa cosa. Ad esempio, il mio indirizzo di casa può essere dato a molte persone e organizzazioni e quell'indirizzo si riferisce sempre alla stessa posizione fisica. Quindi il primo punto è che gli oggetti spesso rappresentano qualcosa che è specifico, reale o concreto; e quindi essere in grado di avere molti riferimenti alla stessa cosa è estremamente utile. Altrimenti sarebbe più difficile scrivere programmi.
Ogni volta che si passa a
come argomento / parametro a un'altra funzione, ad esempio chiamando
foo(Dog aDoggy);
o si applica un metodo a
, il codice di programma sottostante crea una copia del riferimento, per produrre un secondo riferimento allo stesso oggetto.
Inoltre, se il codice con un riferimento copiato si trova in un thread diverso, entrambi possono essere utilizzati contemporaneamente per accedere allo stesso oggetto.
Quindi nella maggior parte dei programmi utili, ci saranno più riferimenti allo stesso oggetto, perché questa è la semantica della maggior parte dei linguaggi di programmazione OO.
Ora, se ci pensiamo, perché passare per riferimento è l' unico meccanismo disponibile in molti linguaggi OO (C ++ supporta entrambi), potremmo aspettarci che sia il comportamento predefinito "giusto" .
IMHO, l'utilizzo dei riferimenti è il valore predefinito predefinito , per un paio di motivi:
- Garantisce che il valore di un oggetto utilizzato in due luoghi diversi sia lo stesso. Immagina di inserire un oggetto in due diverse strutture di dati (array, elenchi ecc.) E di eseguire alcune operazioni su un oggetto che lo modifica. Potrebbe essere un incubo per il debug. Ancora più importante, è lo stesso oggetto in entrambe le strutture di dati o il programma ha un bug.
- È possibile convertire in modo felice il codice in più funzioni o unire il codice di più funzioni in una e la semantica non cambia. Se la lingua non fornisse la semantica di riferimento, sarebbe ancora più complesso modificare il codice.
C'è anche un argomento di efficienza; fare copie di interi oggetti è meno efficiente della copia di un riferimento. Tuttavia, penso che manchi il punto. I riferimenti multipli allo stesso oggetto hanno più senso e sono più facili da usare, poiché corrispondono alla semantica del mondo fisico reale.
Quindi, IMHO, di solito ha senso avere più riferimenti allo stesso oggetto. Nei casi insoliti in cui ciò non ha senso nel contesto di un algoritmo, la maggior parte delle lingue offre la possibilità di creare un "clone" o una copia approfondita. Tuttavia, questo non è il valore predefinito.
Penso che le persone che sostengono che questo non dovrebbe essere il default stiano usando un linguaggio che non fornisce la garbage collection automatica. Ad esempio, C ++ vecchio stile. Il problema è che devono trovare un modo per raccogliere oggetti "morti" e non recuperare oggetti che potrebbero essere ancora richiesti; avere più riferimenti allo stesso oggetto lo rende difficile.
Penso che se il C ++ avesse una garbage collection sufficientemente a basso costo, in modo che tutti gli oggetti referenziati fossero garbage collection, allora gran parte dell'obiezione scompare. Ci saranno ancora alcuni casi in cui la semantica di riferimento non è ciò che è necessario. Tuttavia, nella mia esperienza, le persone che sono in grado di identificare tali situazioni sono anche in genere in grado di scegliere comunque la semantica appropriata.
Credo che ci siano alcune prove che una grande quantità di codice in un programma C ++ è lì per gestire o mitigare la garbage collection. Tuttavia, scrivere e mantenere quel tipo di codice "infrastrutturale" aggiunge costi; è lì per rendere la lingua più facile da usare o più robusta. Quindi, ad esempio, il linguaggio Go è progettato con l'obiettivo di correggere alcuni dei punti deboli del C ++ e non ha altra scelta se non la garbage collection.
Ciò è ovviamente irrilevante nel contesto di Java. Anche questo è stato progettato per essere facile da usare, così come la raccolta dei rifiuti. Quindi avere più riferimenti è la semantica predefinita ed è relativamente sicura nel senso che gli oggetti non vengono recuperati mentre c'è un riferimento ad essi. Naturalmente potrebbero essere trattenuti da una struttura di dati perché il programma non riordina correttamente quando ha veramente finito con un oggetto.
Quindi, tornando indietro alla tua domanda (con un po 'di generalizzazione), quando vorresti più di un riferimento allo stesso oggetto? Praticamente in ogni situazione che mi viene in mente. Sono la semantica predefinita del meccanismo di passaggio dei parametri della maggior parte delle lingue. Suggerisco che ciò sia dovuto al fatto che la semantica predefinita della gestione degli oggetti che esiste nel mondo reale deve essere per riferimento (perché gli oggetti reali sono là fuori).
Qualsiasi altra semantica sarebbe più difficile da gestire.
Dog a = new Dog("rover"); // initialise with name
DogList dl = new DogList()
dl.add(a)
...
a.setOwner("Mr Been")
Suggerisco che il "rover" in dl
dovrebbe essere quello effettuato setOwner
o che i programmi diventino difficili da scrivere, comprendere, eseguire il debug o modificare. Penso che la maggior parte dei programmatori sarebbe perplessa o sconcertata altrimenti.
più tardi, il cane viene venduto:
soldDog = dl.lookupOwner("rover", "Mr Been")
soldDog.setOwner("Mr Mcgoo")
Questo tipo di elaborazione è comune e normale. Quindi la semantica di riferimento è l'impostazione predefinita perché di solito ha più senso.
Riepilogo: ha sempre senso avere più riferimenti allo stesso oggetto.