Trovi i riferimenti invisibili quando esegui la scansione del codice e ci sono delle linee guida sulla codifica per il loro utilizzo?

3

Ho sviluppato l'abitudine di usare costrutti C ++ sicuri, laddove possibile, ma c'è un posto in cui non sono sempre sicuro se sia meglio usare riferimenti o ricorrere a buoni puntatori.

Codice di esempio:

int FillFancyPointer(char *&ptr)
{
    ptr = NULL;

    char *tmp_ptr = static_cast<char*>(calloc(...));
    if(!ptr)
        return -1;

   ptr = tmp_ptr;
   return 0;
}

Codice successivo:

char *ptr = nullptr;
if(FillFancyPointer(ptr)>=0 && ptr)
   Nice();

Il problema con questo, IMHO, è che il ptr sembra essere di sola lettura variabile quando si guarda il codice, mentre in realtà è modificato.

L'approccio COM ISmthn *ptr; , CoCreate(..., &ptr) sembra più pronunciato. Ma è anche più incline agli errori, dato che c'è questa roba ** ovunque.

A pensarci bene, anche le variabili di output come std::string saranno mascherate con tale approccio.

int Foo(const string &in, string &inout)

Trovate riferimenti confusi in tali luoghi?

    
posta Coder 13.12.2011 - 19:42
fonte

3 risposte

4

Il problema con il tuo esempio di codice non è che tu prendi un riferimento, è che usi un codice di ritorno. In C ++, se l'operazione fallisce, lancia un'eccezione o, se ciò non è insolito, usa boost::optional o anche boost::variant<T, ErrorCode> .

Il tuo codice è molto C e non C ++ affatto.

    
risposta data 22.12.2011 - 16:52
fonte
2

Se sei preoccupato per la mutabilità, fai riferimento a const a meno che non debbano essere mutabili, e lascia perdere. Il nome e la documentazione di una funzione dovrebbero comunicare il suo scopo e se intende modificare uno dei suoi parametri.

Gli utenti della funzione non dovrebbero aver bisogno di preoccuparsi se qualcosa viene passato per valore o riferimento; la "invisibilità" dei riferimenti, che hanno la stessa sintassi dei valori, è uno dei loro punti di forza . Il motivo per cui si introducevano i riferimenti a C ++ era in primo luogo quello di "invisibilmente" supportare il sovraccarico dell'operatore. Oltre alla loro consistenza, sono anche suscettibili alla programmazione generica , che è una grande cosa nel mondo C ++. E in C ++ 0x, diventa più interessante: puoi passare variabili sintatticamente in base al valore, ma possono essere costruite in movimento, eliminando la necessità di una copia.

    
risposta data 13.12.2011 - 20:51
fonte
1

Tutto ciò che riguarda l'esempio di codice è C e non C ++. Penso che tu abbia problemi maggiori rispetto al fatto che tu stia passando un puntatore per riferimento o meno. Ad esempio, suggerirei di usare new e delete piuttosto che malloc.

Per rispondere direttamente alla tua domanda, usa i riferimenti ovunque puoi e i puntatori quando devi, cioè quando hai bisogno di riposizionare il riferimento. Tutto questo è nelle FAQ del C ++ che è una miniera di informazioni brillanti.

    
risposta data 22.12.2011 - 15:51
fonte

Leggi altre domande sui tag