Harap pertimbangkan kode ini. Saya telah melihat kode jenis ini beberapa kali. words
adalah vektor lokal. Bagaimana mungkin mengembalikannya dari suatu fungsi?
Bisakah kita jamin dia tidak akan mati?
std::vector<std::string> read_file(const std::string& path)
{
std::ifstream file("E:\\names.txt");
if (!file.is_open())
{
std::cerr << "Unable to open file" << "\n";
std::exit(-1);
}
std::vector<string> words;//this vector will be returned
std::string token;
while (std::getline(file, token, ','))
{
words.push_back(token);
}
return words;
}
std::vector<std::string>&
Jawaban:
Selama tidak ada referensi yang dikembalikan, tidak masalah untuk melakukannya.
words
akan dipindahkan ke variabel yang menerima hasilnya.Variabel lokal akan keluar dari ruang lingkup. setelah dipindahkan (atau disalin).
sumber
Sebelum C ++ 11:
Fungsi ini tidak akan mengembalikan variabel lokal, melainkan salinannya. Namun kompilator Anda mungkin melakukan pengoptimalan di mana tidak ada tindakan penyalinan yang sebenarnya dilakukan.
Lihat pertanyaan & jawaban ini untuk lebih jelasnya.
C ++ 11:
Fungsi tersebut akan memindahkan nilai. Lihat jawaban ini untuk lebih jelasnya.
sumber
Saya pikir Anda mengacu pada masalah di C (dan C ++) yang mengembalikan array dari fungsi tidak diizinkan (atau setidaknya tidak akan berfungsi seperti yang diharapkan) - ini karena pengembalian array akan (jika Anda menuliskannya di bentuk sederhana) mengembalikan pointer ke array aktual di stack, yang kemudian segera dihapus saat fungsi kembali.
Tapi dalam kasus ini, itu berfungsi, karena
std::vector
adalah kelas, dan kelas, seperti struct, dapat (dan akan) disalin ke konteks pemanggil. [Sebenarnya, sebagian besar kompiler akan mengoptimalkan jenis salinan khusus ini menggunakan sesuatu yang disebut "Pengoptimalan Nilai Kembali", yang secara khusus diperkenalkan untuk menghindari penyalinan objek besar saat dikembalikan dari suatu fungsi, tetapi itu adalah pengoptimalan, dan dari perspektif pemrogram, itu akan berperilaku seolah-olah konstruktor tugas dipanggil untuk objek]Selama Anda tidak mengembalikan pointer atau referensi ke sesuatu yang ada di dalam fungsi yang dikembalikan, Anda baik-baik saja.
sumber
Untuk memahami perilakunya dengan baik, Anda dapat menjalankan kode ini:
Outputnya adalah sebagai berikut:
Perhatikan bahwa contoh ini disediakan dalam konteks C ++ 03, dapat ditingkatkan untuk C ++> = 11
sumber
Saya tidak setuju dan tidak merekomendasikan untuk mengembalikan
vector
:Ini jauh lebih cepat:
Saya menguji pada Visual Studio 2017 dengan hasil berikut dalam mode rilis:
8,01 MOP dengan referensi
vektor pengembalian 5,09 MOP
Dalam mode debug, segalanya menjadi lebih buruk:
0,053 MOPS dengan referensi
0,034 MOPs dengan vektor kembali
sumber
Ini sebenarnya adalah kegagalan desain. Anda tidak boleh menggunakan nilai pengembalian untuk apa pun yang bukan primitif untuk apa pun yang relatif tidak sepele.
Solusi ideal harus diimplementasikan melalui parameter return dengan keputusan referensi / pointer dan penggunaan yang tepat dari "const \ 'y \' ness" sebagai deskriptor.
Di atas ini, Anda harus menyadari bahwa label pada larik di C dan C ++ secara efektif adalah penunjuk dan langganannya secara efektif merupakan simbol offset atau penambahan.
Jadi label atau ptr array_ptr === label array sehingga mengembalikan foo [offset] benar-benar mengatakan elemen kembalian di lokasi penunjuk memori foo + offset tipe kembalian.
sumber