struct A {
A(int) : i(new int(783)) {
std::cout << "a ctor" << std::endl;
}
A(const A& other) : i(new int(*(other.i))) {
std::cout << "a copy ctor" << std::endl;
}
~A() {
std::cout << "a dtor" << std::endl;
delete i;
}
void get() {
std::cout << *i << std::endl;
}
private:
int* i;
};
const A& foo() {
return A(32);
}
const A& foo_2() {
return 6;
}
int main()
{
A a = foo();
a.get();
}
Lo so, restituire i riferimenti ai valori locali è negativo. D'altro canto, il riferimento const dovrebbe estendere la durata di un oggetto temporaneo.Cosa succede esattamente quando si restituisce un riferimento const a un oggetto locale?
Questo codice produce un'uscita UB. Quindi nessuna estensione della vita.
Perché? Voglio dire qualcuno può spiegare cosa sta succedendo passo dopo passo?
Dov'è l'errore nella mia catena di ragionamento?
foo():
A (32) - ctor
ritorno A (32) - viene creato un riferimento const all'oggetto locale e viene restituito
A bis = pippo(); - a è inizializzato da foo() valore restituito, il valore restituito esce dall'ambito (fuori dall'espressione) e viene distrutto, ma a è già inizializzato;
(Ma in realtà distruttore viene chiamato prima copia costruttore)
foo_2():
ritorno 6 - Temp oggetto di tipo A è stato creato in modo implicito, un riferimento const a questo oggetto viene creato (estendendo la sua vita) e viene restituito
A a = foo(); - a è inizializzato da foo() valore restituito, il valore restituito esce dall'ambito (fuori dall'espressione) e viene distrutto, ma a è già inizializzato;
(ma in realtà distruttore viene chiamato prima costruttore di copia)
"il riferimento const dovrebbe estendere la durata di un oggetto temporaneo" <- erm, no quando si tratta di oggetti-lifetime i riferimenti non-const e const sono uguali e fanno * not * estenderlo. – Giel
Penso che questo sia ciò di cui Alexander sta parlando in termini di prolungamento della durata: http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/ – vmpstr
@Giel: No. Il riferimento Const ** può ** estendere la durata dell'oggetto temporaneo. I riferimenti constst e non const sono molto diversi quando si tratta di lavorare con i temporaries. In questo caso funziona solo diversamente da ciò che l'OP sembra aspettarsi. – AnT