2015-10-29 12 views
8

Voglio passare un oggetto di Classe A (chiamarlo a) per riferimento (nel senso ampio, ovvero tramite A & o A *) al costruttore di un'altra Classe B. I non voglio che 'a' sia modificato all'interno di B ('a' è di sola lettura ed è di grandi dimensioni ed è per questo che voglio passarlo per riferimento). So di due opzioni:Passaggio per opzioni di riferimento in C++

1) Pass 'un' come

const A & a_ 

2) Pass 'un' come

const A * a_ 

Lo svantaggio dell'opzione 1 è che posso erroneamente passare un r-value. Lo svantaggio dell'opzione 2 è che posso erroneamente passare un puntatore nullo.

Le mie domande sono: 1) Ho ragione sugli svantaggi sopra? 2) C'è un altro modo consigliato di passare 'a' per riferimento?

Ho visto le risposte nel link sottostante. Ma sono curioso di sapere se ci sono altre opzioni oltre a ciò che viene pubblicato in quella domanda. Are there benefits of passing by pointer over passing by reference in C++?

+5

Come probabile è che si passa erroneamente un valore di R, e quanto grave sarà le conseguenze di tale azione sarebbe? – emlai

+1

Se hai le tue preoccupazioni e conosci i problemi, hai bisogno di un controllo degli errori. Passa per riferimento e prova/cattura. Se lo fai con un puntatore, modificherai l'istanza originale del tuo oggetto. –

+1

Che cos'è un valore? È un'uguaglianza indefinita? Ti piace un lvalue? –

risposta

18

Passaggio const A &.

È possibile impedire il passaggio accidentale dei valori dichiarando un sovraccarico di rvalue di tale funzione = delete. Per esempio:

struct A { }; 

void func(const A & a) { } 
void func(A && a) = delete; 

int main() 
{ 
    A a; 
    func(a); // compiles 
    func(A()); // doesn't compile 
} 
+1

C'è un problema spinoso in cui mi sono imbattuto quando ho a che fare con questo: se si vuole veramente disabilitare * tutti * i rvalues, è meglio usare 'void func (const A &&) = delete;' invece. Sembra strano e sporco, ma fa il lavoro.Questo perché altrimenti il ​​codice legacy che ritorna con il valore 'const' (non raccomandato, ma sfortunatamente usato frequentemente in funzioni di fabbrica) si collegherà a' func (const &); 'invece. Correlato: http://stackoverflow.com/q/33244951/3093378 – vsoftco

4

Date un'occhiata a std::reference_wrapper 's costruttori: http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper/reference_wrapper

E' un costruttore in più eliminato che prende riferimento rvalue, quindi se si tenta di passare un rvalue ad esso, che il costruttore vince la risoluzione di sovraccarico e si ottiene un errore.

È possibile fare la stessa cosa: dichiarare entrambi i costruttori const A& e A&& ed eliminare quest'ultimo. Quindi nessuno sarà in grado di passare in un valore.

-3

Il codice:

#include <iostream> 
using namespace std; 

struct A 
{ }; 

int func_one(A& var) { 
    A * insertVal=new A; 
    if (&var==nullptr) 
     return 0; 
    else 
     return 1; 
} 

int main() { 
    A refVar; 
    int x; 
    x=func_one(refVar); 

    return 1; 
} 
+2

Questo non viene compilato. – emlai

+0

Perché? Nessuna struttura? –

+2

Prova a compilarlo, controlla quali errori ottieni e risolvi prima quelli. Una risposta di solo codice con codice non valido non è molto utile. – emlai

Problemi correlati