Saya membaca bahwa operator yang kelebihan beban yang dideklarasikan sebagai fungsi anggota adalah asimetris karena hanya dapat memiliki satu parameter dan parameter lainnya yang dilewatkan secara otomatis adalah this
pointer. Jadi tidak ada standar untuk membandingkannya. Di sisi lain, operator yang kelebihan beban dideklarasikan sebagai a friend
adalah simetris karena kita melewatkan dua argumen dengan tipe yang sama dan karenanya, keduanya dapat dibandingkan.
Pertanyaan saya adalah bahwa ketika saya masih bisa membandingkan nilai pointer dengan referensi, mengapa teman lebih disukai? (menggunakan versi asimetris memberikan hasil yang sama dengan simetris) Mengapa algoritma STL hanya menggunakan versi simetris?
Jawaban:
Jika Anda mendefinisikan fungsi operator yang kelebihan beban sebagai fungsi anggota, maka compiler menerjemahkan ekspresi seperti
s1 + s2
menjadis1.operator+(s2)
. Itu berarti, fungsi anggota yang kelebihan beban operator akan dipanggil pada operan pertama. Begitulah cara kerja fungsi anggota!Tetapi bagaimana jika operan pertama bukan kelas? Ada masalah besar jika kita ingin membebani operator di mana operan pertamanya bukan tipe kelas, lebih tepatnya
double
. Jadi Anda tidak bisa menulis seperti ini10.0 + s2
. Namun, Anda dapat menulis fungsi anggota yang kelebihan beban operator untuk ekspresi sepertis1 + 10.0
.Untuk mengatasi masalah pengurutan ini , kami mendefinisikan fungsi operator overloaded sebagai
friend
JIKA ia perlu mengaksesprivate
anggota. Jadikanfriend
HANYA saat perlu mengakses anggota pribadi. Jika tidak, cukup buat fungsi non-teman non-anggota untuk meningkatkan enkapsulasi!Baca ini:
Sedikit masalah pemesanan di operan
Bagaimana Fungsi Non-Anggota Meningkatkan Enkapsulasi
sumber
friend
hanya ketika perlu mengakses anggota pribadi .. dan ketika Anda tidak memiliki / bosan menulis aksesor, kan?a/b
.friend
adalah dengan menerapkannya dalam istilah operator penugasan operasi (yang hampir pasti akan menjadi anggota publik). Misalnya, Anda dapat mendefinisikanT T::operator+=(const T &rhs)
sebagai anggota dan kemudian mendefinisikan non-anggotaT operator(T lhs, const T &rhs)
sebagaireturn lhs += rhs;
. Fungsi non-anggota harus didefinisikan dalam namespace yang sama dengan kelas.Ini belum tentu merupakan perbedaan antara
friend
kelebihan operator dan kelebihan operator fungsi anggota karena itu adalah antara kelebihan operator global dan kelebihan operator fungsi anggota.Salah satu alasan untuk memilih kelebihan operator global adalah jika Anda ingin mengizinkan ekspresi di mana jenis kelas muncul di sisi kanan operator biner. Sebagai contoh:
Ini hanya berfungsi jika ada kelebihan beban operator global untuk
Perhatikan bahwa kelebihan beban operator global tidak harus berupa
friend
fungsi. Ini hanya diperlukan jika memerlukan akses ke anggota pribadi dariFoo
, tetapi tidak selalu demikian.Terlepas dari itu, jika
Foo
hanya operator fungsi anggota yang kelebihan beban, seperti:... maka kita hanya dapat memiliki ekspresi di mana sebuah
Foo
instance muncul di sebelah kiri operator plus.sumber