Yanıtlar:
Güvenli. Const ref geçici ömrünü uzatır. Kapsam const ref kapsamı olacaktır.
Süresi geçici nesnenin (11 C ++ çünkü) const lvalue referansına veya rvalue referans bağlanma uzatılabilir, bakınız , referans başlatma bilgi için bkz.
Bir referans bir geçici veya onun bir alt nesnesine bağlı olduğunda, geçici durumun ömrü, aşağıdaki istisnalar dışında referansın ömrüne uyacak şekilde uzatılır :
- return ifadesindeki bir işlevin dönüş değerine geçici bir bağ genişletilmez: dönüş ifadesinin sonunda hemen yok edilir. Bu işlev her zaman sarkan bir referans döndürür.
- bir yapıcı başlatıcısı listesinde bir referans üyeye geçici bir bağ, nesne var olduğu sürece değil, yalnızca kurucu çıkana kadar devam eder. (not: bu başlatma, DR 1696'dan itibaren kötü biçimlendirilmiştir).
- bir işlev çağrısındaki başvuru parametresine geçici bir bağ, o işlev çağrısını içeren tam ifadenin sonuna kadar var olur: işlev tam ifadeden daha büyük bir referans döndürürse, sarkan bir başvuru haline gelir.
- yeni ifadede kullanılan başlatıcıdaki bir referansa geçici bir bağ, başlatılmış nesne kadar değil, bu yeni ifadeyi içeren tam ifadenin sonuna kadar vardır. Başlatılan nesne tam ifadeyi aşarsa, başvuru üyesi sarkan bir başvuru haline gelir.
- liste başlatma sözdiziminin (parantezler) aksine doğrudan başlatma sözdizimi (parantez) kullanılarak başlatılan bir topluluğun referans öğesindeki bir referansa geçici bir başlangıç, başlatıcıyı içeren tam ifadenin sonuna kadar mevcuttur.
struct A { int&& r; }; A a1{7}; // OK, lifetime is extended A a2(7); // well-formed, but dangling reference
Genel olarak, bir geçidin ömrü "geçirilerek" daha fazla uzatılamaz: geçicinin bağlı olduğu referanstan başlatılan ikinci bir referans, ömrünü etkilemez.
@Konrad Rudolph'un işaret ettiği gibi (ve yukarıdaki son paragrafa bakın):
"
c.GetSomeVariable()
Yerel bir nesneye başvuru veya kendisinin bir nesnenin ömrünü uzattığı bir başvuru döndürürse, yaşam süresi uzantısı devreye girmez"
c.GetSomeVariable()
döner bir referans yerel nesneye veya kendisi bazı nesnenin ömrünü uzatma olduğuna dair bir referans, ömür boyu uzatma yok değil bir tekme.
Ömür boyu uzatma sayesinde burada herhangi bir sorun olmamalıdır . Yeni inşa edilen nesne, referans kapsam dışına çıkana kadar hayatta kalacaktır.
Bu güvenli.
[class.temporary]/5
: Geçicilerin tam ifadenin sonundan farklı bir noktada imha edildiği üç bağlam vardır . [..]
[class.temporary]/6
: Üçüncü bağlam, başvurunun geçici bir nesneye bağlandığı zamandır. Başvurunun bağlı olduğu geçici nesne veya başvurunun bağlı olduğu bir alt nesnenin tam nesnesi olan geçici nesne, başvurunun bağlı olduğu glvalue aşağıdakilerden biri yoluyla elde edildiğinde başvurunun ömrü boyunca devam eder. : [burada bir çok şey]
Bu özel durumda güvenlidir. Bununla birlikte, tüm geçişlerin const referansı ile yakalanmasının güvenli olmadığını unutmayın ... örneğin
#include <stdio.h>
struct Foo {
int member;
Foo() : member(0) {
printf("Constructor\n");
}
~Foo() {
printf("Destructor\n");
}
const Foo& method() const {
return *this;
}
};
int main() {
{
const Foo& x = Foo{}; // safe
printf("here!\n");
}
{
const int& y = Foo{}.member; // safe too (special rule for this)
printf("here (2)!\n");
}
{
const Foo& z = Foo{}.method(); // NOT safe
printf("here (3)!\n");
}
return 0;
}
İçin alınan başvurunun z
kullanımı güvenli DEĞİLDİR çünkü geçici örnek, ifadeye ulaşmadan önce tam ifadenin sonunda yok edilir printf
. Çıktı:
Constructor
here!
Destructor
Constructor
here (2)!
Destructor
Constructor
Destructor
here (3)!