Passare i parametri che devono essere copiati in base al valore o al riferimento const

7

Ho una classe vettoriale (matematica) di base, che a mio parere beneficia dell'overloading dell'operatore di C ++. Le operazioni scalari vettoriali sono definite come funzioni auto modificanti nella classe stessa,

class Vec3i {
  Vec3i& operator+=(int const n) {
    for (int i = 0; i < 3; ++i) {
      _data[i] += n;
    }
  }
  std::array<int, 3> _data;
};

e come funzioni libere non modificabili. Per questi posso vedere due opzioni quando si tratta di passare nel vettore.

// By value, meaning an implicit copy.
Vec3i operator+(Vec3i lhs, int const rhs) {
  return (lhs += rhs);
}

// By const reference, copying manually.
Vec3i operator+(Vec3i const& lhs, int const rhs) {
  auto result = lhs;
  return (result += rhs);
}

Ci sono buone ragioni per preferire una variante rispetto all'altra? Preferisco avere il parametro const (constando tutto ciò che non sarà mai modificato), ma la variante di valore è ben concisa. O dovrei semplicemente iniziare a leggere il valore-by come implicitamente const?

    
posta Kolja 15.12.2014 - 23:57
fonte

3 risposte

5

Nel vecchio C ++ (pre C ++ 11), non vi è alcuna differenza significativa tra le due implementazioni di operator+ . Il costruttore della copia viene chiamato quando si richiama l'operatore o quando si esegue la copia esplicita all'interno dell'operatore.
In questo caso, è più un problema di preferenze personali / linee guida per la codifica quale scegliere.

Con l'introduzione dei costruttori di spostamenti in C ++ 11, il caso del pass-by-value ha guadagnato un vantaggio, perché ciò consente di costruire il parametro usando il costruttore di copie o il costruttore di movimento, a seconda di cosa l'operatore viene invocato con.
Per la tua classe Vec3i , la differenza non è così grande, ma se hai classi che mantengono risorse allocate dinamicamente, l'uso appropriato dei costruttori di mosse può ridurre significativamente la quantità di memoria di cui l'applicazione ha bisogno.

    
risposta data 16.12.2014 - 10:07
fonte
2

Questo è probabilmente un po 'supponente, ma se vedo due alternative equivalenti nel codice, di solito preferisco quella con meno "rumore". Nel tuo caso, la differenza della seconda alternativa alla prima è solo in "rumore" aggiuntivo - codice tecnico che non migliora la leggibilità in alcun modo. Ecco perché preferirei la prima variante.

or should I simply start to read by-value as implicitly const

Dovresti leggere le funzioni con argomenti "di valore" come liberi da effetti collaterali, se è questo che intendevi.

    
risposta data 16.12.2014 - 08:17
fonte
0

Mi piacerebbe adottare l'approccio basato sul valore.

Forse in questo caso non ha importanza in quanto Vec3i è economico da copiare, ma in generale questo consentirebbe di costruire il valore lhs da rvalue con un costruttore di mosse, rimuovendo così qualsiasi copia di oggetti.

    
risposta data 16.12.2014 - 09:36
fonte

Leggi altre domande sui tag