Apakah mungkin untuk memberikan nilai default ke parameter suatu fungsi saat kita meneruskan parameter dengan referensi. di C ++
Misalnya, ketika saya mencoba mendeklarasikan fungsi seperti:
virtual const ULONG Write(ULONG &State = 0, bool sequence = true);
Ketika saya melakukan ini, itu memberikan kesalahan:
kesalahan C2440: 'argumen default': tidak dapat mengonversi dari 'const int' menjadi 'unsigned long &' Referensi yang bukan untuk 'const' tidak dapat terikat ke nilai non-l
c++
pass-by-reference
default-value
Drew Noakes
sumber
sumber
WxWidgets style guide says "don't use templates" and they have good reasons
<- screw std :: vector, saya katakanJawaban:
Anda bisa melakukannya untuk referensi const, tetapi tidak untuk non-const. Ini karena C ++ tidak mengizinkan sementara (nilai default dalam kasus ini) untuk terikat ke referensi non-const.
Salah satu cara untuk melakukannya adalah dengan menggunakan instance aktual sebagai default:
tetapi penggunaan praktis ini sangat terbatas.
sumber
Itu telah dikatakan di salah satu komentar langsung ke jawaban Anda, tetapi hanya untuk menyatakannya secara resmi. Yang ingin Anda gunakan adalah kelebihan beban:
Menggunakan kelebihan fungsi juga memiliki manfaat tambahan. Pertama, Anda dapat menetapkan default argumen apa pun yang Anda inginkan:
Juga dimungkinkan untuk mendefinisikan ulang argumen default ke fungsi virtual di kelas turunan, yang menghindari overloading:
Hanya ada satu situasi di mana default benar-benar perlu digunakan, dan itu ada di konstruktor. Tidak mungkin memanggil satu konstruktor dari yang lain, sehingga teknik ini tidak berfungsi dalam kasus itu.
sumber
d.f2(); // f2(int) called with '0' b.f2(); // f2(int) called with '0'
Masih ada cara C lama untuk menyediakan argumen opsional: pointer yang bisa berupa NULL jika tidak ada:
sumber
Template kecil ini akan membantu Anda:
Kemudian Anda akan dapat:
sumber
ByRef
live, berdasarkan ingatan? Bukankah itu objek sementara yang akan hancur setelah meninggalkan beberapa ruang lingkup (seperti konstruktor)?Tidak, itu tidak mungkin.
Melewati referensi menyiratkan bahwa fungsi tersebut mungkin mengubah nilai parameter. Jika parameter tidak disediakan oleh pemanggil dan berasal dari konstanta default, fungsi apa yang harus diubah?
sumber
Ada dua alasan untuk meneruskan argumen dengan referensi: (1) untuk performa (dalam hal ini Anda ingin meneruskan referensi const) dan (2) karena Anda memerlukan kemampuan untuk mengubah nilai argumen di dalam fungsi.
Saya sangat meragukan bahwa melewatkan waktu yang lama pada arsitektur modern terlalu memperlambat Anda. Jadi saya berasumsi bahwa Anda bermaksud mengubah nilai
State
di dalam metode. Kompilator mengeluh karena konstanta0
tidak dapat diubah, karena ini adalah nilai r ("non-lvalue" dalam pesan kesalahan) dan tidak dapat diubah (const
dalam pesan kesalahan).Sederhananya, Anda menginginkan metode yang dapat mengubah argumen yang diteruskan, tetapi secara default Anda ingin meneruskan argumen yang tidak dapat diubah.
Dengan kata lain, non-
const
referensi harus mengacu pada variabel aktual. Nilai default di function signature (0
) bukanlah variabel nyata. Anda mengalami masalah yang sama seperti:Jika Anda tidak benar-benar berniat untuk mengubah
State
di dalam metode ini, Anda dapat mengubahnya menjadiconst ULONG&
. Tetapi Anda tidak akan mendapatkan keuntungan kinerja yang besar dari itu, jadi saya akan merekomendasikan untuk mengubahnya menjadi non-referensiULONG
. Saya perhatikan bahwa Anda telah mengembalikan aULONG
, dan saya curiga bahwa nilainya adalah nilaiState
setelah modifikasi yang diperlukan. Dalam hal ini saya hanya akan mendeklarasikan metode sebagai berikut:Tentu saja, saya tidak yakin apa yang Anda tulis atau ke mana. Tapi itu pertanyaan lain untuk lain waktu.
sumber
Anda tidak dapat menggunakan literal konstan untuk parameter default karena alasan yang sama Anda tidak dapat menggunakan satu sebagai parameter untuk pemanggilan fungsi. Nilai referensi harus memiliki alamat, nilai referensi konstan tidak perlu (yaitu dapat berupa nilai r atau literal konstan).
Pastikan nilai default Anda memiliki alamat dan Anda baik-baik saja.
Saya telah menggunakan pola ini beberapa kali di mana saya memiliki parameter yang bisa berupa variabel atau nol. Pendekatan biasa adalah meminta pengguna untuk memasukkan pointer ke kasus ini. Mereka mengirimkan pointer NULL jika mereka tidak ingin Anda mengisi nilainya. Saya suka pendekatan objek null. Itu membuat hidup penelepon lebih mudah tanpa memperumit kode panggilan.
sumber
Saya kira tidak, dan alasannya adalah bahwa nilai default dievaluasi menjadi konstanta dan nilai yang diteruskan oleh referensi harus dapat berubah, kecuali jika Anda juga menyatakannya sebagai referensi konstan.
sumber
Cara lain bisa jadi sebagai berikut:
maka panggilan berikut dimungkinkan:
sumber
sumber
Dalam kasus OO ... Untuk mengatakan bahwa Kelas yang Diberikan memiliki dan "Default" berarti Default ini (nilai) harus dideklarasikan secara langsung dan kemudian dapat digunakan sebagai Parameter Default misalnya:
Tentang Metode Anda ...
Solusi ini sangat cocok karena dalam kasus ini, "Penomoran halaman default global" adalah nilai "referensi" tunggal. Anda juga dapat mengubah nilai default pada waktu proses seperti konfigurasi "level-gobal", misalnya: preferensi navigasi penomoran halaman pengguna, dll.
sumber
Itu mungkin dengan kualifikasi const untuk Negara:
sumber
sumber
Ada juga trik kotor untuk ini:
Dalam hal ini Anda harus memanggilnya dengan
std::move
:Ini hanya beberapa solusi lucu, saya sama sekali tidak merekomendasikannya menggunakan kode nyata!
sumber
Saya memiliki solusi untuk ini, lihat contoh berikut tentang nilai default untuk
int&
:Anda dapat melakukannya untuk tipe data sepele apa pun yang Anda inginkan, seperti
bool
,double
...sumber
Tentukan 2 fungsi kelebihan beban.
sumber
Jawabannya cukup sederhana dan saya tidak begitu pandai menjelaskan tetapi jika Anda ingin meneruskan nilai default ke parameter non-const yang mungkin akan dimodifikasi dalam fungsi ini adalah menggunakannya seperti ini:
sumber