Ho visto numerosi argomenti che l'utilizzo di un valore di ritorno è preferibile ai parametri. Sono convinto dei motivi per cui evitarli, ma non sono sicuro di trovarmi nei casi in cui è inevitabile.Come evitare i parametri?
Part One della mia domanda è: Quali sono alcuni dei tuoi modi preferiti/comuni di spostarsi usando un parametro out? Stuff lungo le linee: uomo, nelle recensioni tra colleghi vedo sempre gli altri programmatori farlo quando avrebbero potuto farlo facilmente in questo modo.
Seconda parte della mia domanda riguarda alcuni casi specifici che ho riscontrato in cui vorrei evitare un parametro esterno ma non riesco a pensare a un modo pulito per farlo.
Esempio 1: Ho una classe con una copia costosa che vorrei evitare. Il lavoro può essere fatto sull'oggetto e questo crea l'oggetto per essere costoso da copiare. Il lavoro per costruire i dati non è esattamente banale. Attualmente, passerò questo oggetto in una funzione che modificherà lo stato dell'oggetto. Questo per me è preferibile a new'ing l'oggetto interno alla funzione worker e restituirlo indietro, in quanto mi permette di tenere le cose in pila.
class ExpensiveCopy //Defines some interface I can't change.
{
public:
ExpensiveCopy(const ExpensiveCopy toCopy){ /*Ouch! This hurts.*/ };
ExpensiveCopy& operator=(const ExpensiveCopy& toCopy){/*Ouch! This hurts.*/};
void addToData(SomeData);
SomeData getData();
}
class B
{
public:
static void doWork(ExpensiveCopy& ec_out, int someParam);
//or
// Your Function Here.
}
Utilizzando la mia funzione, vengo chiamando codice come questo:
const int SOME_PARAM = 5;
ExpensiveCopy toModify;
B::doWork(toModify, SOME_PARAM);
mi piacerebbe avere qualcosa di simile:
ExpensiveCopy theResult = B::doWork(SOME_PARAM);
Ma io non so se questo è possibile.
Secondo esempio: Ho una matrice di oggetti. Gli oggetti nell'array sono di tipo complesso e ho bisogno di lavorare su ogni elemento, lavoro che mi piacerebbe mantenere separato dal ciclo principale che accede a ciascun elemento. Il codice al momento è simile al seguente:
std::vector<ComplexType> theCollection;
for(int index = 0; index < theCollection.size(); ++index)
{
doWork(theCollection[index]);
}
void doWork(ComplexType& ct_out)
{
//Do work on the individual element.
}
Qualche suggerimento su come gestire alcune di queste situazioni? Io lavoro principalmente in C++, ma sono interessato a vedere se altre lingue facilitano una configurazione più semplice. Ho incontrato RVO come una possibile soluzione, ma ho bisogno di leggere di più su di esso e suona come una caratteristica specifica del compilatore.
La semantica di un parametro di riferimento non const è che verrà (può) essere modificata nella funzione. Se non avessi intenzione di cambiarlo, lo passeresti come riferimento const, dopotutto. – Bill
* "ma sono interessato a vedere se altre lingue facilitano una configurazione più semplice" * - linguaggi come Java e C# semplicemente non hanno questo problema dato che passano sempre i riferimenti agli oggetti in giro. –
Meravigliose risposte da parte di tutti. Ho avuto la sensazione che nei miei esempi specifici non ci sarebbe stata molta altra opzione.Ho visto post su SO da persone che sono così irremovibili su come evitare i parametri a tutti i costi. Speravo che forse uno di loro potesse approfondire il modo in cui ottengono una tale impresa. Per quanto riguarda RVO, sono un po 'titubante nell'usare caratteristiche specifiche del compilatore, dato che sarebbe difficile spiegare ai miei capi perché devo ridisegnare metà del mio codice perché non funziona più a causa di una caratteristica mancante come risultato di un modifica/aggiornamento del compilatore. –