A doit être liée référence à une longue durée de vie lvalue
. Fondamentalement, comme vous le dites si éloquemment, un objet qui a une adresse définie. Si elles sont liées à un temporaire, le temporaire sera détruit pendant que la référence le référencera encore et les résultats ne sont pas définis.
Les références const de courte durée (variables de fonction locales et arguments de fonction) peuvent être liées à des temporaires. Si c'est le cas, le temporaire est garanti de ne pas être détruit tant que la référence n'est pas hors de portée.
Code de démonstration:
#include <iostream>
class Big {
public:
Big() : living_(true), i_(5) { // This initialization of i is strictly legal but
void *me = this; // the result is undefined.
::std::cerr << "Big constructor called for " << me << "\n";
}
~Big() {
void *me = this;
living_ = false;
::std::cerr << "Big destructor called for " << me << "\n";
}
bool isLiving() const { return living_; }
const int &getIref() const;
const int *getIptr() const;
private:
::std::string s_;
bool living_;
const int &i_;
char stuff[50];
};
const int &Big::getIref() const
{
return i_;
}
const int *Big::getIptr() const
{
return &i_;
}
inline ::std::ostream &operator <<(::std::ostream &os, const Big &b)
{
const void *thisb = &b;
return os << "A " << (b.isLiving() ? "living" : "dead (you're lucky this didn't segfault or worse)")
<< " Big at " << thisb
<< " && b.getIref() == " << b.getIref()
<< " && *b.getIptr() == " << *b.getIptr();
}
class A {
public:
A() : big_(Big()) {}
const Big &getBig() const { return big_; }
private:
const Big &big_;
};
int main(int argc, char *argv[])
{
A a;
const Big &b = Big();
const int &i = 0;
::std::cerr << "a.getBig() == " << a.getBig() << "\n";
::std::cerr << "b == " << b << "\n";
::std::cerr << "i == " << i << "\n";
return 0;
}
Et la sortie:
Big constructor called for 0x7fffebaae420
Big destructor called for 0x7fffebaae420
Big constructor called for 0x7fffebaae4a0
a.getBig() == A living Big at 0x7fffebaae420 && b.getIref() == -341121936 && *b.getIptr() == -341121936
b == A living Big at 0x7fffebaae4a0 && b.getIref() == 0 && *b.getIptr() == 0
i == 0
Big destructor called for 0x7fffebaae4a0
L'exemple spécifique dans son constructeur échouera encore lamentablement s'il déclare la variable membre 'const'. – Omnifarious
@Omnifarious: Comment ça? – GManNickG
Que se passe-t-il lorsque le 0 temporaire est détruit? Que diriez-vous si son adresse est prise et que déréférencé? – Omnifarious