Proprio nel momento in cui pensavo di comprendere il riferimento di rvalue, mi sono imbattuto in questo problema. Il codice è probabilmente inutilmente lungo, ma l'idea è abbastanza semplice. C'è una funzione main() e la funzione returnRValueRef().Come funziona il ritorno per riferimento di rvalue?
#include <iostream>
#define NV(x) "[" << #x << "=" << (x) << "]"
#define log(x) cout << __FILE__ << ":" << __LINE__ << " " << x << endl
using namespace std;
class AClass {
public:
int a_;
AClass() : a_(0) {
log("inside default constructor");
}
AClass(int aa) : a_(aa) {
log("inside constructor");
}
int getInt() const {
return a_;
}
void setInt(int a) {
a_ = a;
}
AClass(AClass const & other) : a_(other.a_) {
log("inside copy constructor");
}
AClass & operator=(AClass const & rhs) {
log("inside assignment operator" << "left value" << NV(a_) << "right value" << NV(rhs.a_));
a_ = rhs.a_;
return *this;
}
AClass & operator=(AClass && rhs) {
log("inside assignment operator (rvalue ref)" << "left" << NV(a_) << "right" << NV(rhs.a_));
a_ = rhs.a_;
return *this;
}
};
AClass && returnRValueRef() {
AClass a1(4);
return move(a1);
}
int main() {
AClass a;
a = returnRValueRef();
}
Va bene, mi sarei aspettato questo codice alla prima stampa "all'interno costruttore di default" (per una), poi "dentro costruttore" (per A1), e quindi il messaggio operatore di assegnamento con rhs.a_ = 4. Ma l'uscita è
testcpp/return_rvalue_ref.cpp:14 inside default constructor
testcpp/return_rvalue_ref.cpp:17 inside constructor
testcpp/return_rvalue_ref.cpp:39 inside assignment operator (rvalue ref)left[a_=0]right[rhs.a_=0]
qualcuno può spiegare perché l'ultima riga nelle stampe in uscita right[rhs.a_=0]
invece di right[rhs.a_=4]
? Ho pensato che move() abbia appena fatto il valore di lvalue in rvalue senza cambiarne il contenuto. Ma mi manca chiaramente qualcosa.
Grazie mille per il vostro aiuto. :-)
Edit: Penso di sapere cosa potrebbe succedere. Può essere il distruttore per a1
nella funzione returnRValueRef()
viene chiamato quando esce dal campo di applicazione (anche se è convertito in valore), e dopo che la posizione di memoria per a1
(o il riferimento di valore per esso) contiene roba non definita! Non sono sicuro se questo è ciò che sta accadendo, ma sembra plausibile.
Grazie per il tuo commento. Mentre hai aggiunto il tuo commento, ho anche modificato la domanda e sembra che quello che hai detto sia il problema. Grazie. (Scusa, non posso revocare la tua risposta, troppo pochi punti.) –
@ YogeshwerSharma: solo un'accettazione sarebbe grandiosa, grazie! –
Esiste un esempio in cui è utile il ritorno per riferimento di rvalue? Non sembra essere? :( –