Apakah yang berikut (contoh yang dibuat-buat) baik-baik saja atau apakah itu perilaku tidak terdefinisi:
// undefined behavior?
const auto& c = SomeClass{};
// use c in code later
const auto& v = c.GetSomeVariable();
sumber
Apakah yang berikut (contoh yang dibuat-buat) baik-baik saja atau apakah itu perilaku tidak terdefinisi:
// undefined behavior?
const auto& c = SomeClass{};
// use c in code later
const auto& v = c.GetSomeVariable();
Itu aman. Konstitusi memperpanjang umur sementara. Ruang lingkup akan menjadi ruang lingkup const ref.
Masa pakai objek sementara dapat diperpanjang dengan mengikat ke referensi nilai konstan atau ke nilai referensi (karena C ++ 11), lihat inisialisasi referensi untuk detail.
Setiap kali referensi terikat untuk sementara atau ke sub-proyeknya, masa pakai sementara diperpanjang untuk mencocokkan masa pakai referensi, dengan pengecualian berikut :
- terikat sementara untuk nilai kembali suatu fungsi dalam pernyataan kembali tidak diperpanjang: itu dihancurkan segera di akhir ekspresi kembali. Fungsi seperti itu selalu mengembalikan referensi yang menggantung.
- terikat sementara untuk anggota referensi dalam daftar penginisialisasi konstruktor hanya bertahan sampai konstruktor keluar, tidak selama objek ada. (catatan: inisialisasi seperti itu terbentuk dengan buruk pada DR 1696).
- sementara terikat ke parameter referensi dalam panggilan fungsi ada sampai akhir ekspresi penuh berisi panggilan fungsi: jika fungsi mengembalikan referensi, yang hidup lebih lama dari ekspresi penuh, itu menjadi referensi menggantung.
- terikat sementara pada referensi di penginisialisasi yang digunakan dalam ekspresi-baru ada sampai akhir ekspresi penuh yang mengandung ekspresi-baru, tidak selama objek diinisialisasi. Jika objek yang diinisialisasi bertahan lebih lama dari ekspresi penuh, anggota rujukannya menjadi referensi yang menggantung.
- sementara terikat pada referensi dalam elemen referensi agregat diinisialisasi menggunakan sintaks inisialisasi langsung (tanda kurung) yang bertentangan dengan sintaksis inisialisasi daftar (kurung) ada sampai akhir ekspresi penuh berisi inisialisasi.
struct A { int&& r; }; A a1{7}; // OK, lifetime is extended A a2(7); // well-formed, but dangling reference
Secara umum, masa temporer tidak dapat diperpanjang dengan "meneruskannya": referensi kedua, yang diinisialisasi dari referensi dimana temporer terikat, tidak mempengaruhi masa pakainya.
seperti yang ditunjukkan @Konrad Rudolph (dan lihat paragraf terakhir di atas):
"Jika
c.GetSomeVariable()
mengembalikan referensi ke objek lokal atau referensi yang itu sendiri memperpanjang masa hidup beberapa objek, ekstensi seumur hidup tidak masuk"
c.GetSomeVariable()
mengembalikan referensi ke objek lokal atau referensi yang itu sendiri memperpanjang masa hidup beberapa objek, ekstensi seumur hidup tidak masuk.Seharusnya tidak ada masalah di sini, berkat perpanjangan seumur hidup . Objek yang baru dibangun akan bertahan sampai referensi keluar dari ruang lingkup.
sumber
Ya ini benar-benar aman: pengikatan
const
referensi memperpanjang umur sementara ke lingkup referensi itu.Perhatikan bahwa perilaku tersebut tidak transitif . Misalnya dengan
cc
menggantung.sumber
Ini aman.
sumber
Aman dalam kasus khusus ini. Namun perhatikan bahwa tidak semua temporer aman untuk ditangkap dengan referensi const ... misalnya
Referensi yang diperoleh
z
BUKAN aman untuk digunakan karena instance sementara akan dihancurkan pada akhir ekspresi penuh, sebelum mencapaiprintf
pernyataan. Output adalah:sumber