Overloading operator dalam C ++ dianggap oleh banyak orang sebagai A Bad Thing (tm), dan kesalahan tidak diulang dalam bahasa yang lebih baru. Tentu saja, itu adalah salah satu fitur yang secara khusus dijatuhkan ketika mendesain Java.
Sekarang saya sudah mulai membaca di Scala, saya menemukan bahwa ia memiliki apa yang tampak seperti overloading operator (walaupun secara teknis ia tidak memiliki overloading operator karena tidak memiliki operator, hanya fungsi). Namun, sepertinya tidak akan berbeda secara kualitatif dengan overloading operator di C ++, di mana seingat saya operator didefinisikan sebagai fungsi khusus.
Jadi pertanyaan saya adalah apa yang membuat ide untuk mendefinisikan "+" di Scala ide yang lebih baik daripada di C ++?
c++
scala
operator-overloading
skaffman
sumber
sumber
Jawaban:
C ++ mewarisi operator biru yang sebenarnya dari C. Maksud saya bahwa "+" di 6 + 4 sangat istimewa. Anda tidak bisa, misalnya, mendapatkan pointer ke fungsi + itu.
Scala di sisi lain tidak memiliki operator seperti itu. Itu hanya memiliki fleksibilitas besar dalam mendefinisikan nama metode ditambah sedikit dibangun diutamakan untuk simbol non-kata. Jadi secara teknis Scala tidak memiliki kelebihan operator.
Apa pun yang Anda ingin menyebutnya, kelebihan operator pada dasarnya tidak buruk, bahkan di C ++. Masalahnya adalah ketika programmer buruk menyalahgunakannya. Tapi sejujurnya, saya berpendapat bahwa menghilangkan kemampuan programmer untuk menyalahgunakan kelebihan operator tidak akan membuat Anda memperbaiki semua hal yang bisa disalahgunakan oleh programmer. Jawaban sebenarnya adalah mentoring. http://james-iry.blogspot.com/2009/03/operator-overloading-ad-absurdum.html
Tidak ada yang kurang, ada perbedaan antara overloading operator C ++ dan metode penamaan yang fleksibel Scala yang, IMHO, membuat Scala lebih baik dan lebih kasar.
Di C ++ satu-satunya cara untuk mendapatkan notasi in-fix adalah menggunakan operator. Kalau tidak, Anda harus menggunakan object.message (argumen) atau pointer-> messsage (argumen) atau fungsi (argument1, argument2). Jadi jika Anda ingin gaya DSLish tertentu untuk kode Anda maka ada tekanan untuk menggunakan operator.
Di Scala Anda bisa mendapatkan notasi infiks dengan mengirim pesan apa pun. "argumen pesan objek" sangat oke, yang berarti Anda tidak perlu menggunakan simbol non-kata hanya untuk mendapatkan notasi infiks.
Kelebihan operator C ++ terbatas pada dasarnya operator C. Dikombinasikan dengan batasan bahwa hanya operator yang dapat menggunakan infiks yang menekan orang untuk mencoba memetakan berbagai konsep yang tidak terkait ke simbol yang relatif sedikit seperti "+" dan ">>"
Scala memungkinkan sejumlah besar simbol non-kata yang valid sebagai nama metode. Sebagai contoh, saya punya DSL Prolog-ish tertanam di mana Anda dapat menulis
Simbol: -,!,?, Dan & didefinisikan sebagai metode biasa. Dalam C ++ saja & akan valid sehingga upaya untuk memetakan DSL ini ke C ++ akan memerlukan beberapa simbol yang sudah membangkitkan konsep yang sangat berbeda.
Tentu saja, ini juga membuka Scala untuk jenis penyalahgunaan lainnya. Di Scala, Anda dapat memberi nama metode $! & ^% Jika mau.
Untuk bahasa lain yang, seperti Scala, fleksibel dalam penggunaan fungsi non-kata dan nama metode lihat Smalltalk di mana, seperti Scala, setiap "operator" hanyalah metode lain dan Haskell yang memungkinkan pemrogram untuk menentukan prioritas dan perbaikan dari nama fleksibel. fungsi.
sumber
int main() {return (3).operator+(5);}
menghasilkanerror: request for member ‘operator+’ in ‘3’, which is of non-class type ‘int’
Hanya oleh orang bebal. Ini benar-benar diperlukan dalam bahasa seperti C ++, dan terlihat bahwa bahasa lain yang mulai mengambil pandangan "purist", telah menambahkannya begitu desainer mereka mengetahui betapa perlunya itu.
sumber
Overloading operator tidak pernah secara universal dianggap sebagai ide buruk di C ++ - hanya penyalahgunaan operator overloading dianggap sebagai ide yang buruk. Seseorang tidak benar-benar membutuhkan operator kelebihan dalam bahasa karena mereka dapat disimulasikan dengan lebih banyak panggilan fungsi verbose. Menghindari overloading operator di Jawa membuat implementasi dan spesifikasi Java sedikit lebih sederhana dan memaksa programmer untuk tidak menyalahgunakan operator. Ada beberapa perdebatan di komunitas Jawa tentang memperkenalkan kelebihan operator.
Keuntungan dan kerugian kelebihan operator di Scala sama dengan di C ++ - Anda dapat menulis lebih banyak kode alami jika Anda menggunakan operator yang berlebihan secara tepat - dan kode yang lebih samar dan samar jika tidak.
FYI: Operator tidak didefinisikan sebagai fungsi khusus dalam C ++, mereka berperilaku seperti fungsi lainnya - meskipun ada beberapa perbedaan dalam pencarian nama, apakah mereka perlu menjadi fungsi anggota, dan fakta bahwa mereka dapat dipanggil dengan dua cara: 1 ) sintaksis operator, dan 2) sintaksis fungsi-operator-id.
sumber
add(2, multiply(5, 3))
?Artikel ini - " Warisan Positif C ++ dan Java " - menjawab pertanyaan Anda secara langsung.
Java keliru (menurut penulis) menghilangkan overloading operator karena rumit dalam C ++, tetapi lupa mengapa (atau tidak menyadari bahwa itu tidak berlaku untuk Java).
Untungnya, bahasa tingkat yang lebih tinggi seperti Scala memberikan opsi kepada pengembang, sementara masih berjalan pada JVM yang sama.
sumber
Tidak ada yang salah dengan kelebihan operator. Bahkan, ada yang salah dengan tidak memiliki operator kelebihan untuk tipe numerik. (Lihatlah beberapa kode Java yang menggunakan BigInteger dan BigDecimal.)
C ++ memiliki tradisi menyalahgunakan fitur. Contoh yang sering dikutip adalah bahwa operator bitshift kelebihan beban untuk melakukan I / O.
sumber
=
alih-alih<<
dan>>
pada hari-hari awal C ++, tetapi mengalami masalah karena tidak memiliki prioritas operator yang tepat (yaitu apakah ia mencari argumen di sebelah kiri atau kanan terlebih dahulu). Jadi tangannya agak terikat tentang apa yang bisa dia gunakan.Secara umum itu bukan hal yang buruk.
Bahasa baru seperti C # juga memiliki kelebihan operator.
Itu adalah penyalahgunaan operator overloading yang merupakan hal yang buruk.
Tetapi ada juga masalah dengan overloading operator sebagaimana didefinisikan dalam C ++. Karena operator kelebihan beban hanyalah gula sintaksis untuk pemanggilan metode, mereka berperilaku seperti metode. Di sisi lain, operator bawaan normal tidak berperilaku seperti metode. Ketidakkonsistenan ini dapat menyebabkan masalah.
Dari atas operator kepala saya
||
dan&&
.Versi bawaannya adalah operator pintasan. Ini tidak benar untuk versi kelebihan beban dan telah menyebabkan beberapa masalah.
Fakta bahwa + - * / semua mengembalikan jenis yang sama dengan yang mereka operasikan (setelah promosi operator)
Versi kelebihan beban dapat mengembalikan apa pun (Di sinilah penyalahgunaan terjadi, Jika operator Anda mulai mengembalikan beberapa jenis arbiter yang tidak diharapkan pengguna tidak diharapkan oleh pengguna) semuanya turun bukit).
sumber
Overloading operator bukanlah sesuatu yang benar-benar Anda "butuhkan" sangat sering, tetapi ketika menggunakan Java, jika Anda mencapai titik di mana Anda benar-benar membutuhkannya, itu akan membuat Anda ingin merobek kuku Anda hanya agar Anda memiliki alasan untuk berhenti mengetik .
Kode yang baru saja Anda temukan melimpah? Yup, Anda harus mengetik ulang keseluruhan untuk membuatnya bekerja dengan BigInteger. Tidak ada yang lebih membuat frustrasi bahwa harus menemukan kembali roda hanya untuk mengubah jenis variabel.
sumber
Guy Steele berpendapat bahwa overloading operator harus di Jawa juga, dalam pidatonya "Menumbuhkan bahasa" - ada video dan transkripsi, dan itu benar-benar pidato yang luar biasa. Anda akan bertanya-tanya apa yang dia bicarakan untuk beberapa halaman pertama, tetapi jika Anda terus membaca, Anda akan melihat intinya dan mencapai pencerahan. Dan fakta bahwa dia bisa melakukan pidato seperti itu sama sekali juga luar biasa.
Pada saat yang sama, ceramah ini menginspirasi banyak penelitian mendasar, mungkin termasuk Scala - ini adalah salah satu makalah yang harus dibaca semua orang untuk bekerja di lapangan.
Kembali ke titik, contoh-contohnya sebagian besar tentang kelas numerik (seperti BigInteger, dan beberapa hal aneh), tetapi itu tidak penting.
Memang benar, bahwa penyalahgunaan overloading operator dapat menyebabkan hasil yang mengerikan, dan bahkan penggunaan yang tepat dapat memperumit masalah, jika Anda mencoba membaca kode tanpa mempelajari sedikit perpustakaan yang digunakan. Tapi apakah itu ide yang bagus? OTOH, bukankah perpustakaan seperti itu harus mencoba memasukkan lembar contekan operator untuk operator mereka?
sumber
Saya percaya SETIAP jawaban terjawab ini. Di C ++ Anda bisa membebani operator semau Anda, tetapi Anda tidak bisa memengaruhi prioritas yang telah mereka evaluasi. Scala tidak memiliki masalah ini, IIRC.
Adapun itu menjadi ide yang buruk, selain masalah diutamakan, orang-orang datang dengan makna yang sangat gila untuk operator, dan jarang membantu keterbacaan. Perpustakaan scala sangat buruk untuk ini, simbol konyol yang harus Anda hafal setiap kali, dengan pengelola perpustakaan menempelkan kepala mereka di pasir berkata, 'Anda hanya perlu mempelajarinya sekali saja'. Hebat, sekarang saya perlu belajar beberapa sintaksis samar 'pintar' penulis * jumlah perpustakaan yang saya ingin gunakan. Tidak akan terlalu buruk jika ada konvensi SELALU menyediakan versi melek huruf dari operator.
sumber
Overloading operator bukanlah penemuan C ++ - itu berasal dari Algol IIRC dan bahkan Gosling tidak mengklaim itu adalah ide yang buruk secara umum.
sumber
Satu-satunya hal yang diketahui salah dalam C ++ adalah kurangnya kemampuan untuk membebani [] = sebagai operator terpisah. Ini bisa sulit untuk diterapkan dalam kompiler C ++ untuk apa yang mungkin bukan alasan yang jelas tetapi banyak yang sepadan.
sumber
Seperti yang ditunjukkan oleh jawaban lain; Operator overloading itu sendiri tidak selalu buruk. Apa yang buruk ketika digunakan dengan cara yang membuat kode yang dihasilkan tidak jelas. Umumnya ketika menggunakan mereka, Anda perlu membuat mereka melakukan hal yang paling tidak mengejutkan (memiliki divisi operator + do akan menyebabkan masalah untuk penggunaan kelas rasional) atau seperti yang dikatakan Scott Meyers:
Sekarang beberapa orang telah mengambil kelebihan operator ke ekstrim dengan hal-hal seperti boost :: spirit . Pada level ini Anda tidak tahu bagaimana ini diterapkan tetapi itu membuat sintaks yang menarik untuk mendapatkan apa yang Anda inginkan. Saya tidak yakin apakah ini baik atau buruk. Tampaknya bagus, tetapi saya belum menggunakannya.
sumber
Saya belum pernah melihat artikel yang mengklaim bahwa overloading operator C ++ buruk.
Operator yang ditentukan pengguna memungkinkan tingkat ekspresivitas dan kegunaan yang lebih tinggi dan mudah bagi pengguna bahasa.
sumber
AFAIK, Tidak ada yang istimewa dalam fungsi operator dibandingkan dengan fungsi anggota "normal". Tentu saja Anda hanya memiliki satu set operator tertentu yang dapat kelebihan beban, tetapi itu tidak membuat mereka sangat istimewa.
sumber