Domanda

Ho andare una domanda molto semplice, ma purtroppo non riesco a capire la risposta me stesso.

Si supponga che ho delle struttura dati che contiene le impostazioni e si comporta come una mappa delle impostazioni. Ho un metodo GetValue(const std::string& name), che restituisce il valore corrispondente.

Ora sto cercando di capire - che tipo di approccio improntato al rendimento valore sarebbe meglio. I mezzi più ovvia che fanno il mio metodo di agire come

std::string GetValue(const std::string& name) const

e restituisce una copia dell'oggetto e si basano su RVO di significati prestazioni.

L'altro significherebbe fare due metodi

std::string& GetValue(...)
const std::string& GetValue(...) const

che generalmente significa duplicare codice o utilizzando alcuni calchi male costanti da utilizzare una di queste routine due volte.

#Q

Qual 'è la scelta in questo tipo di situazione e perché?

È stato utile?

Soluzione

In realtà avrei probabilmente usare:

std::string GetValue(const std::string& name) const;
// or
const std::string* GetValue(const std::string& name) const;

void SetValue(std::string name, std::string value);

Setter prima:

  • Passando in valore SetValue consente al compilatore alcune ottimizzazioni che non possono essere fatte con passaggio da const riferimento, è stato spiegato in un articolo di Dave Abrahams, "Voglia di velocità? passaggio per valore".
  • Utilizzo di un Setter di solito è meglio, perché è possibile controllare il valore di essere impostato mentre con un riferimento chiaro si ha alcuna garanzia che il chiamante non fare niente di stupido con i dati.

Per il getter:

  • Tornando dalla copia sembra uno spreco in quanto il più delle volte non si modificare l'oggetto restituito (per impostazioni della mappa), tuttavia puntatore o riferimento voglio dire che l'oggetto alias vivrà abbastanza a lungo, se non è possibile garantire che poi il punto è discutibile: il ritorno per valore. Anche copiare permettono di evitare di esporre un dettaglio interno, ad esempio se si dovesse improvvisamente di passare a std::wstring perché avete bisogno di alcune impostazioni in UTF-8 ...
  • Se avete bisogno di prestazioni, allora siete pronti a fare alcune concessioni in questo reparto. Tuttavia un riferimento non consente di segnalare l'assenza della proprietà (a meno che non si dispone di un certo valore magico) mentre il puntatore rende facile (NULL è già tagliato fuori per voi).

Altri suggerimenti

Questo dipende dall'uso. Dovrebbe GetValue("foo") = "bar" senso? In tal caso, il ritorno per valore non fa quello che si vuole.

Se è possibile restituire per riferimento const, vero. L'unica ragione per tornare una classe di memoria con capacità di gestione come std :: string per valore è perché è una stringa temporanea.

Questo è un punto molto "sensibili" di C ++. IMHO è uno dei punti più deboli del design C ++. AFAIK non c'è davvero un'ottima scelta, che sarà sia guardare ed eseguire bene.

Un punto che va menzionato che l'ottimizzazione RVO fa di solito solo una parte del lavoro. Senza di essa una tipica espressione in questo modo:

std::string txt = GetValue("...");

sarà effettivamente produrre 2 copie! Dipende dal compilatore, ma di solito RVO elimina ottimizzazione una sola copia, ma l'altro è ancora lì.

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