Fungsi menimpa dan kelebihan beban dalam C ++ dan Delphi
Spacesoft 【pasir malam gelap】
Dalam pemrograman yang berorientasi objek, ketika subclass melanjutkan fungsi dari kelas dasar, subclass mungkin perlu berurusan dengan beberapa fungsi secara berbeda dari kelas dasar, seperti:
Kelas Chuman
{
publik:
void saymyname () // cetak nama objek
{
cout << Hai, saya manusia << endl;
}
};
Maka jelas, jika subkelasnya memiliki fungsi SayMyname dengan nama yang sama, parameter yang sama dan nilai pengembalian (satu kalimat, fungsi yang sama), fungsi mana yang akan disebut? Misalnya, ada kelas CMark sekarang
Kelas Cmark: Chuman Publik
{
publik:
batal saymyname ()
{
cout << Hai, saya Mark << endl;
}
};
Kemudian kita harus bertanya, segmen program berikut:
Chuman *ph = cmark baru;
if (ph)
ph-> saymyname ();
kalau tidak
cout << cast error! << endl;
Hapus pH;
pH = null;
Apakah hai, saya tanda kami ingin mencetak?
TIDAK. Itu output hai, saya manusia. Ini mengerikan, dan ketika kita menunjuk seseorang dan memintanya untuk menyebutkan namanya, dia memberi tahu kita bahwa dia adalah "seseorang" daripada menyebutkan namanya. Alasan untuk masalah ini adalah bahwa menunjuk ke kelas yang diturunkan publik dengan penunjuk kelas dasar, Anda dapat mengakses fungsi anggota kelas turunan yang berlanjut dari kelas dasar. Tetapi jika ada fungsi dengan nama yang sama di kelas yang diturunkan, hasilnya masih mengakses fungsi dari nama yang sama dari kelas dasar, daripada fungsi kelas turunan itu sendiri. Faktanya, yang kita inginkan adalah menentukan fungsi mana dari nama yang sama yang harus disebut oleh jenis objek yang sebenarnya, yaitu, resolusi seperti itu dinamis. Atau kita dapat mengatakan bahwa ketika suatu objek adalah subtipe, implementasinya dengan nama yang sama di subkelas mengesampingkan implementasi kelas dasar.
Mari kita mulai dengan penanganan C ++ tentang masalah ini.
Ini adalah contoh khas polimorfisme dalam C ++. Untuk lebih spesifik, itu adalah menggunakan kata -kata kunci virtual untuk menggambarkan fungsi sebagai fungsi virtual.
Kelas Chuman
{
publik:
virtual void saymyname () // cetak nama objek
{
cout << Hai, saya manusia << endl;
}
};
Dengan cara ini, kode lain masih sama, tetapi CMark kami sudah tahu bagaimana mengatakan namanya. Tidak masalah apakah fungsi SayMyname () dari CMark telah menambahkan kata kunci virtual, karena menurut ketentuan sintaks C ++, karena mengesampingkan fungsi chuman dengan nama yang sama, itu menjadi virtual itu sendiri. Adapun mengapa kata kunci virtual memiliki efek magis seperti itu? C ++ FAQ Lite menjelaskan ini sebagai berikut: Dalam C ++, "Fungsi anggota virtual ditentukan secara dinamis (saat runtime). Yaitu, fungsi anggota (saat runtime) dipilih secara dinamis, dan pemilihan didasarkan pada jenis objek., Bukan Jenis pointer/referensi ke objek itu ". Jadi pH kami menemukan bahwa itu benar -benar menunjuk pada objek tipe Cmark, bukan chuman yang dinyatakan oleh tipenya sendiri, sehingga secara cerdik menyebut CMark Saymyname.
Delphi menggunakan kata -kata kunci override untuk menggambarkan override fungsi. Fungsi yang ditimpa harus virtual atau dinamis, yaitu fungsi harus berisi salah satu dari dua indikator ini ketika dinyatakan, seperti:
Draw prosedur;
Ketika Anda perlu mengganti, Anda hanya perlu mengulanginya dengan indikator override di subkelas.
Draw Prosedur;
Secara sintaksis, deklarasi sebagai virtual dan dinamis setara. Perbedaannya adalah bahwa yang pertama mengoptimalkan kecepatan implementasi, sementara yang terakhir mengoptimalkan ukuran kode.
Bagaimana jika kelas dasar dan subkelas berisi nama dan parameter fungsi yang sama, dan indikator override tidak ditambahkan ke subkelas? Ini juga benar secara sintaksis. Ini berarti bahwa implementasi fungsi fungsi subclass menyembunyikan implementasi kelas dasar, meskipun keduanya ada di kelas yang diturunkan. Lalu mari kita kembali ke situasi yang ditunjukkan pada contoh pertama di awal artikel ini: ketika kita menunjuk ke seseorang dan memintanya untuk mengatakan namanya sendiri, dia memberi tahu kita bahwa dia adalah "seseorang", daripada mengatakan miliknya sendiri nama.
Perlu dicatat bahwa tidak seperti fungsi kelebihan muatan dan fungsi berlebih yang sering kita sebut kelebihan beban di C ++, di Delphi, hanya kelebihan beban adalah apa yang biasanya kita sebut kelebihan beban. Tentu saja, ketika fungsi menjatuhkan kelebihan beban sama dengan parameter fungsi kelas dasar, implementasi kelas dasar disembunyikan, seperti yang disebutkan di atas. Override berarti membuat fungsi yang ditimpa tidak terlihat dan memang ditimpa, dan implementasi asli akan hilang. Karena alasan ini, banyak artikel dan bahkan beberapa buku telah secara keliru diterjemahkan mengesampingkan menjadi kelebihan beban, yang menurut saya tidak tepat.