Se si dispone di una classe che ha molte, float
e enum
variabili membro, è considerato efficiente e/o buona pratica restituirle come riferimenti anziché come copie e restituire riferimenti costanti in cui non devono essere apportate modifiche? O c'è una ragione per cui dovrei restituirli come copie?È consigliabile restituire sempre i riferimenti per i getter della variabile membro?
risposta
Non vi è alcun motivo per restituire tipi primitivi come int
e float
per riferimento, a meno che non si desideri consentire loro di essere modificati. Restituirli per riferimento è in realtà meno efficiente perché non salva nulla (int
s ei puntatori di solito hanno le stesse dimensioni) mentre il dereferenziamento aggiunge effettivamente un sovraccarico.
E 'stato utile, grazie! – Jengerer
Ho una domanda, però. Quale dovrebbe essere considerato un giusto compromesso per l'utilizzo di un puntatore o di un riferimento? Ad esempio, un doppio è di 8 byte e un puntatore a un doppio è di 4 byte. Il sovraccarico aggiunto per il dereferenziamento supera le dimensioni inferiori? – Jengerer
Sì. La mia regola generale è di restituire direttamente i tipi primitivi, anche 'double'. Le classi vengono restituite come riferimenti const, anche piccoli. –
Questo è probabilmente per lo più una questione di stile o preferenza. Una ragione per non restituire riferimenti è perché stai usando getter e setter per permetterti di cambiare l'implementazione di quei membri, se hai cambiato un membro privato in un altro tipo, o lo hai rimosso completamente perché può essere calcolato, allora non hai più la possibilità di restituire un riferimento, poiché non c'è nulla a cui fare riferimento.
D'altra parte, restituire riferimenti per tipi non banali (classi composte) può velocizzare il codice un po 'per fare una copia, e puoi consentire a quei membri di essere assegnati attraverso il riferimento restituito (se lo si desidera).
Se sono riferimenti costanti, forse è OK. Se non sono riferimenti costanti, probabilmente no.
Per quanto riguarda l'efficienza - su una macchina a 64 bit, i riferimenti saranno quantità a 64 bit (puntatori sotto mentite spoglie); int
e float
e enum
saranno più piccoli. Se restituisci un riferimento, stai forzando un livello di riferimento indiretto; è meno efficiente.
Pertanto, in particolare per i tipi predefiniti come valori di ritorno, è generalmente preferibile restituire il valore anziché un riferimento.
Grazie per la risposta, ha aiutato! – Jengerer
Alcuni casi è necessario:
Guarda sovraccaricato operator[]
per qualsiasi classe. Di solito ha due versioni. La versione mutante deve restituire un riferimento.
int &operator[](int index); // by reference
int operator[](int index) const; // by value
In generale, è consentito consentire l'accesso ai membri della classe da parte di entità attendibili da una classe, ad es. amici. Nel caso in cui queste entità fidate abbiano anche bisogno di modificare lo stato, i riferimenti o i puntatori ai membri della classe, sono le uniche opzioni disponibili.
In molti casi, i riferimenti di solito semplificano la sintassi ad esempio dove 'v' è vettore STL.
v.at(1) = 2 vs *(v.at(1)) = 2;
Quasi, i riferimenti const sono migliori. Per intelli e simili non c'è motivo perché vorreste che fossero cambiati o perché hanno la stessa dimensione (o quasi) di un riferimento.
Quindi sì, è una buona idea. Preferisco un'altra lingua o per hackerare la mia roba in C++ e solo permettere alla var di essere pubblica (ancora una volta è solo la mia roba)
Certo, potrei renderli pubblici, ma alcuni di essi non dovrebbero essere accessibili pubblicamente poiché hanno determinate restrizioni per il valore che possono essere dati, e quindi li avvolgo con setter/getter per far rispettare quelle regole. Grazie per la risposta! – Jengerer
@Jenger: per regole molto semplici e autonome, puoi consentire al sistema di tipi di aiutarti. Ad esempio, invece di un campo 'int digit' e un setter che controlla che le cifre siano tra 0 e 9, potresti scrivere il tuo tipo' digit' che ha solo i valori da 0 a 9 e quindi usa un campo 'digit' pubblico nella tua classe, senza getter e setter. – fredoverflow
Jengerer: Sto dicendo che nel mio codice a casa lo farò dappertutto perché è mio e nessun altro (nessuno deve toccarlo). Inoltre, se la lezione è banale, lo farò al lavoro e, in effetti, nessuno si è lamentato. Ma non lavoro davvero sul C++ –
Questa è una domanda di prestazioni, ma per lo più da un punto di vista della robustezza direi è preferibile restituire valori anziché riferimenti const. Il motivo è che anche i riferimenti const indeboliscono l'incapsulamento.Considera questo:
struct SomeClass
{
std::vector<int> const & SomeInts() const;
void AddAnInt (int i); // Adds an integer to the vector of ints.
private:
std::vector<int> m_someInts;
};
bool ShouldIAddThisInt(int i);
void F (SomeClass & sc)
{
auto someInts = sc.SomeInts();
auto end = someInts.end();
for (auto iter = someInts.begin(); iter != end; ++iter)
{
if (ShouldIAddThisInt(*iter))
{
// oops invalidates the iterators
sc.AddAnInt (*iter);
}
}
}
Quindi nel caso abbia senso semanticamente e possiamo evitare allocazioni dinamiche eccessive, preferisco il ritorno per valore.
I getter sono per le emissioni di una classe dire Exhaust Car.emit()
, dove l'auto ha appena creato il Exhaust
.
Se si sono tenuti a scrivere const Seat& Car.get_front_seat()
di avere in seguito sedersi in Driver
, si può notare subito che qualcosa non va.
correcly, si preferisce scrivere Car.get_in_driver(Driver)
che poi chiama direttamente seat.sit_into(Driver)
.
Questo secondo metodo evita facilmente quelle situazioni imbarazzanti quando si è get_front_seat
ma la porta è chiusa e praticamente si spinge il guidatore attraverso la porta chiusa. Ricorda, hai solo chiesto un posto! :)
Tutto sommato: restituire sempre in base al valore (e fare affidamento sull'ottimizzazione del valore restituito), o rendersi conto che è ora di cambiare il progetto.
Lo sfondo: le classi sono state create in modo che i dati possano essere accoppiati con la sua funzionalità di accesso, localizzando bug ecc. Quindi le classi non sono mai attività, ma orientate ai dati.
Ulteriori insidie: in C++ se si restituisce qualcosa con const ref, quindi si può facilmente dimenticare che è solo un riferimento e una volta che il tuo oggetto è stato distrutto puoi essere lasciato con un riferimento non valido. Altrimenti, quell'oggetto verrà copiato una volta che lascia comunque il getter. Ma le copie non necessarie vengono evitate dal compilatore, vedere Return Value Optimization.
- 1. Posso usare i riferimenti const invece delle funzioni getter?
- 2. È consigliabile utilizzare i framework CSS?
- 3. È consigliabile utilizzare LINQ per sostituire i loop?
- 4. Il C++ supporta i riferimenti alle funzioni membro?
- 5. Perché i setter e i getter della proprietà si scontrano con i metodi get_X e set_X?
- 6. Sintassi per i riferimenti universali
- 7. Quando è consigliabile restituire un puntatore a una struttura?
- 8. Android: è efficiente memorizzare riferimenti a Views come variabili membro?
- 9. Variabile membro membro della classe derivata accesso in funzione virtuale
- 10. ignorando i getter/setter ereditari
- 11. Restituire copie di dati privati anziché riferimenti
- 12. È sempre consigliabile utilizzare elenchi di associazioni anziché record?
- 13. Perché il valore di un puntatore-membro è sempre lo stesso per i diversi membri della stessa struttura?
- 14. Quali sono i "riferimenti rvalue per * questo" per?
- 15. Is (* i) .Membro meno efficienti rispetto i-> membro
- 16. I riferimenti o i puntatori sono più veloci?
- 17. Riferimenti C#; Tenere nascosti i membri
- 18. Funzione membro variabile della classe template
- 19. È buona norma rimuovere i riferimenti per aiutare il GC?
- 20. I riferimenti di ritorno delle variabili membro sono una cattiva pratica?
- 21. La variabile di ritorno predefinita della funzione è sempre allocata?
- 22. L'inizializzazione della variabile membro C++ è protetta da thread?
- 23. Come è possibile controllare i nomi dei file per i riferimenti al servizio .NET?
- 24. Query Elasticsearch per restituire tutti i record
- 25. I riferimenti const ai membri sicuri sono
- 26. È consigliabile estrarre i valori letterali stringa in costanti in Javascript?
- 27. Valore di i per (i == -i && i! = 0) per restituire true in Java
- 28. Utilizzare i riferimenti della struttura dati più comunemente
- 29. Flusso C++ come variabile membro
- 30. Get xpath() per restituire i valori vuoti
Ho fatto una domanda correlata http://stackoverflow.com/q/3740876/15161 - forse le risposte ci aiuteranno. – slashmais
Domanda sbagliata. Migliore domanda: [È una cattiva idea avere getter di tutti i tuoi dati membri?] (Http://www.idinews.com/quasiClass.pdf) – sbi