Apa yang akan menjadi praktik yang lebih baik ketika memberikan fungsi variabel asli untuk bekerja dengan:
unsigned long x = 4;
void func1(unsigned long& val) {
val = 5;
}
func1(x);
atau:
void func2(unsigned long* val) {
*val = 5;
}
func2(&x);
TKI: Apakah ada alasan untuk memilih satu dari yang lain?
Jawaban:
Aturan praktis saya adalah:
Gunakan pointer jika Anda ingin melakukan aritmatika pointer dengan mereka (misalnya, menambah alamat pointer untuk melangkah melalui array) atau jika Anda harus melewati pointer NULL.
Gunakan referensi sebaliknya.
sumber
Base* b = new Derived()
)? Ini seperti kasus yang tidak bisa ditangani tanpa petunjuk.Saya benar-benar berpikir Anda akan mendapat manfaat dari membangun pedoman pemanggilan fungsi panggilan berikut:
Seperti di semua tempat lain, selalu benar-
const
benar.const
specifier.Hanya berikan nilai dengan pointer jika nilai 0 / NULL adalah input yang valid dalam konteks saat ini.
Dasar Pemikiran 1: Sebagai penelepon , Anda melihat bahwa apa pun yang Anda lewati harus dalam kondisi yang dapat digunakan.
Dasar Pemikiran 2: Seperti yang disebut , Anda tahu bahwa apa pun yang masuk adalah dalam kondisi yang dapat digunakan. Oleh karena itu, tidak ada pemeriksaan NULL atau penanganan kesalahan yang perlu dilakukan untuk nilai tersebut.
Dasar Pemikiran 3: Dasar pemikiran 1 dan 2 akan diberlakukan kompiler . Selalu tangkap kesalahan pada waktu kompilasi jika Anda bisa.
Jika argumen fungsi adalah nilai keluar, maka sampaikan dengan referensi.
Pilih "pass by value" over "pass by const reference" hanya jika nilainya adalah POD ( Plain old Datastructure ) atau cukup kecil (berdasarkan memori) atau dengan cara lain cukup murah (berdasarkan waktu) untuk disalin.
sumber
std::vector<>
.Ini akhirnya menjadi subyektif. Diskusi sejauh ini bermanfaat, tetapi saya tidak berpikir ada jawaban yang benar atau menentukan untuk ini. Banyak yang akan tergantung pada pedoman gaya dan kebutuhan Anda saat itu.
Meskipun ada beberapa kemampuan yang berbeda (apakah sesuatu bisa NULL atau tidak) dengan sebuah pointer, perbedaan praktis terbesar untuk parameter output adalah murni sintaksis. Panduan Gaya C ++ Google ( https://google.github.io/styleguide/cppguide.html#Reference_Arguments ), misalnya, mandat hanya pointer untuk parameter output, dan hanya memperbolehkan referensi yang konst. Alasannya adalah salah satu keterbacaan: sesuatu dengan sintaks nilai seharusnya tidak memiliki makna semantik pointer. Saya tidak menyarankan bahwa ini benar atau salah, tetapi saya pikir intinya di sini adalah masalah gaya, bukan kebenaran.
sumber
Anda harus melewati pointer jika Anda akan mengubah nilai variabel. Meskipun secara teknis melewati referensi atau pointer adalah sama, melewati pointer dalam use case Anda lebih mudah dibaca karena "mengiklankan" fakta bahwa nilainya akan diubah oleh fungsi.
sumber
const
atau bukanconst
referensi, tetapi Anda dapat melihat apakah parameternya dilewatkan secara default&x
vsx
, dan gunakan konvensi itu untuk menyandikan apakah parameter tersebut dapat dimodifikasi. (Yang mengatakan, ada saat-saat ketika Anda ingin melewati sebuahconst
pointer, jadi konvensioni hanyalah sebuah petunjuk. Diduga mencurigai sesuatu mungkin dimodifikasi ketika itu tidak akan kurang berbahaya daripada berpikir itu tidak akan menjadi ketika itu akan menjadi ....)Jika Anda memiliki parameter di mana Anda mungkin perlu menunjukkan tidak adanya nilai, itu praktik umum untuk membuat parameter nilai penunjuk dan meneruskan NULL.
Solusi yang lebih baik dalam banyak kasus (dari perspektif keamanan) adalah dengan menggunakan boost :: opsional . Ini memungkinkan Anda untuk memberikan nilai opsional dengan referensi dan juga sebagai nilai balik.
sumber
Gunakan referensi ketika Anda bisa, gunakan pointer ketika Anda harus. Dari C ++ FAQ: "Kapan saya harus menggunakan referensi, dan kapan saya harus menggunakan pointer?"
sumber
Pointer
Pointer yang saat ini tidak menunjuk ke lokasi memori yang valid diberi nilai nol (Yang nol)
& Adalah operator unary yang mengembalikan alamat memori operannya.
Operator referensi (*) digunakan untuk mengakses nilai yang disimpan dalam variabel yang ditunjuk oleh pointer.
Referensi
Referensi (&) seperti alias ke variabel yang ada.
Referensi (&) seperti pointer konstan yang secara otomatis direferensikan.
Biasanya digunakan untuk daftar argumen fungsi dan nilai pengembalian fungsi.
Referensi harus diinisialisasi ketika dibuat.
Setelah referensi diinisialisasi ke suatu objek, itu tidak dapat diubah untuk merujuk ke objek lain.
Anda tidak dapat memiliki referensi NULL.
Referensi const dapat merujuk ke const int. Ini dilakukan dengan variabel sementara dengan nilai const
sumber
Referensi adalah pointer implisit. Pada dasarnya Anda dapat mengubah nilai referensi ke titik tetapi Anda tidak dapat mengubah referensi untuk menunjuk ke sesuatu yang lain. Jadi 2 sen saya adalah bahwa jika Anda hanya ingin mengubah nilai suatu parameter, letakkan sebagai referensi tetapi jika Anda perlu mengubah parameter untuk menunjuk ke objek yang berbeda, lewati dengan menggunakan pointer.
sumber
Pertimbangkan kata kunci C # yang keluar. Kompiler memerlukan penelepon metode untuk menerapkan kata kunci keluar untuk argumen apa pun, meskipun ia sudah tahu jika mereka. Ini dimaksudkan untuk meningkatkan keterbacaan. Meskipun dengan IDE modern saya cenderung berpikir bahwa ini adalah pekerjaan untuk menyoroti sintaks (atau semantik).
sumber
Lewati referensi const kecuali ada alasan Anda ingin mengubah / menyimpan konten yang Anda lewati.
Ini akan menjadi metode yang paling efisien dalam banyak kasus.
Pastikan Anda menggunakan const pada setiap parameter yang tidak ingin Anda ubah, karena ini tidak hanya melindungi Anda dari melakukan sesuatu yang bodoh dalam fungsi, itu memberikan indikasi yang baik kepada pengguna lain apa fungsi yang dilakukannya terhadap nilai yang diteruskan. Ini termasuk membuat pointer pointer ketika Anda hanya ingin mengubah ...
sumber
Pointer:
nullptr
(atauNULL
).&
jika tipe Anda bukan pointer itu sendiri, membuat Anda secara eksplisit memodifikasi objek Anda.Referensi:
&
. Ini kadang-kadang dianggap buruk karena Anda harus pergi ke implementasi fungsi untuk melihat apakah parameter Anda diubah.sumber
Referensi mirip dengan pointer, kecuali bahwa Anda tidak perlu menggunakan awalan ∗ untuk mengakses nilai yang dirujuk oleh referensi. Juga, referensi tidak dapat dibuat untuk merujuk ke objek yang berbeda setelah inisialisasi.
Referensi sangat berguna untuk menentukan argumen fungsi.
untuk informasi lebih lanjut lihat "Tur C ++" oleh "Bjarne Stroustrup" (2014) Halaman 11-12
sumber