Saya mengerti sebagian besar operator overloading, dengan pengecualian dari operator akses anggota ->
, .*
, ->*
dll
Secara khusus, apa yang diteruskan ke fungsi operator ini, dan apa yang harus dikembalikan?
Bagaimana fungsi operator (mis. operator->(...)
) Mengetahui anggota yang dirujuk? Bisakah itu tahu? Apakah itu perlu diketahui?
Akhirnya, adakah pertimbangan const yang perlu dipertimbangkan? Misalnya, ketika melakukan overload seperti operator[]
, umumnya Anda memerlukan versi const dan non-const. Apakah operator akses anggota memerlukan versi const dan non-const?
c++
operator-overloading
c++-faq
Bingo
sumber
sumber
const
dan yang bukanconst
versioperator->
tidak diperlukan , tetapi menyediakan keduanya dapat bermanfaat.->*
dan.*
. Bahkan, itu bahkan tidak menyebutkannya! Saya merasa mereka jarang berada di FAQ, tetapi saya dengan senang hati menghubungkan pertanyaan ini dari FAQ. Tolong jangan tutup ini sebagai duplikat dari FAQ!Jawaban:
->
Ini adalah satu-satunya yang sangat rumit. Ini harus menjadi fungsi anggota yang tidak statis, dan tidak membutuhkan argumen. Nilai kembali digunakan untuk melakukan pencarian anggota.
Jika nilai kembali adalah objek lain dari tipe kelas, bukan pointer, maka pencarian anggota berikutnya juga ditangani oleh suatu
operator->
fungsi. Inilah yang disebut "perilaku boros." Bahasa menyatukanoperator->
panggilan sampai panggilan terakhir mengembalikan sebuah pointer.->*
Yang ini hanya rumit karena tidak ada yang istimewa tentang itu. Versi non-overload membutuhkan objek pointer ke tipe kelas di sisi kiri dan objek pointer ke tipe anggota di sebelah kanan. Tetapi ketika Anda membebani secara berlebihan, Anda dapat mengambil argumen apa pun yang Anda suka dan mengembalikan apa pun yang Anda inginkan. Bahkan tidak harus menjadi anggota yang tidak statis.
Dengan kata lain, yang satu ini hanyalah sebuah operator biner normal seperti
+
,-
, dan/
. Lihat juga: Apakah operator gratis -> * kelebihan beban jahat?.*
dan.
Ini tidak dapat kelebihan beban. Sudah ada makna bawaan ketika sisi kiri adalah tipe kelas. Mungkin akan masuk akal jika kita dapat mendefinisikannya sebagai penunjuk di sebelah kiri, tetapi komite desain bahasa memutuskan bahwa akan lebih membingungkan daripada berguna.
Overloading
->
,->*
,.
, dan.*
hanya dapat mengisi dalam kasus di mana ekspresi akan terdefinisi, tidak pernah mengubah arti dari ekspresi yang akan berlaku tanpa overloading.sumber
new
operator secara berlebihan , meskipun itu berlaku meskipun tidak kelebihan beban.new
selalu kelebihan beban, atau aturan kelebihan muatan tidak benar-benar berlaku untuk itu (13.5 / 5: Fungsi alokasi dan deallokasi, operator baru, operator baru [], operator hapus dan operator hapus [], dijelaskan sepenuhnya dalam 3.7 0,4. atribut dan pembatasan yang ditemukan di seluruh sub ayat ini tidak berlaku untuk mereka kecuali secara eksplisit dinyatakan dalam 3.7.4.) Tapi overloading unary&
atau biner&&
,||
atau,
, atau menambahkan overloads darioperator=
, atau overloading apa saja untuk unscoped jenis pencacahan, dapat mengubah makna ekspresi. Klarifikasi pernyataan itu, terima kasih!Operator -> spesial.
"Ia memiliki kendala tambahan yang tidak lazim: Ia harus mengembalikan objek (atau referensi ke objek) yang juga memiliki operator dereference pointer, atau harus mengembalikan pointer yang dapat digunakan untuk memilih apa yang ditunjuk oleh panah operator dereference pointer. " Bruce Eckel: Berpikir CPP Vol-one: operator->
Fungsionalitas tambahan disediakan untuk kenyamanan, jadi Anda tidak perlu menelepon
Anda bisa melakukannya:
Itu membuat operator -> berbeda dari kelebihan operator lainnya.
sumber
Anda tidak dapat membebani akses anggota
.
(yaitu bagian kedua dari apa yang->
tidak). Namun Anda dapat membebani operator dereferencing unary*
(yaitu bagian pertama dari apa yang->
tidak).Operator C ++
->
pada dasarnya adalah gabungan dari dua langkah dan ini jelas jika Anda berpikir itux->y
setara dengan(*x).y
. C ++ memungkinkan Anda untuk menyesuaikan apa yang harus dilakukan dengan(*x)
bagian tersebut ketikax
merupakan instance dari kelas Anda.Semantik untuk
->
overloading agak aneh karena C ++ memungkinkan Anda untuk mengembalikan pointer biasa (bahwa itu akan digunakan untuk menemukan objek runcing) atau untuk mengembalikan instance dari kelas lain jika kelas ini juga menyediakan->
operator. Ketika dalam kasus kedua ini pencarian untuk objek dereferensi berlanjut dari instance baru ini.sumber
->*
, karena setara dengan bentuk(*x).*
?The
->
operator tidak tahu apa anggota yang sedang menunjuk, itu hanya menyediakan sebuah objek untuk melakukan akses anggota yang sebenarnya pada.Selain itu, saya tidak melihat alasan mengapa Anda tidak dapat memberikan versi const dan non-const.
sumber
Ketika Anda membebani operator -> () (tidak ada argumen yang dilewatkan di sini), apa yang sebenarnya dilakukan oleh kompiler adalah -> secara rekursif hingga mengembalikan pointer aktual ke suatu tipe. Kemudian menggunakan anggota / metode yang benar.
Ini berguna, misalnya, untuk membuat kelas pointer cerdas yang merangkum pointer sebenarnya. Operator yang kelebihan beban dipanggil>, melakukan apa pun yang dilakukannya (mis. Mengunci keamanan benang), mengembalikan pointer internal dan kemudian kompiler memanggil -> untuk pointer internal ini.
Adapun keteguhan - sudah dijawab dalam komentar dan jawaban lainnya (Anda bisa, dan harus, memberikan keduanya).
sumber