Mengapa demikian:
#include <string>
#include <iostream>
using namespace std;
class Sandbox
{
public:
Sandbox(const string& n) : member(n) {}
const string& member;
};
int main()
{
Sandbox sandbox(string("four"));
cout << "The answer is: " << sandbox.member << endl;
return 0;
}
Berikan hasil:
Jawabannya adalah:
Dari pada:
Jawabannya adalah: empat
cout << "The answer is: " << Sandbox(string("four")).member << endl;
, maka dijamin akan berhasil.SandBox::member
dibaca, string sementara masih hidup .string("four")
dihancurkan pada akhir ekspresi penuh, dan tidak setelahSandbox
konstruktor keluar? Jawaban Potatoswatter mengatakan A sementara terikat pada anggota referensi di ctor-inisialisasi konstruktor (§12.6.2 [class.base.init]) bertahan hingga konstruktor keluar.Jawaban:
Hanya referensi lokal yang
const
memperpanjang umur.Standar tersebut menetapkan perilaku tersebut dalam §8.5.3 / 5, [dcl.init.ref], bagian tentang inisialisasi deklarasi referensi. Referensi dalam contoh Anda terikat dengan argumen konstruktor
n
, dan menjadi tidak valid ketika objekn
terikat keluar dari ruang lingkup.Ekstensi seumur hidup tidak transitif melalui argumen fungsi. §12.2 / 5 [class.t Sementara]:
sumber
member
itu terikat untuk sementara, karena menginisialisasimember
dengann
cara mengikatmember
ke objek yang saman
terikat, dan itu sebenarnya adalah objek sementara dalam kasus ini.const
quaifier.Inilah cara paling sederhana untuk menjelaskan apa yang terjadi:
Di main () Anda membuat string dan meneruskannya ke konstruktor. Contoh string ini hanya ada dalam konstruktor. Di dalam konstruktor, Anda menugaskan anggota untuk menunjuk langsung ke instance ini. Ketika ketika lingkup meninggalkan konstruktor, instance string dihancurkan, dan anggota kemudian menunjuk ke objek string yang tidak ada lagi. Memiliki Sandbox.member menunjuk ke referensi di luar ruang lingkupnya tidak akan menampung instance eksternal dalam ruang lingkup.
Jika Anda ingin memperbaiki program Anda untuk menampilkan perilaku yang Anda inginkan, buat perubahan berikut:
Sekarang temp akan melewati ruang lingkup di ujung main () alih-alih di ujung konstruktor. Namun, ini adalah praktik buruk. Variabel anggota Anda tidak boleh menjadi referensi ke variabel yang ada di luar instance. Dalam praktiknya, Anda tidak pernah tahu kapan variabel itu akan keluar dari ruang lingkup.
Apa yang saya sarankan adalah mendefinisikan Sandbox.member sebagai
const string member;
Ini akan menyalin data parameter sementara ke dalam variabel anggota alih-alih menetapkan variabel anggota sebagai parameter sementara itu sendiri.sumber
const string & temp = string("four"); Sandbox sandbox(temp); cout << sandbox.member << endl;
Apakah masih akan berfungsi?const string &temp = string("four");
memberikan hasil yang sama denganconst string temp("four");
, kecuali jika Anda menggunakandecltype(temp)
secara khususHowever, this is bad practice.
- mengapa Jika temp dan objek yang mengandung menggunakan penyimpanan otomatis dalam cakupan yang sama, bukankah 100% aman? Dan jika Anda tidak melakukan itu, apa yang akan Anda lakukan jika string terlalu besar dan terlalu mahal untuk disalin?Secara teknis, program ini tidak diharuskan untuk benar-benar mengeluarkan apapun ke keluaran standar (yang merupakan aliran buffered untuk memulai).
The
cout << "The answer is: "
bit akan memancarkan"The answer is: "
ke penyangga dari stdout.Kemudian
<< sandbox.member
bit akan memasok referensi yang menggantung ke dalamoperator << (ostream &, const std::string &)
, yang memanggil perilaku tidak terdefinisi .Karena itu, tidak ada yang dijamin terjadi. Program ini mungkin bekerja dengan baik atau macet tanpa harus menyiram stdout - artinya teks "Jawabannya adalah:" tidak akan muncul di layar Anda.
sumber
"The answer is: "
akan ditulis di mana saja.Karena string sementara Anda keluar dari ruang lingkup begitu konstruktor Sandbox kembali, dan tumpukan yang ditempati itu direklamasi untuk beberapa tujuan lain.
Secara umum, Anda tidak boleh menyimpan referensi jangka panjang. Referensi baik untuk argumen atau variabel lokal, tidak pernah anggota kelas.
sumber
Anda mengacu pada sesuatu yang telah lenyap. Berikut ini akan berfungsi
sumber