2010-02-23 20 views
9

Czy ktoś może mi wyjaśnić, dlaczego między tymi dwoma stwierdzeniami istnieje różnica?Inicjowanie odwołań w C++

class A{}; 

const A& a = A();   // correct 

A& b = A();    // wrong 

Mówi nieważny inicjalizacji const odniesienia typu A& z czasowego typu A

Dlaczego const sprawa tutaj?

Odpowiedz

14

Niezawarte referencje muszą być inicjowane za pomocą wartości-l. Jeśli mógłbyś zainicjować je za pomocą tymczasowych, to co by zrobiły poniższe?

int& foo = 5; 
foo = 6; // ?! 

const referencje mają szczególną właściwość, że przedłużenie ich żywotności sędziego, a ponieważ są one const, nie ma możliwości, że będziesz próbować zmieniać coś, co nie siedzieć w pamięci. Na przykład:

const int& foo = 5; 
foo = 6; // not allowed, because foo is const. 

Pamiętaj, że odniesienia w rzeczywistości muszą odnosić się do czegoś, a nie tylko zmiennych tymczasowych. Na przykład:

int foo = 5; 
int& bar = foo; 
bar = 6; 
assert(foo == 6); 
+1

Czekaj, więc czy to oznacza, że ​​mogę użyć 'const classA & ref = ReturnsClassAByValue();'? Myślałem, że tymczasowi umrą na następnej linii. – Lucas

+2

Tak, możesz tego użyć. Tymczasowy będzie trwać tak długo, jak długo będzie istniała zmienna referencyjna: http://herbsutter.spaces.live.com/blog/cns!2D4327CC297151BB !378.entry –

+1

Niesamowite, dzięki. Na SO dowiadujesz się czegoś nowego każdego dnia ... – Lucas

1

Dla tymczasowej/rwartalnej, można mieć tylko odniesienie do stałej.

Możesz mieć niezwiązane odniesienie do nie-tymczasowej/lwartości.

A a; 
A& b = a; 

Wierzę powodem jest wzmocnienie fakt, że RValue jest tymczasowy, jak niewiele jest wartość w jest w stanie modyfikować coś, zniknie na chwilę.

+1

Przyznane; Uważam, że PO szuka przyczyny takiego stanu rzeczy. – fbrereto

1

W języku C++ niedozwolone jest dołączanie niestablinowej referencji do wartości r, natomiast jest całkowicie dopuszczalne dołączanie odniesienia do stałej wartości r. Na przykład, jest to legalne

const int& r = 5; 

natomiast nie jest to

int &r = 5; // ERROR 

tymczasowy obiekt typu A zwróconej przez wyrażenie A() jest rvalue, więc powyższa zasada ma zastosowanie w danym przypadku również.

+0

Wartość r jest nienazwaną wartością tymczasową, podobnie jak wartość zwracana przez funkcję. – thebretness

+0

@bretness: Niekoniecznie. Na przykład stała wyliczeniowa jest wartością r, ale jest * nazwana *. – AnT

3

Terminologia w tym zakresie jest nieco myląca; możesz chcieć trochę ich zbadać. Oto krótka odpowiedź:

Przypisujesz obiekt tymczasowy (wynik wywołania konstruktora klasy) do zmiennej. Obiekt tymczasowy to wartość R. Nie można przypisać wartości R do odniesienia stałego.

Możesz przypisać wartość R do odniesienia const, choć uzasadnienie dla tego jest dość niejasne.

0

Ponieważ standard mówi tak:

§8.5.3.5 ... W przeciwnym razie referencyjna wynosi lwartością odniesienie do nieulotnej typu const ...

Jednakże, jeśli chcesz go bardzo dużo, można je dostać:

#include <iostream> 
int main() 
{ 
    const int & cr=5; 
    int & r=const_cast<int &>(cr); 
    r=6; 
    std::cout<<r; 
} 
// outputs 6 with c++/clang++, Debian 8, amd64 

Ale należy pamiętać, że domniemana stała cr nie jest const więcej, także i ponieść niezdefiniowanej zachowanie. (§1.9 (4))

Jak sugeruje powyższy kod, nie ma żadnych technicznych przyczyn różnicy. Raczej projektanci mieli koszmary o tym, co użytkownicy robią z niestałymi odniesieniami do tymczasowych.