Jika saya mendeklarasikan kelas dasar (atau kelas antarmuka) dan menentukan nilai default untuk satu atau lebih parameternya, apakah kelas turunan harus menentukan default yang sama dan jika tidak, default mana yang akan terwujud dalam kelas turunan?
Tambahan: Saya juga tertarik dengan bagaimana hal ini dapat ditangani di berbagai kompiler dan masukan apa pun tentang praktik "disarankan" dalam skenario ini.
Jawaban:
Virtual mungkin memiliki default. Default di kelas dasar tidak diwarisi oleh kelas turunan.
Default mana yang digunakan - yaitu, kelas dasar 'atau kelas turunan' - ditentukan oleh tipe statis yang digunakan untuk membuat panggilan ke fungsi. Jika Anda memanggil objek kelas dasar, penunjuk atau referensi, standar yang ditunjukkan dalam kelas dasar digunakan. Sebaliknya, jika Anda memanggil objek kelas turunan, penunjuk atau referensi standar yang ditunjukkan dalam kelas turunan digunakan. Ada contoh di bawah kutipan Standar yang menunjukkan ini.
Beberapa kompiler mungkin melakukan sesuatu yang berbeda, tetapi inilah yang dikatakan oleh Standar C ++ 03 dan C ++ 11:
Berikut adalah contoh program untuk menunjukkan default apa yang diambil. Saya menggunakan
struct
s di sini daripadaclass
es hanya untuk singkatnya -class
danstruct
persis sama di hampir setiap cara kecuali visibilitas standar.Output dari program ini (pada MSVC10 dan GCC 4.4) adalah:
sumber
Ini adalah topik dari salah satu posting Guru of the Week awal Herb Sutter .
Hal pertama yang dia katakan tentang masalah ini adalah JANGAN MELAKUKANNYA.
Secara lebih rinci, ya, Anda dapat menentukan parameter default yang berbeda. Mereka tidak akan bekerja dengan cara yang sama seperti fungsi virtual. Fungsi virtual disebut pada tipe dinamis objek, sedangkan nilai parameter default didasarkan pada tipe statis.
Diberikan
Anda harus mendapatkan A :: foo1 B :: foo2 B :: foo1
sumber
Ini adalah ide yang buruk, karena argumen default yang Anda peroleh akan tergantung pada tipe statis objek, sedangkan
virtual
fungsi yang dikirim akan tergantung pada tipe dinamis .Dengan kata lain, ketika Anda memanggil suatu fungsi dengan argumen default, argumen default diganti pada waktu kompilasi, terlepas dari apakah fungsi tersebut
virtual
atau tidak.@cppcoder ditawarkan contoh berikut dalam bukunya [ditutup] pertanyaan :
Yang menghasilkan output berikut:
Dengan bantuan penjelasan di atas, mudah diketahui alasannya. Pada waktu kompilasi, kompiler menggantikan argumen default dari fungsi anggota dari tipe statis dari pointer, membuat
main
fungsi setara dengan yang berikut:sumber
Seperti yang dapat Anda lihat dari jawaban lain, ini adalah topik yang rumit. Alih-alih mencoba melakukan ini atau memahami apa yang dilakukannya (jika Anda harus bertanya sekarang, pengelola harus meminta atau mencarinya setahun dari sekarang).
Sebagai gantinya, buat fungsi publik non-virtual di kelas dasar dengan parameter default. Kemudian ia memanggil fungsi virtual pribadi atau yang dilindungi yang tidak memiliki parameter default dan ditimpa dalam kelas anak sesuai kebutuhan. Maka Anda tidak perlu khawatir tentang rinciannya dan kodenya sangat jelas.
sumber
Ini adalah salah satu yang Anda mungkin dapat mencari tahu dengan cukup baik dengan pengujian (yaitu, itu adalah bagian yang cukup utama dari bahasa yang sebagian besar kompiler hampir pasti melakukannya dengan benar dan kecuali jika Anda melihat perbedaan antara kompiler, output mereka dapat dianggap cukup otoritatif).
sumber
Sebagai jawaban lain telah merinci, itu ide buruk. Namun karena tidak ada yang menyebutkan solusi sederhana dan efektif, ini dia: Konversikan parameter Anda menjadi struct dan kemudian Anda dapat memiliki nilai default menjadi anggota struct!
Jadi alih-alih,
melakukan hal ini,
sumber