Saya mencoba memahami teman C ++. Kapan kasus penggunaan yang baik untuk menggunakan teman? Saya kira jika kita ingin membiarkan kelas lain memiliki akses ke atribut kelas lain, mengapa kita tidak menjadikannya sebagai publik atau mewarisi dari kelas itu saja?
Terima kasih untuk bantuannya.
Jawaban:
Membuat anggota kelas
public
berarti memberi semua orang akses ke sana, sehingga melanggar enkapsulasi sepenuhnya.Mewarisi dari sebuah kelas seringkali tidak diinginkan, jika kelas teman tidak dimaksudkan untuk menjadi subclass. Subkelas hanya untuk mendapatkan akses ke internal kelas adalah kesalahan desain yang serius. Dan bahkan subclass tidak dapat melihat anggota pribadi dari kelas dasar.
Penggunaan tipikal
friend
adalah untuk operator yang tidak dapat menjadi anggota, seperti operator aliran,operator+
dll. Dalam kasus ini, kelas aktual yang terkait dengan mereka bukan (selalu) parameter pertama dari fungsi, sehingga fungsi tidak dapat diimplementasikan sebagai metode anggota.Contoh lain adalah menerapkan iterator untuk koleksi. Iterator (dan hanya iterator) perlu melihat bagian dalam koleksi induknya, namun itu bukan subkelas dari koleksi.
sumber
Contoh saya paling sering melihat kelas teman yang digunakan dalam C ++ adalah dalam unit testing. Tes unit biasanya ingin mengetahui semua tentang internal Anda, tetapi bukan bagian dari Anda, dan tidak masuk akal untuk meminta mereka mencoba mewarisi dari Anda.
Jika Anda tidak terbiasa dengan penulisan unit test, saya sarankan Anda segera mulai .
sumber
Pertanyaan ini harus di stackoverflow. Pokoknya Anda menggunakan teman hanya ketika Anda ingin berbagi bagian pribadi dari kelas Anda dengan kelas lain (atau kelas) tetapi tidak dengan orang lain. Jika Anda membuatnya publik semua orang dapat melihat bagian pribadi Anda (pun intended ;-P). Ada dua batasan penting yang menegakkan privasi: 1) Anda harus menentukan siapa teman Anda. Tidak ada orang lain yang bisa menjadi teman. 2) Anda tidak dapat mewarisi perilaku "ramah" di subclass kelas teman
sumber
Penggunaan khas adalah untuk memberikan akses ke fungsi yang membentuk bagian dari antarmuka kelas, tetapi berkat aturan lain tidak dapat benar-benar menjadi bagian dari kelas yang semestinya. Inserters / extractors untuk iostreams adalah contoh klasik:
Menjadikan para operator ini anggota kelas tidak akan bekerja. Operasi I / O terlihat seperti:
Untuk operator yang diimplementasikan sebagai fungsi anggota, ini akan diselesaikan sebagai:
Yaitu, fungsi harus menjadi anggota
std::cout
, bukan darisomething
. Karena kami tidak inginstd::ostream
terus-menerus memodifikasi , satu-satunya pilihan kami yang masuk akal adalah membebani operator dengan fungsi bebas alih-alih fungsi anggota. Itu membuat kita memiliki dua kemungkinan: mengabaikan enkapsulasi sepenuhnya, dan membuat segala sesuatu di kelas publik, atau menjaganya tetap pribadi, tetapi memberikan akses ke beberapa hal yang benar-benar membutuhkannya.Membuat kelas lain menjadi teman agak kurang umum. Dalam hal ini, Anda biasanya membuat sesuatu berdasarkan urutan modul atau subsistem - sekumpulan kelas yang bekerja bersama dan memiliki beberapa tingkat akses khusus satu sama lain yang tidak diberikan kepada dunia secara luas.
sumber
Ada contoh yang cukup bagus tentang perlunya kelas teman dalam permintaan ini untuk kelas seperti teman di C # , bahasa yang tidak memilikinya.
Dikutip grosir di sini:
Mads Torgersen, C # Language PM, bahkan telah menjawab proposal ini, menyatakan bahwa kekhawatiran tersebut memang benar, tetapi tidak yakin tentang implementasi spesifik yang disarankan di sana.
C ++
friend
hanyalah salah satu cara untuk mengatasi masalah yang dijelaskan.sumber
Ketika Anda ingin kelas Anda memiliki hubungan monogami.
Misalnya ketika Anda tidak ingin kelas yang tidak dikenal mengakses privasi mereka, tetapi pasangan mereka membutuhkan akses.
sumber
Saya menemukan kelas teman di C ++ berguna di mana di Jawa saya akan menggunakan akses paket. Yaitu, saya memiliki banyak kelas yang sangat terkait sehingga ditulis dan dikelola sebagai satu unit, dalam file sumber yang sama. Siapa pun yang bekerja pada salah satu dari mereka benar-benar mengerjakan semuanya. Invarian yang mereka pertahankan dipertahankan bersama. Masuk akal bagi mereka untuk melihat internal satu sama lain sehingga mereka dapat mempertahankan invarian bersama mereka.
Yang tidak masuk akal adalah akses yang dilindungi. Jika tidak aman untuk mengekspos beberapa bagian dari internal saya kepada publik, itu tidak aman untuk mengeksposnya ke jackanapes apa pun yang muncul kemudian dalam proyek yang sama sekali tidak terkait dan mengklaim sebagai subclass saya. Biarkan subclass menggunakan antarmuka publik saya, sama seperti orang lain. (Kecuali mereka teman, tetapi dalam kasus itu saya menulisnya dan mengimplementasikannya di sumber yang sama, jadi mereka hampir tidak dari proyek lain.)
sumber
Katakanlah ada fungsi eksternal yang mengharuskan Anda untuk melakukan operasi pada anggota pribadi atau yang dilindungi dari dua kelas yang berbeda dalam program Anda. sekarang, agar fungsi itu mendapatkan akses dan benar-benar menggunakan anggota kelas ini, Anda harus menjadikannya teman dari kedua kelas. Perlu diingat bahwa dengan menjadikannya teman dari kedua kelas ini tidak menjadikannya sebagai anggota kelas, ia hanya mendapatkan prevelage untuk merujuk pada anggota pribadi atau yang dilindungi dari kelas-kelas ini. Saya dapat mengatakan bahwa Anda perlu menggunakan fungsi teman saat Anda ingin mengoperasikan objek dari dua kelas yang berbeda. Padahal terlalu seringnya fungsi teman dan kelas bisa mengurangi nilai enkapsulasi.
sumber