Apa ide umum delegasi di C ++? Untuk apa mereka, bagaimana mereka digunakan dan untuk apa mereka digunakan?
Pertama-tama saya ingin mempelajarinya dengan cara 'kotak hitam', tetapi sedikit informasi tentang nyali hal-hal ini juga bagus.
Ini bukan C ++ paling murni atau terbersih, tapi saya perhatikan bahwa basis kode tempat saya bekerja memiliki mereka dalam kelimpahan. Saya berharap untuk cukup memahami mereka, jadi saya hanya bisa menggunakannya dan tidak harus menyelidiki keasyikan templat bersarang yang mengerikan.
Dua artikel The Code Project ini menjelaskan apa yang saya maksud tetapi tidak terlalu ringkas:
c++
delegates
delegation
SirYakalot
sumber
sumber
delegate
bukan nama umum dalam bahasa c ++. Anda harus menambahkan beberapa informasi ke pertanyaan untuk memasukkan konteks di mana Anda telah membacanya. Perhatikan bahwa meskipun polanya mungkin umum, jawabannya mungkin berbeda jika Anda berbicara tentang delegasi secara umum, atau dalam konteks C ++ CLI atau perpustakaan lain yang memiliki implementasi delegasi tertentu .Jawaban:
Anda memiliki banyak pilihan untuk mencapai delegasi di C ++. Inilah beberapa yang muncul di pikiran saya.
Opsi 1: functors:
Objek fungsi dapat dibuat dengan mengimplementasikan
operator()
Opsi 2: ekspresi lambda (khusus C ++ 11 )
Opsi 3: pointer fungsi
Opsi 4: penunjuk ke fungsi anggota (solusi tercepat)
Lihat Fast C ++ Delegate (pada Proyek Kode ).
Opsi 5: std :: function
(atau
boost::function
jika perpustakaan standar Anda tidak mendukungnya). Ini lebih lambat, tetapi yang paling fleksibel.Opsi 6: mengikat (menggunakan std :: bind )
Memungkinkan pengaturan beberapa parameter terlebih dahulu, mudah untuk memanggil fungsi anggota misalnya.
Opsi 7: template
Terima apa saja asalkan cocok dengan daftar argumen.
sumber
std::bind
, dan keduanya benar-benar melakukan hal yang sama, kecuali lambda bukan polimorfik dalam arti bahwa mereka dapat menerima jenis argumen yang berbeda.binding
dalam daftar saya). Anda tidak dapat mencapai ini dengan pointer fungsi.Delegasi adalah kelas yang membungkus pointer atau referensi ke instance objek, metode anggota kelas objek yang akan dipanggil pada instance objek itu, dan menyediakan metode untuk memicu panggilan itu.
Ini sebuah contoh:
sumber
Execute()
yang memicu pemanggilan fungsi pada objek yang dibungkus oleh delegasi.Kebutuhan akan implementasi delegasi C ++ adalah penghinaan jangka panjang bagi komunitas C ++. Setiap programmer C ++ akan senang memilikinya, jadi mereka akhirnya menggunakannya terlepas dari fakta bahwa:
std::function()
menggunakan operasi tumpukan (dan berada di luar jangkauan untuk pemrograman tertanam yang serius).Semua implementasi lain membuat konsesi terhadap portabilitas atau kesesuaian standar ke tingkat yang lebih besar atau lebih kecil (harap verifikasi dengan memeriksa berbagai implementasi delegasi di sini dan pada proyek codep). Saya belum melihat implementasi yang tidak menggunakan reinterpret_casts liar, kelas bertingkat "prototipe" yang mudah-mudahan menghasilkan pointer fungsi dengan ukuran yang sama seperti yang dilewati oleh pengguna, trik kompiler seperti pertama maju menyatakan, kemudian ketik kemudian mendeklarasikan lagi, kali ini mewarisi dari kelas lain atau teknik teduh serupa. Meskipun ini adalah pencapaian besar bagi para pelaksana yang membangunnya, itu masih merupakan kesaksian yang menyedihkan tentang bagaimana C ++ berkembang.
Jarang sekali ditunjukkan, bahwa sekarang lebih dari 3 revisi standar C ++, delegasi tidak ditangani dengan baik. (Atau kurangnya fitur bahasa yang memungkinkan implementasi delegasi langsung.)
Dengan cara fungsi C ++ 11 lambda didefinisikan oleh standar (setiap lambda memiliki jenis anonim, berbeda), situasinya hanya membaik dalam beberapa kasus penggunaan. Tetapi untuk kasus penggunaan menggunakan delegasi di (DLL) perpustakaan API, lambdas sendiri masih tidak dapat digunakan. Teknik umum di sini, adalah untuk pertama-tama mengemas lambda menjadi fungsi std :: dan kemudian menyebarkannya ke seluruh API.
sumber
std::function
tidak selalu mengalokasikan secara dinamisSederhananya, delegasi menyediakan fungsionalitas untuk bagaimana fungsi pointer HARUS bekerja. Ada banyak batasan fungsi pointer di C ++. Seorang delegasi menggunakan beberapa kejelekan templat di belakang layar untuk membuat kelas-jenis-fungsi-pointer-templat yang berfungsi sesuai keinginan Anda.
yaitu - Anda dapat mengatur mereka untuk menunjuk pada fungsi yang diberikan dan Anda dapat menyebarkannya dan memanggil mereka kapanpun dan dimanapun Anda suka.
Ada beberapa contoh yang sangat bagus di sini:
sumber
Opsi untuk delegasi dalam C ++ yang tidak disebutkan di sini adalah melakukannya dengan gaya C menggunakan ptr fungsi dan argumen konteks. Ini mungkin merupakan pola yang sama yang banyak orang menanyakan pertanyaan ini coba hindari. Namun, polanya portabel, efisien, dan dapat digunakan dalam kode tertanam dan kernel.
sumber
Windows Runtime setara dengan objek fungsi dalam standar C ++. Satu dapat menggunakan seluruh fungsi sebagai parameter (sebenarnya itu adalah pointer fungsi). Itu sebagian besar digunakan bersama dengan acara. Delegasi tersebut mewakili kontrak yang dipenuhi oleh para penangan acara. Ini memfasilitasi bagaimana fungsi pointer dapat bekerja.
sumber