Haruskah kita menghindari fitur bahasa yang dimiliki C ++ tetapi Java tidak?

110

Misalkan saya terbatas untuk menggunakan C ++ oleh lingkungan dalam proyek. Apakah baik untuk mencegah penggunaan beberapa fitur bahasa yang dimiliki C ++ tetapi Java tidak memiliki (mis: multiple inheritance, operator overloading)?

Saya pikir alasannya adalah:

  1. Karena Java lebih baru dari C ++, jika Java tidak menyediakan fitur yang dimiliki C ++, itu berarti fitur tersebut tidak baik, jadi kita harus menghindari menggunakannya.
  2. Kode C ++ dengan fitur khusus C ++ (mis: fungsi teman, pewarisan berganda) hanya dapat dipertahankan atau ditinjau oleh programmer C ++, tetapi jika kita hanya menulis C ++ seperti Java (tanpa fitur khusus bahasa C ++), kode tersebut dapat dipertahankan atau ditinjau oleh keduanya Pemrogram C ++ dan Java.
  3. Anda mungkin akan diminta untuk mengonversi kode ke Java suatu hari nanti
  4. Kode tanpa fitur spesifik C ++ biasanya lebih mudah dikelola
  5. Setiap fitur khusus bahasa C ++ (mis: multiple inheritance) harus memiliki alternatif untuk diimplementasikan di Java. Jika tidak, itu berarti pola desain atau arsitektur kode bermasalah.

Benarkah itu?

ggrr
sumber
7
Jika Anda melihat saran Anda, Anda berbicara tentang membuat standar pengkodean. Fakta bahwa Anda membuat dan mengikuti standar sebenarnya adalah apa yang akan meningkatkan pemeliharaan.
Brandin
63
Haruskah kode Java juga dibatasi untuk fitur, yang juga ditemukan dalam bahasa C ++? Jadi jangan gunakan misalnya Java volatile, akses anggota kelas-swasta, refleksi / introspeksi, akhirnya-blok, pengecekan pengecualian, dan sebagainya? Seluruh jenis pertanyaan tidak masuk akal ... C ++ dan Java dangkal serupa, tetapi pada akhirnya bahasa yang sangat berbeda.
Hyde
5
Bagaimana bahasa berkembang jika orang tidak mau menggunakan fitur baru? Tujuan dari fitur-fitur baru ini adalah untuk membuat hidup Anda lebih mudah dengan memecahkan masalah umum. Jika pengguna tidak menggunakan fitur baru, maka tidak ada motivasi bagi siapa pun untuk mengimplementasikannya.
Matius
72
Jika Anda ingin Java, gunakan Java. Jika Anda menggunakan C ++, gunakan C ++, bukan imitasi Java yang mengerikan dan terpuntir dengan sintaksis C ++. Menggunakan C ++ tetapi membatasi diri Anda ke set fitur Java memberi Anda yang terburuk dari kedua dunia.
Jerry Coffin
11
Anda akan terkejut dengan seberapa cepat perbedaan akan menggigit Anda (dan sulit ). SomeObject a = previousObject;melakukan hal yang sangat berbeda di Java dan C ++. Di Jawa itu menyalin referensi, sementara di C ++ itu menyalin objek. Di Jawa, modifikasi ajuga akan mempengaruhi objek sebelumnya. Di C ++, Anda memiliki dua objek terpisah.
Clockwork-Muse

Jawaban:

307

Tidak. Ini menyedihkan dan sangat salah arah.

  • Fitur Java tidak lebih baik daripada fitur C ++, terutama dalam ruang hampa.
  • Jika programmer Anda tidak tahu cara menggunakan fitur, latih atau pekerjakan pengembang yang lebih baik; membatasi pengembang Anda hingga yang terburuk dari tim Anda adalah cara cepat dan mudah untuk kehilangan pengembang yang baik.
  • YAGNI . Selesaikan masalah Anda yang sebenarnya hari ini, bukan hantu dari beberapa masalah di masa depan.
Telastyn
sumber
6
Ada pertanyaan baru-baru ini tentang pengembang yang meninjau kode dalam bahasa yang biasanya tidak mereka tulis. Saya pikir kebijaksanaan di sini berlaku di sini: pengembang yang baik akan menemukan banyak kesalahan mendasar dalam hampir semua bahasa, tetapi setiap bahasa memiliki begitu banyak gotchas sehingga manfaat maksimal dicapai ketika pengembang dalam bahasa melakukan peninjauan. Ini bahkan benar jika C ++ Anda adalah "Fitur Java saja".
corsiKa
5
+1 Selain poin kedua Anda. OP harus meluangkan waktu untuk membaca tentang "Praktik Terbaik C ++" untuk memutuskan fitur mana yang harus mereka gunakan. Informasi terakhir saya tentang C ++ adalah bahwa fungsi teman dan banyak pewarisan dianggap Praktik Buruk . Hal-hal seperti Templat dan Operator Overloading adalah praktik yang baik IMHO jika Anda menggunakannya dengan bijak.
some_coder
4
@some_coder: Ini semua masalah mengetahui kapan, dan di mana. Ketika saya melakukan pemrograman berbasis kebijakan, saya mewarisi dari (mungkin beberapa) kelas kebijakan untuk memperluas struktur kelas host saya dengan anggota yang dibutuhkan oleh kelas-kelas kebijakan tersebut. Itu hanya cara kerjanya. Juga, operator<<( ostream &, T const & )biasanya diimplementasikan melalui friend. Itulah masalah dengan pernyataan selimut tentang apa fitur bahasa yang baik dan apa yang buruk: Mereka adalah saran yang bagus, kecuali ketika mereka tidak ...
DevSolar
142

Hanya karena sintaksnya tampak serupa di permukaan tidak berarti kedua bahasa tersebut kompatibel.

1, 4 dan 5 adalah pertanyaan yang sama:

Sekarang, saya bukan penggemar C ++, tetapi mengatakan "Kode tanpa fitur khusus C ++ biasanya lebih dapat dipertahankan" hanya konyol - apakah Anda benar-benar percaya bahwa Java mendapatkan segalanya dengan benar, dan mengambil semua fitur yang baik sambil mengabaikan semua yang buruk? Apakah Anda benar-benar percaya ada sesuatu yang secara universal merupakan fitur "buruk" atau "baik"? Jika ada, mengapa kita tidak memiliki satu bahasa yang murni baik? Dan tidak, Java jelas bukan bahasa itu. Apakah itu berarti bahwa Java dan C ++ tidak berguna? Tentu saja tidak.

Bagaimana jika pemimpin Anda memutuskan bahwa Anda akan melakukan porting ke C #, bukan ke Jawa? C # tidak hanya mendukung operator utama, tetapi juga default - jika Anda akan meminta orang untuk menggunakan mis. obj.Equals(obj2)Alih-alih obj == obj2, orang akan membuat kesalahan sepanjang waktu. Bahkan jika Anda hanya mempertahankan fitur-fitur umum dari kedua bahasa itu, ada harapan yang berbeda, budaya yang berbeda. Jika Anda melakukan sesuatu seperti if (myField == null)di C ++, orang akan segera melihat Anda seorang pemula. Jika Anda menggunakan if (null == myField)dalam C #, orang akan melihat Anda belum benar-benar asli C # - alasan C pengembang belajar untuk menggunakan varian "membalik" tidak lagi ada dalam C #.

Menggunakan logika Anda, kita seharusnya terjebak dengan kode mesin atau perakitan atau COBOL, karena mengapa pernah berubah menjadi sesuatu seperti Pascal, ketika itu hanya menambahkan fitur baru yang harus dipelajari oleh programmer Anda? Mengapa kita menggunakan sesuatu seperti SQL, padahal ia tidak memiliki loop ? Mengapa kita pernah menggunakan sesuatu yang lain dari SQL, ketika SQL tidak memiliki loop dan X tidak?

Kode C ++ tentu saja tidak dapat dikelola oleh programmer Java. Saya tidak mengerti dari mana Anda mendapatkan ide ini - apa yang sebenarnya tersisa ketika Anda membatasi C ++ hanya pada fitur yang bekerja persis sama dengan di Jawa? Anda bahkan tidak akan mendapatkan panggilan metode - bahkan panggilan fungsi pun tidak . Sekali lagi, hanya karena kedua bahasa menggunakan kurung kurawal, tidak berarti bahwa bahasa-bahasa tersebut dapat saling dipertukarkan.

Mengkonversi kode C ++ seperti Java akan sangat rentan kesalahan apa pun yang Anda lakukan. Terlalu banyak perbedaan. Jika Anda ingin harus menulis ulang aplikasi Anda dalam bahasa yang berbeda, pikirkan cara yang masuk akal untuk memodulasi semuanya, sehingga Anda dapat mengganti komponen tanpa merusak keseluruhannya. Tetapi pada akhirnya, YAGNI - tidak peduli apa yang Anda lakukan, akan ada biaya yang signifikan untuk membuat kode Anda "siap untuk dikonversi ke Jawa". Itu waktu yang kemungkinan besar lebih baik dihabiskan untuk menambah atau meningkatkan fitur Anda.

Kami menggunakan bahasa yang berbeda karena mereka memberi kami seperangkat alat yang berbeda untuk menyelesaikan masalah. Jika Anda membutuhkan file yang dapat dieksekusi yang berfungsi "di mana saja", gunakan Java. Jika Anda ingin kode yang mengkompilasi "di mana-mana", C ++ berfungsi dengan baik. Jika Anda menginginkan kode yang mudah dipahami dan diurai, gunakan LISP atau apa pun. Tetapi saya dapat memberitahu Anda satu hal - menulis kode dalam satu bahasa seolah-olah Anda menulisnya dalam bahasa lain selalu merupakan kesalahan, dan Anda akan menderita. Belum lagi ketika Anda benar-benar menyewa seorang pria C ++, ia akan menjalankan kode kedua ketika ia melihat bahwa kode "Java-ish compatible". Dan ... orang Jawa itu akan melakukan hal yang sama. Anda tahu, bahkan "mengetahui" C ++ dan Java, saya akan berlari sangat keras :)

Saya benar-benar harus bekerja pada (C) kode C yang ditulis oleh pengembang Pascal yang sepertinya berpikir seperti Anda. Dia menggunakan #defines untuk mendefinisikan ulang C agar terlihat dan terasa lebih seperti Pascal, lengkap dengan hal-hal seperti "BEGIN diterjemahkan menjadi {". Hasilnya agak dapat diprediksi - kode yang tidak dapat dipahami oleh pengembang C atau Pascal, dan penuh dengan bug yang merupakan akibat dari "abstraksi" bocor Pascal di atas C. Dan Pascal dan C hampir identik dari sudut pandang hari ini. Bahkan pergi C <-> C ++ jauh lebih berbeda, dan itu masih kacang untuk sesuatu seperti C ++ <-> Java.

Luaan
sumber
9
"Jika Anda menginginkan kode yang mudah dimengerti dan diurai, lanjutkan dengan LISP atau apa pun." Saya tidak akan setuju dengan itu. Lisp sepele untuk diurai, tetapi justru karena ini - karena ia diciptakan pada masa ketika pengetahuan tentang parser dan prinsip-prinsip di balik membangunnya secara efektif masih dalam masa pertumbuhan, sehingga mereka mengerjai dan pergi dengan hal yang paling sederhana yang sangat sederhana yang mungkin bisa berfungsi - Anda tidak mendapatkan banyak manfaat sintaksis dari bahasa modern. Jadi mudah diurai, tapi sama sekali tidak mudah dimengerti . Ada alasan mengapa orang menyebutnya "Lost In Superfluous Parentheses."
Mason Wheeler
9
@MasonWheeler Itu masalah selera - programmer C menyebutnya begitu, bukan LISPers: P. Hitung kurung - ada sekitar sebanyak dalam program C ++ khas Anda. Perbedaan sebenarnya adalah posisi mereka ( myFunc()versus (myFunc)), dan itu memiliki alasan yang sangat bagus. Bahasa berbasis LISP masih sangat populer, terutama dengan orang-orang matematika / fisika. Hal utama sebenarnya adalah bahwa bahasa LISPy sangat asing bagi programmer C-style modern - tetapi itu bukan alasan untuk mengabaikannya. Skema, Clojure, dan sampai tingkat bahasa berbasis ML (OCaml, F # ...) memang sangat LISPy.
Luaan
4
@Luaan Saya dapat memberitahu Anda dengan pasti bahwa LISP TIDAK populer di bidang fisika. Dua bahasa dominan di lapangan adalah FORTRAN dan C ++. FORTRAN 'populer' karena begitu banyak kode lama ditulis di dalamnya, tetapi hampir semua program baru ditulis dalam C ++. Sebagai seorang ahli fisika penelitian, saya belum pernah menemukan atau bahkan mendengar tentang program LISP. Bukan untuk mengatakan mereka tidak ada, tetapi bahasa jelas tidak populer .
James Matta
4
@Luaan Kami mungkin atau mungkin tidak membutuhkan lebih banyak pengembang perangkat lunak. Kami jelas tidak membutuhkan lebih banyak lulusan CS. Itu seperti mengatakan "kita membutuhkan lebih banyak insinyur struktural, jadi kita membutuhkan lebih banyak lulusan fisika teoretis."
Miles Rout
4
@ user1717828 Ini untuk menghindari efek menyenangkan dari salah ketik if (myField == null)sebagai if (myField = null), yang akan mengkompilasi baik-baik saja C / C ++, tapi mungkin tidak melakukan apa yang Anda inginkan. Di sisi lain, if (null = myField)akan melempar kesalahan, karena Anda tidak dapat menetapkan konstanta.
Wlerin
94

Saya akan menjawab pertanyaan Anda secara berurutan.

  1. Jika Java tidak menyediakan fitur yang dimiliki C ++, itu berarti fitur tersebut tidak bagus, jadi kami harus mencegah menggunakannya.

Ya, fitur apa pun yang tidak ada di Jawa adalah laknat pada hard drive. Itu harus dibakar dari basis kode Anda. Mereka yang tidak taat akan dimusnahkan, jiwa mereka digunakan untuk menenangkan dewa RAID.

  1. Kode C ++ dengan fitur khusus C ++ (mis: fungsi teman, pewarisan berganda) hanya dapat dipertahankan atau ditinjau oleh programmer C ++, tetapi jika kita hanya menulis C ++ seperti Java (tanpa fitur khusus bahasa C ++), kode tersebut dapat dipertahankan atau ditinjau oleh keduanya Pemrogram C ++ dan Java.

Jika ragu, tulis kode untuk anggota tim Anda yang paling tidak kompeten. Kode dibaca jauh lebih sering daripada yang tertulis, dan kode yang sepintar yang Anda bisa tulis terlalu pintar untuk dibaca. Ulasan kode yang tidak dimengerti oleh staf meja depan Anda harus ditolak. Untuk membantu, ajari mereka cara memprogram dalam visual basic 2.0 selama akhir pekan, kemudian meniru gaya pengkodean mereka dalam bahasa apa pun yang Anda gunakan.

  1. Anda mungkin akan diminta untuk mengonversi kode ke Java suatu hari nanti

Benar! Tapi mengapa berhenti di Jawa? Anda mungkin diminta untuk mengubah kode menjadi dasar, assembler dan / atau perl suatu hari. Karena ada penerjemah perl di setiap bahasa di luar sana, cukup tulis program Anda sebagai string perl panjang, dan argumen marshal ke dalamnya dalam bahasa pilihan.

Sekarang ketika Anda perlu mengubah bahasa, cukup menulis ulang kode yang membungkus string perl.

  1. Kode tanpa fitur spesifik C ++ biasanya lebih mudah dikelola

Memang benar bahwa kode yang menggunakan lebih sedikit fitur lebih mudah dipelihara. Dan karena semua bahasa setara dengan Mesin Turing, dan Mesin Turing memiliki fitur paling sedikit dari bahasa pemrograman mana pun, minta penerjemah perl di atas benar-benar menjalankan Mesin Turing (pita dan semua) yang menyelesaikan masalah Anda.

  1. Setiap fitur khusus bahasa C ++ (mis: multiple inheritance) harus memiliki alternatif untuk diimplementasikan di Java. Jika tidak, itu berarti pola desain atau arsitektur kode bermasalah.

Fitur khusus bahasa C ++ sebenarnya memiliki penggunaan yang berharga. Karena mereka bukan Jawa, mereka laknat, dan mereka yang menggunakannya bisa dianggap bidat. Jika C ++ tidak memiliki fitur-fitur bahasa tersebut, Anda tidak akan dapat menemukan fitur yang perlu Anda korbankan. Fitur bahasa C ++ menyelesaikan masalah!


Lihat, C ++ dan Java memiliki serangkaian kemampuan yang berbeda. Pemrograman di persimpangan C ++ dan Java menghasilkan kode yang telah membuang sebagian besar keuntungan dari kedua bahasa.

Java dikembangkan sebagian sebagai reaksi terhadap beberapa penyalahgunaan fitur C ++. Ini tidak berarti bahwa reaksi itu dibenarkan, terutama bertahun-tahun setelah itu ketika fitur telah matang.

Anda dapat melakukan hal-hal mengerikan dengan kelebihan operator; tetapi tidak ada bahasa yang dapat mencegah kode mengerikan ditulis dalam bahasa, kecuali itu menghentikan semua kode yang ditulis dalam bahasa.

Dan Anda juga dapat melakukan hal-hal yang sangat elegan dengan overloading operator. Hal-hal sederhana, seperti bilangan kompleks atau kelas matriks yang berfungsi seperti bilangan kompleks atau matriks.

Perhatian tentang penggunaan fitur C ++ yang tidak tersedia di Java harus dilihat dengan hati-hati. Hanya karena sekumpulan pengembang Anda saat ini pada tingkat keahlian mereka saat ini tidak memahami suatu fitur tidak berarti itu tidak boleh digunakan; pada saat yang sama, hanya karena Anda dapat menggunakan fitur, tidak berarti Anda harus melakukannya. Namun, di toko Java-berat, kemungkinan resistensi akan lebih kuat daripada seharusnya terhadap fitur non-Jawa-esque.

Konversi kode antar bahasa paling baik dilakukan dengan penulisan ulang, tidak peduli seberapa miripnya mereka. Segala upaya untuk melakukannya tanpa penulisan ulang seperti itu akan gagal total.

Banyak fitur khusus C ++ yang luar biasa untuk pemeliharaan. Ketik penghapusan (seperti std::function) memungkinkan Anda memisahkan hierarki, yang mengurangi ketergantungan. Pointer pintar dan daya tahan deterministik dan RAII mengurangi kejutan runtime, dan memindahkan sumber daya boiler keluar dari jalan. Pemeriksaan tipe statis berarti kode gagal dikompilasi, bukan gagal berfungsi. Campuran mengurangi duplikasi kode. ADL memungkinkan ekstensi antarmuka ad-hoc independen antara hierarki jenis. Lambda memungkinkan Anda menulis kode di sebelah tempat kode itu digunakan. Meneruskan dan memindahkan mengurangi salinan, dan membuat pemrograman fungsional (bebas efek samping) efisien. Overloading operator mengurangi derau saluran, dan membuat kode lebih terlihat seperti matematika yang dimodelkan.

Waspadai lubang Turing Tar. Anda dapat mengimplementasikan segala sesuatu dalam bahasa apa pun (termasuk Mesin Turing mentah dengan Tape), tetapi itu tidak berarti Anda harus melakukannya . Meniru fitur C ++ menggunakan konstruksi Java-esque di C ++ adalah ide yang mengerikan; itu akan menghasilkan kode yang tidak dapat dipelihara yang tidak dapat dibaca atau dipahami oleh siapa pun.

Anda dapat mengambil inspirasi dari desain Java dan memindahkannya ke C ++. Saya penggemar berat mengambil fitur bahasa Python dan mengimplementasikannya dalam C ++, karena saya suka sintaks. Tapi itu tidak berarti saya menulis metode kelas saya sebagai metode statis mengambil diri eksplisit, kemudian menulis pembungkus yang meneruskan panggilan metode non-statis untuk itu.

C ++ Modern tidak terlalu mirip dengan bahasa yang ditiru dan ditolak oleh Java. Jangan dikunci oleh fitur satu bahasa; tidak ada "satu bahasa yang benar". Pelajari tentang bahasa baru dan fitur-fiturnya, dan serap kekhasannya.

Yakk
sumber
1
-1, bertele-tele dan tidak jelas.
Djechlin
4
-1 argumentatif, argumen straw-man
user949300
28
+1, dekonstruksi yang tepat dari pertanyaan yang diajukan dan saya tertawa :)
cat
11
+1. Lucu tapi tetap pada intinya. Sangat jelas bagi orang yang benar-benar membacanya.
Luis Masuelli
14
"Pemrograman di persimpangan C ++ dan Java menghasilkan kode yang telah membuang sebagian besar keunggulan kedua bahasa." Memukul paku di kepala! +1
Ajedi32
56

Saya hanya akan menjawab alasan Anda:

  1. Saya tidak mengerti bagaimana Anda sampai pada kesimpulan itu. Bahasa yang berbeda memiliki fitur yang berbeda. Tergantung pada ruang lingkup, arsitektur bahasa, kadang-kadang preferensi pencipta dan banyak lagi alasan. Beberapa fitur bahasa mungkin buruk, tetapi generalisasi Anda IMHO salah.
  2. Menulis C ++ seperti Java dapat menyebabkan kode yang lebih buruk. Misalnya saat ini dengan C ++ 11 saya menghindari menggunakan baru / menghapus, tetapi menggunakan pointer bersama. Dalam skenario Anda, saya hanya akan bergantung pada baru / hapus. Jika programmer Anda hanya mengerti Java, latih mereka atau pekerjakan yang lebih baik.
  3. Apakah itu mungkin akan terjadi? Mengapa Anda tidak menulis di Jawa? Saya pikir menulis ulang program dari awal dalam bahasa baru umumnya merupakan ide yang buruk dan Anda akan membutuhkan pembenaran yang sangat baik untuk risiko seperti itu.
  4. Ini hanya sebuah asumsi.
  5. Tergantung IMHO pada skenario atau kasus penggunaan Anda.
Simon
sumber
27
Dan Java-Programmer tidak akan menggunakan deletekeduanya.
Paŭlo Ebermann
8
Saya harus memperbaiki kebocoran memori yang disebabkan oleh programmer Java yang tidak tahu delete. Dari apa yang saya ingat, setidaknya dalam salah satu kasus itu, alokasi dinamis ( new) juga tidak diperlukan.
Ethan Kaminski
16
@EthanKaminski Ya, itulah bagaimana Anda dapat dengan mudah menemukan pemula C ++, terutama seseorang yang berasal dari latar belakang Java atau sejenisnya. Berhentilah menggunakan yang baru untuk semuanya, sial!
Luaan
1
@ PaŭloEbermann Ya, bahkan lebih buruk.
Simon
1
"Dalam skenario Anda, saya hanya akan bergantung pada baru / hapus" - lucu, saya akan berpikir bahwa "Java (seperti) - fitur saja" idiom C ++ akan digunakan secara eksklusif make_shared.
Kyle Strand
26

Java memiliki fitur-fitur yang tidak dimiliki C ++, seperti pengumpul sampah bawaan, cepat, andal, hierarki objek satu-akar, dan introspeksi yang kuat.

Fitur-fitur lain dari Java dirancang untuk bekerja bersama dengan fitur-fitur eksklusif Java, dan banyak fitur Java dari penghilangan C ++ dimungkinkan karena fitur-fitur baru menutupi kekurangannya. Misalnya, Java tidak memiliki objek yang dialokasikan stack dengan destruktor deterministik, tetapi akhirnya memblokir (dan mencoba-dengan-sumber daya sejak Java 7) dan pengumpul sampah untuk menebus kekurangan ini.

C ++ akhirnya tidak memiliki blok atau pengumpulan sampah. Jika Anda tidak menggunakan destruktor karena tidak ada di Jawa (saya tidak menghitung finalizer), Anda berada pada level C dari manajemen sumber daya (yaitu semua manual), kecuali bahwa Anda bahkan tidak dapat mengelompokkan pembersihan Anda. menjadi blok pembersihan yang Anda goto, karena Java tidak memiliki goto juga. Apakah Anda benar-benar berpikir bahwa meningkatkan rawatan?

Java memiliki hierarki objek yang memayungi di mana setiap kelas akhirnya berasal dari Object, dan beberapa tipe primitif dapat secara otomatis dimasukkan ke dalam kelas-kelas semacam itu juga. Ini memungkinkan penulisan wadah objek sekali, untuk memegang pointer ke Obyek. Java 5 memperkenalkan obat-obatan generik, yang menyingkirkan gips yang diperlukan wadah tersebut, tetapi masih dapat dikompilasi dengan kode yang hampir sama.

C ++ tidak memiliki hierarki seperti itu. Untuk memudahkan penulisan wadah yang berfungsi untuk banyak jenis, Anda menggunakan templat, yang merupakan cetak biru yang dipakai oleh kompiler yang diperlukan untuk berbagai jenis. Apakah Anda akan melarang penggunaan template (dan makro) dan pergi rute C baik menulis kode kontainer yang sama berulang-ulang untuk berbagai jenis, atau menggunakan void pointer? (Tunggu, Java tidak memiliki void pointer!) Apakah Anda yakin ini akan meningkatkan rawatan?

Bahasa yang layak memiliki banyak fitur yang dirancang untuk bekerja bersama. Dengan melarang fitur-fitur dari bahasa A karena bahasa B tidak memilikinya, Anda melumpuhkan bahasa A, karena Anda pada saat yang sama tidak menambahkan fitur-fitur dari B yang membuat B menjadi keseluruhan yang koheren.

Itu bukan untuk mengatakan bahwa Anda tidak harus membatasi fitur C ++ yang diizinkan. C ++ adalah bahasa besar yang dikembangkan secara historis yang menekankan memungkinkan programmer untuk melakukan apa yang diinginkannya atas keamanan dan kemudahan penggunaan, dan tidak semua fitur dalam semua fleksibilitasnya diperlukan untuk membangun program yang baik. Ada banyak standar pengkodean yang membatasi penggunaan beberapa fitur; misalnya pedoman Google sebagian besar melarang pewarisan berganda, templat kompleks, dan pengecualian (meskipun yang terakhir karena alasan historis). Tetapi tidak ada fitur yang dilarang "karena Java tidak memilikinya"; fitur dianggap dalam kerangka C ++ saja.

Sebastian Redl
sumber
27
Veteran C ++ berpengalaman biasanya menolak pedoman pengkodean Google. C ++ modern jauh lebih baik karena menggunakan fitur-fitur itu. Ya, itu membuatnya semakin berbeda.
Jan Hudec
17
Perhatikan bahwa C ++ akhirnya tidak memiliki blok, tetapi memiliki RAII, yang jauh lebih baik untuk sebagian besar kasus. Dan, sekali lagi, berbeda.
Jan Hudec
7
Java Objectcukup banyak void*digunakan - Masih, yuck.
Quentin
1
Di luar pilihan fitur, ada masalah gaya dan idiom. Program umumnya lebih mudah dibaca dan dipelihara jika mereka menggunakan idiom normal untuk bahasa di mana mereka ditulis. Bahkan jika seseorang dapat menulis sebagian dari program C ++ hanya menggunakan fitur seperti Java, hasilnya akan aneh, C ++ kaku.
Patricia Shanahan
2
Saya akan memilih jawaban ini karena berada di jalur yang benar ("jangan lakukan itu"), tetapi saya tidak tahan dengan premis dasar bahwa Jawa entah bagaimana "lebih maju" daripada C ++. C ++ tidak memerlukan pengumpul sampah atau hierarki objek root tunggal, dengan cara yang sama Java tidak perlu ... err ... maaf saya tidak tahu bagaimana menyelesaikan kalimat, karena saya kehilangan destruktor deterministik di Jawa, dan finallybukan pengganti untuk mereka. Kedua bahasa itu pada dasarnya berbeda.
DevSolar
25

Saya telah berdebat apakah perlu repot untuk mengirim jawaban lain ketika Anda sudah memiliki nomor yang mencapai kesimpulan yang tampaknya sepenuhnya masuk akal: bahwa ide Anda pada dasarnya adalah bencana yang menunggu untuk terjadi. Saya pikir, bagaimanapun, mereka telah gagal menunjukkan beberapa alasan yang sangat relevan di balik kesimpulan itu.

Perbedaan antara Java dan C ++ berjalan jauh lebih dalam daripada detail yang menjadi fokus Anda.

Misalnya, Anda berbicara tentang pelarangan pewarisan berganda di C ++. Pertama, saya akan menunjukkan bahwa ini tidak ada gunanya. Java mendefinisikan "antarmuka" sebagai hal yang terpisah dari "kelas". Satu kelas hanya mewarisi dari satu kelas lain, tetapi dapat mengimplementasikan sejumlah antarmuka yang sewenang-wenang.

C ++ tidak memisahkan dua konsep seperti itu. C ++ analog terdekat menyediakan untuk mengimplementasikan antarmuka di Jawa yang diwarisi dari kelas lain. Dengan demikian, untuk menjaga keduanya tetap selaras dengan baik, Anda mungkin perlu menggunakan banyak pewarisan dalam C ++, tetapi Anda ingin membatasi beberapa kelas dasar dengan cara yang hampir sama dengan cara Java membatasi antarmuka dibandingkan dengan kelas (yaitu, pada dasarnya yang menentukan tanda tangan fungsi tetapi, setidaknya sebagian besar, bukan implementasi).

Itu hampir tidak menggores permukaan perbedaan nyata antara keduanya. Pada kenyataannya, di mana kode Java cenderung mendefinisikan antarmuka, dan kelas yang mengimplementasikan antarmuka tersebut, kode C ++ jauh lebih mungkin untuk mendefinisikan beberapa templat yang akan bekerja dengan kelas apa pun yang memenuhi persyaratannya (bukan hanya yang didefinisikan secara khusus untuk mengimplementasikan antarmuka tersebut) (s) itu menentukan).

Jika Anda benar-benar ingin kode yang pada dasarnya "Java menggunakan sintaks C ++", Anda hampir pasti harus melarang apa pun dan segala sesuatu yang mirip dengan yang terakhir sekalipun. Anda harus membatasi penggunaan template untuk level "kontainer T" yang didukung oleh generik Java. Sayangnya, melakukan itu akan menghasilkan kode C ++ yang berantakan sehingga tidak ada yang bisa mempertahankannya seperti yang ada sekarang, belum lagi kemungkinan jangka panjang menerjemahkannya ke beberapa bahasa pemrograman lain.

Jika Anda benar-benar menginginkan kode yang dapat dikonversi ke bahasa lain di masa mendatang, berusahalah untuk membuatnya sebersih dan semudah mungkin dibaca. Yang ideal adalah menulis pseudo-code dan masih menjalankannya. C ++ modern yang ditulis dengan baik mendekati yang ideal jauh lebih dekat daripada subset yang Anda sarankan. Tidak masalah bagaimana Anda menulisnya, jika Anda pernah menerjemahkan ke Java, Anda harus benar-benar menerjemahkan kode, bukan hanya sintaks dari pernyataan individual.

Jerry Coffin
sumber
Banyak fitur C ++ dapat digunakan dalam beberapa cara yang memetakan dengan baik ke konsep Java, dan cara lain yang tidak. Beberapa bagian dari program akan memerlukan sesuatu di luar bagian fungsi bahasa yang tumpang tindih, dan mencoba untuk menulis bagian seperti "Java using C ++ syntax" akan menghasilkan kekacauan yang mengerikan. Di sisi lain, banyak bagian lain dari kode mungkin memerlukan apa pun di luar bagian yang dibagikan, dan mencoba untuk tetap di dalam bagian yang dibagikan untuk bagian-bagian dari kode di mana tidak ada alasan kuat untuk keluar mungkin dapat membantu.
supercat
Agaknya di mana Anda mengatakan "mungkin perlu", Anda benar-benar berarti: "mungkin tidak perlu"? Dengan asumsi demikian, maka saya cenderung setuju.
Jerry Coffin
Ya. Jika menjadi perlu untuk mendukung platform yang mendukung Java tetapi bukan C ++, bagian dari kode hampir pasti harus ditulis ulang dari awal dan tidak masalah apakah bagian-bagian itu telah ditulis menggunakan beberapa teknik yang ramah Java, karena mereka ' akan tetap ditulis ulang. Namun dimungkinkan untuk menulis bagian lain, dengan cara yang memungkinkan mereka untuk dimigrasi tanpa penulisan ulang penuh, dan dalam beberapa kasus biaya tambahan yang diperlukan untuk melakukannya mungkin minimal.
supercat
4
@supercat: OTOH, mengingat jumlah platform yang mendukung Java tetapi tidak C ++, ini menurut saya hampir seluruhnya merupakan solusi dalam mencari masalah.
Jerry Coffin
Untuk sementara, dukungan browser untuk applet Java lebih baik daripada untuk applet C ++. Namun, dukungan browser untuk JavsScript (tidak ada hubungannya dengan Java) telah cukup membaik sehingga pada dasarnya diambil dari keduanya.
supercat
11

Jika Anda akan menulis kode dalam bahasa X, luangkan waktu untuk mempelajari bahasa dengan benar dan gunakan semua fitur yang ditawarkan untuk membantu Anda memecahkan masalah. Hal-hal buruk terjadi ketika Anda mencoba melakukan terjemahan "kata demi kata" dari satu bahasa ke bahasa lain, baik itu Bahasa Jepang ke Bahasa Inggris atau Java ke C ++. Jauh lebih baik untuk memulai dengan pemahaman yang baik tentang masalah dan mengekspresikan solusi dengan cara yang paling alami untuk bahasa yang digunakan.

Bertahun-tahun yang lalu saya melihat program C yang tidak memiliki lekukan dan setiap pernyataan dimulai pada kolom 7, karena pembuat kode adalah seorang programmer Fortran yang kebetulan menggunakan C. Programmer Fortran lain merasa gugup tentang hal-hal baru yang disebut pointer. Saya tidak tega menyebutkan pointer ke pointer, saya pikir mereka akan pingsan di tempat.

Bayangkan mempekerjakan seseorang untuk mempertahankan kode ini di masa depan. Jika kode C ++ bagus, Anda dapat menyewa pengembang C ++ yang kompeten dan mereka harus dapat menemukan jalan keluarnya. Jika "Java dalam C ++", maka pengembang C ++ maupun Java tidak akan mudah memahami kode.

Tom Penny
sumber
7

Semua alasan Anda dapat dibantah:

Jika Java tidak menyediakan fitur yang dimiliki C ++, itu berarti fitur tersebut tidak bagus, jadi kami harus mencegah menggunakannya.

Itu tidak berarti fitur tersebut tidak baik (tidak ada fitur yang buruk). Ini hanya berarti bahwa fitur tersebut sering disalahgunakan (atau tidak mungkin diterapkan karena konsep dasar, seperti penunjuk langsung vs pengumpulan sampah). Java menurut definisi ditujukan untuk menjadi lebih mudah dan lebih ramah-programmer, karena itu penghapusan fitur-fitur yang terbukti mudah disalahgunakan.

Kode C ++ dengan fitur khusus C ++ (mis: fungsi teman, pewarisan berganda) hanya dapat dipertahankan atau ditinjau oleh programmer C ++, tetapi jika kita hanya menulis C ++ seperti Java (tanpa fitur khusus bahasa C ++), kode tersebut dapat dipertahankan atau ditinjau oleh keduanya Pemrogram C ++ dan Java.

Oh, mungkinkah itu? Mari kita lihat kode C ++ yang paling sederhana:

int len = mystring->size();

Ups, tidak ada fitur "khusus bahasa" yang digunakan, namun itu sudah bisa dipastikan oleh pengembang Java! Karena di Jawa Anda dereferensi dengan "." sementara di sini "->.

Anda mungkin akan diminta untuk mengonversi kode ke Java suatu hari nanti

Atau C #. Atau Haskell. Atau Python. Atau Ruby. Atau COBOL (ya, Anda bisa!). Bagaimana Anda bisa tahu masa depan?

Kode tanpa fitur spesifik C ++ biasanya lebih mudah dikelola.

Kebalikannya. Setiap fitur diperkenalkan untuk membuat pemrograman lebih mudah sehingga lebih dapat dipelihara. Misalnya: ambil program yang beroperasi di atas pelampung. Sekarang tingkatkan untuk menangani angka kompleks. Operator kelebihan muatan untuk menyelamatkan!

Setiap fitur khusus bahasa C ++ (mis: multiple inheritance) harus memiliki alternatif untuk diimplementasikan di Java. Jika tidak, itu berarti pola desain atau arsitektur kode bermasalah.

Tetapi Java TIDAK memiliki banyak warisan! Ini disebut "antarmuka". Implementasi Java adalah solusi yang bermasalah untuk menghindari berlian yang ditakuti yang disebabkan oleh segala sesuatu yang berasal dari Object. Itu dilakukan dengan memperkenalkan interfacetujuan satu-satunya adalah menjadi sesuatu yang tidak berasal Object. C ++ tidak pernah memiliki masalah ini - tidak ada dasar bersama wajib sehingga setiap kelas dapat berfungsi sebagai antarmuka tanpa berlian yang ditakuti.

Catatan: Java baru-baru ini diperkenalkan ... metode konkret dalam antarmuka. Menambahkan fitur C ++ selalu harus menyelesaikan masalah yang tidak pernah ada.

Anda juga hanya menyebutkan sedikit "hal-hal yang dimiliki C ++ tetapi Java tidak". Salah satu perbedaan terbesar antara C ++ dan Java adalah kontrol atas tata letak memori. Anda dapat membuat array pointer ke objek (seperti di Jawa) ATAU Anda dapat membuat blok memori yang berdekatan. Sekarang, jika saya khawatir tentang fitur C ++ yang dapat menyesatkan Java devs, sesuatu yang tersembunyi dan halus seperti yang akan peringkat di daftar saya jauh lebih tinggi daripada yang jelas dan dikenali pada hal-hal pandangan pertama seperti beberapa pewarisan atau operator kelebihan beban.

Intinya: Kode bersih adalah kode bersih. Java atau C ++ - perbedaan yang sama. Sederhana saja. Komplikasi yang tidak perlu adalah penyebab utama kode buruk.

Agent_L
sumber
Java menawarkan beberapa fitur dan jaminan yang tidak dapat didukung dalam bahasa yang menawarkan semua fitur C ++. Bahasa tidak dapat, misalnya, memungkinkan pemuatan tipe dinamis dan jajaran lengkap Java yang mempertahankan identitas sambil menawarkan bentuk umum dari beragam pewarisan yang termasuk dalam C ++.
supercat
@supercat Saya tidak mengerti mengapa Anda mengatakan ini di sini. Pertanyaannya bukan tentang fitur Java yang tidak dapat direproduksi dalam C ++, ini tentang fitur C ++ yang dibuang oleh Java.
Agent_L
Maksud saya adalah bahwa beberapa fitur di Java tidak termasuk dalam C ++, melainkan bahwa beberapa fitur Java pada dasarnya tidak kompatibel dengan fitur-fitur lain yang termasuk dalam C ++, sehingga tidak ada bahasa yang dapat memiliki tipe yang mendukung keduanya (bahasa seperti C ++ / CLI memiliki tipe yang mendukung fitur C ++ dan tipe yang mendukung fitur Java-ish, tetapi mereka secara efektif mendiami alam semesta yang terpisah dengan interoperabilitas terbatas).
supercat
6

Tidak, Anda harus umumnya tidak menulis C ++ seperti itu Java, dan Anda harus pasti tidak menghilangkan C ++ fitur bahasa yang tidak hadir di Jawa.

Untuk satu hal, Java adalah sampah yang dikumpulkan, dan karenanya tidak memiliki kata kunci C ++ "delete" yang setara. Oke, jadi Anda menerapkan program tanpa menghapus, karena menurut aturan Anda, itu tidak diizinkan.

Selamat, Anda sekarang mengalami kebocoran memori;). Itu juga tidak teoretis - saya telah melihat situasi yang tepat ini terjadi dalam permainan sumber terbuka.

Demikian pula, Java tidak memiliki apa pun seperti pointer C ++, yang mengesampingkan banyak konvensi panggilan fungsi umum.

Ada beberapa fitur C ++ yang sebaiknya Anda hindari (lihat di bawah), tetapi "tidak berada di Jawa" bukan tes lakmus yang baik.


Pedoman yang lebih baik adalah sebagai berikut:

  1. Tulis kode yang sesuai dengan bahasa, lingkungan, dan alat Anda.
  2. Tulis kode yang dapat dimengerti tim Anda .
  3. Pastikan tim Anda kompeten dalam domain yang diberikan.

Butir (3) berarti bahwa Anda seharusnya tidak memiliki kode programmer Java dalam C ++ tanpa melatihnya dalam C ++. Ada beberapa perbedaan kecil tapi sangat penting yang mungkin tidak mereka pelajari jika mereka mencoba memperlakukannya seperti dialek Jawa yang aneh.

Butir (2) berarti bahwa, jika tim Anda secara khusus merasa tidak nyaman dengan pewarisan berganda (misalnya), dan jika ada solusi yang memadai yang tidak menggunakannya, maka mungkin yang terbaik adalah menggunakan solusi alternatif itu. Namun, ini tergantung pada tim Anda secara khusus. Di sisi lain, jika tim Anda lebih tidak nyaman dengan solusi alternatif itu daripada dengan pewarisan berganda, gunakan pewarisan berganda!


Terakhir, ADA fitur bahasa C ++ yang, bisa dibilang, harus dihindari. Jika Anda ingin tahu apa ini, tanyakan programmer C ++ , daripada programmer dari bahasa yang berbeda. Beberapa contoh untuk memulai adalah pointer aritmatika (tidak ada konsensus universal) dan goto.

Ethan Kaminski
sumber
6

Sudah ada beberapa poin bagus dalam jawaban lain, tetapi saya ingin memberikan jawaban yang lebih lengkap, menjawab pertanyaan dan pernyataan Anda secara individual.


Jika Java tidak menyediakan fitur yang dimiliki C ++, itu berarti fitur tersebut tidak bagus, jadi kami harus mencegah menggunakannya.

Ini telah dijawab dengan cukup baik: Java bukan "bagian yang baik" dari C ++, juga tidak ada alasan untuk berpikir demikian.

Secara khusus, meskipun kelebihan masing-masing fitur C ++ individu masih bisa diperdebatkan, banyak fitur C ++ 11 / C ++ 14 yang bukan bagian dari Java tidak selalu dikecualikan karena desainer Java berpikir mereka adalah ide yang buruk. Sebagai contoh, sampai versi 8, Java tidak memiliki lambdas, tetapi mereka diperkenalkan ke C ++ dalam standar C ++ 11. Sebelum ke Java 8, asumsi Anda bahwa fitur C ++ yang hilang dari Jawa hilang karena desain karena "tidak baik" akan menyiratkan bahwa lambdas sebagai fitur bahasa "tidak baik" (yang membuat LISPers ketakutan di mana-mana, meskipun mereka mungkin cukup ngeri mendengar Anda ternyata benar - benar menyukai Java). Tapi sekarang para desainer Java telah menggunakan Stamp of Approval (TM) mereka di lambdas, jadi mereka sekarang A Good Thing.

Untuk menggali lebih dalam, bahkan di Jawa 8, lambdas-closure tidak sefleksibel lambda C ++ 14, tetapi ini mungkin disebabkan oleh keterbatasan arsitektur JVM daripada keputusan sadar bahwa pendekatan yang lebih fleksibel buruk dari suatu perspektif desain bahasa.


Kode C ++ dengan fitur khusus C ++ (mis: fungsi teman, pewarisan berganda) hanya dapat dipertahankan atau ditinjau oleh programmer C ++, tetapi jika kita hanya menulis C ++ seperti Java (tanpa fitur khusus bahasa C ++), kode tersebut dapat dipertahankan atau ditinjau oleh keduanya Pemrogram C ++ dan Java.

Ini adalah hal utama yang ingin saya tanggapi.

Secara umum, mungkin ada beberapa nilai untuk mendapatkan ulasan kode dari programmer yang tidak akrab dengan bahasa yang Anda gunakan. Mereka dapat memberi Anda umpan balik yang berharga tentang kejelasan fungsi / nama metode dan komentar Anda, dan (seperti yang disiratkan oleh pertanyaan Anda dengan benar) jika bahasanya mirip dengan satu atau lebih bahasa yang telah mereka ketahui, mereka mungkin dapat mengikuti alur program dasar dan berpotensi menangkap kesalahan logika.

Namun, ini bukan masalah bahwa ulasan semacam ini akan pernah "sebagus" atau "setara dengan" ulasan dari pengembang yang benar-benar tahu bahasa yang Anda gunakan. Pada dasarnya, ini karena membuat satu bahasa terlihat seperti yang lain biasanya akan menyembunyikan perbedaan yang halus, sementara membuat satu bahasa berperilaku seperti yang lain (terutama dalam kasus C ++ dan Java) mungkin tidak idiomatis untuk bahasa dan / atau mungkin masih terlalu membingungkan untuk pengulas.

Pertama, mari kita pikirkan apa artinya membuat C ++ "mirip" Java. Sebagai kasus sederhana, Anda dapat menggunakan newuntuk membuat instance objek, seperti di Jawa:

Foo foo = new Foo();

Tetapi objek yang dipakai dengan cara ini menggunakan ->alih-alih .memanggil metode, jadi jika Anda ingin panggilan metode terlihat seperti Java, Anda harus menulis:

Foo& foo = *new Foo();

Tetapi ini tidak idiomatis; khususnya, memori kemudian harus dibersihkan menggunakan delete &foo, yang beberapa pengembang C ++ berpengalaman mungkin bahkan tidak sadari adalah kode hukum . Either way, ada yang lucu simbol non-Jawa-seperti ditaburi seluruh, jadi kita tidak bisa cukup membuat bahasa "terlihat seperti" Java. (Anda bisa dihilangkan *newdengan menggunakan #define New *new, atau, lebih buruk,, #define new *newtetapi kemudian Anda hanya meminta rekan pengembang untuk membenci Anda.) Dan, seperti yang disebutkan di atas, deletetidak ada di Jawa, jadi dalam hal apa pun (seperti disebutkan dalam jawaban lain ) Anda tidak dapat benar - benar membuat penggunaan objek "terlihat" seperti di Jawa tanpa kebocoran memori.

Tapi C ++ modern termasuk pointer berbagi cerdas, yang berperilaku banyak seperti referensi variabel yang dikelola memori Java. Jadi di mana pun di Jawa yang bisa Anda tulis Foo foo = new Foo();, Anda bisa menulis:

std::shared_ptr<Foo> foo = std::make_shared<Foo>();

Sekarang Anda menggunakan fitur bahasa yang sebenarnya sangat mirip dengan Java di bawah tenda. Tetapi tiba-tiba Anda memiliki banyak hal untuk dijelaskan kepada pengulas non-C ++: shared_ptrbarang apa ini ? Apa "gotcha" rumit yang rumit itu make_shared? (Menggunakan forward-forwarding, yang memiliki beberapa kasus kegagalan dan dapat menyebabkan konstruktor "salah" dipanggil.) Mengapa metode perlu dipanggil dengan ->, tetapi menggunakan .dengan beberapa metode diizinkan oleh kompiler? ( shared_ptrmemiliki metode sendiri.) Jika metode itu Foo::reset(void)ada, pengembang yang tidak waspada mungkin mencoba memanggilnya foo.reset(), yang (jika hanya ada satu pointer bersama yang menunjuk ke instance Fooketika panggilan terjadi) akan menghapus memori yang mendasari dan membatalkan foo, dan Pengembang Java sepertinya tidak akan mengalami masalah ini.

Selain itu, C ++ memiliki banyak dari perangkap yang spesifik dengan bahasa. Seperti yang bisa saya katakan, sebagian besar pengembang C ++ belajar untuk menangani perangkap ini dengan secara bertahap mengembangkan idiom mereka sendiri untuk praktik C ++ yang "aman", yang seringkali agak unik bagi mereka atau tim pengembangan mereka (lihat misalnya jawaban yang ada yang menyebutkan Google praktik pengkodean dan komentar di atasnya mengatakan bahwa "veteran C ++ berpengalaman biasanya menolak pedoman pengkodean Google"). Semua klaim bahwa bahasa itu mungkin terlalu rumit, tampaknya (dalam pengalaman saya, setidaknya), biasanya bertemu dengan beberapa variasi "yah, berhenti menggunakannya salah." Saya menyadari ini adalah pandangan yang sangat negatif dari C ++ masyarakat, dan tentu ada pengembang yang berpengalaman lebih bersedia untuk membantu bahasa-peserta didik, tapi ada tidak tampaknya menjadi pembelaan tertentu tentang misalnya perilaku yang tidak terdefinisi (lihat misalnya banyak diskusi di tautan 'perangkap' saya di atas).

Pengembang Java tidak akan sangat membantu dalam menemukan dan memperbaiki perangkap ini melalui review kode.


Anda mungkin akan diminta untuk mengonversi kode ke Java suatu hari nanti.

Ini sepenuhnya valid - patut dipuji, bahkan - untuk mencoba memperhitungkan apa yang mungkin terjadi pada kode Anda di masa depan saat Anda dalam tahap desain.

Tapi, pertama, pertimbangan khusus ini tampak seperti kemungkinan jarak jauh: kode biasanya digunakan kembali sebagaimana mestinya (misalnya Anda bisa menyambungkan sebagian atau semua kode C ++ yang berfungsi ke beberapa perangkat lunak Java masa depan menggunakan antarmuka JNI) atau ditulis ulang seluruhnya agak daripada langsung secara manual "ditranskrip".

Dan, kedua, Anda kemudian berkata,

Setiap fitur khusus bahasa C ++ (mis: multiple inheritance) harus memiliki alternatif untuk diimplementasikan di Java ....

Ini pada dasarnya membatalkan titik "convert to Java" Anda. Jika perangkat lunak ditulis dalam C ++ idiomatik dan kemudian dikonversi ke Java idiomatik, tidak ada alasan untuk berharap bahwa konversi ini akan (atau bisa!) Dilakukan dengan menerapkan pemetaan satu-ke-satu yang tepat dari fitur C ++ ke fitur Java.


Kode tanpa fitur spesifik C ++ biasanya lebih mudah dikelola.

Tidak jelas apa yang Anda maksud di sini, tapi saya sebenarnya agak setuju dengan bagian ini: kecuali Anda sangat berhati-hati, dan bahkan ketika Anda berhati-hati, fitur C ++ dapat menyebabkan masalah pemeliharaan. The C ++ FQA Lite (website kritis terhadap bahasa dan pemeluknya dari seseorang yang setidaknya tampaknya benar-benar mengerti dengan cukup baik) menyatakan bahwa

... 80% pengembang mengerti paling banyak 20% bahasa. Ini bukan 20% sama untuk orang yang berbeda, jadi jangan mengandalkan mereka untuk memahami kode masing-masing.

TOLONG DICATAT: Jika Anda seorang penggemar C ++ dan Anda sampai pada titik ini dalam jawaban saya dan merasa cenderung untuk melompat ke komentar untuk berpendapat bahwa penulis FQA tidak benar-benar memahami C ++ atau tidak jujur ​​dalam sebagian besar argumennya , perhatikan bahwa (1) tepat dua kalimat setelah saya mengutipnya, saya mengakui bahwa FQA adalah sumber yang sangat bias, dan (2) tidak terlalu penting untuk apa yang saya coba katakan apakah penulis FQA memahami C ++ atau tidak. , dan saya tidak mencoba untuk mem-bash C ++, dan Anda harus membaca sisa postingan tanpa berasumsi bahwa saya anti-C ++ hanya karena saya telah mengutip FQA. Akhir catatan.

Demikian pula, Linus Torvalds membenci C ++ karena alasan ini (peringatan: tautan melibatkan banyak sumpah, dalam gaya Linus yang benar-benar terkenal).

Jelas, ini sangat bias mengambil masalah ini, tetapi bahkan pendukung C ++ sering mengatakan bahwa Anda tidak boleh menggunakan keseluruhan set fitur bahasa (sekali lagi, lihat pedoman pengkodean Google; juga, Bjarne Stroustrup, pencipta C ++ , telah secara terbuka menyatakan, "Di dalam C ++, ada bahasa yang jauh lebih kecil dan lebih bersih yang berjuang untuk keluar").

Jadi saya pikir ada beberapa manfaat dengan gagasan bahwa fitur C ++ mungkin terlalu mudah untuk disalahgunakan, terutama jika Anda berasal dari latar belakang Java. Selain itu, ada baiknya untuk meringankan masalah ini dengan membatasi diri Anda ke beberapa bagian dari bahasa.

Namun, memutuskan subset mana yang akan digunakan berdasarkan bahasa yang berbeda tidak tampak seperti pendekatan yang tepat, kecuali jika "bahasa yang berbeda" adalah C, karena memang ada subset seperti-C dari bahasa C ++. (Linus menyebut ini dalam kata-katanya di atas, dan Scott Meyers bahkan menyebut subset ini sebagai "sub-bahasa.") Paradigma run-time Java (pengumpulan sampah, menjalankan pada VM) sangat berbeda dengan C ++ sehingga tidak jelas ada pelajaran berguna untuk menggambar tentang penggunaan C ++ dari itu, dan seperti yang disebutkan di atas, mencoba menggambar pelajaran tentang C ++ langsung dari Jawa dapat menyebabkan kode yang sangat non-idiomatik.

Alih-alih, cobalah untuk mendefinisikan "bagian yang dapat diterima" dari bahasa tersebut pada pemahaman tentang bagaimana bahasa tersebut dapat digunakan secara idiomatis. Jika Anda menginginkan subset yang cukup ketat yang masih memanfaatkan banyak fitur C ++ di luar apa yang ditawarkan C, pedoman Google Coding yang disebutkan di atas mungkin merupakan tempat yang baik untuk memulai. Tentu, Anda akan mendapatkan pengembang yang mengatakan bahwa "tidak ada argumen rasional" untuk beberapa batasan Google , tetapi kecuali jika Anda ingin mempekerjakan Alexandrescu jauh dari pekerjaannya pada bahasa D (yang dengan sendirinya harus memberi tahu Anda sesuatu), itu mungkin baik-baik saja. Ini tentu lebih baik daripada mencoba mengubah C ++ menjadi Java.

Titik awal lain yang baik untuk seperangkat pedoman kode adalah C + + Core Guidelines , yang sedang dalam proses oleh Bjarne Stroustrup dan Herb Sutter.

Satu-satunya cara lain untuk mengatasi kekurangan C ++ adalah memilih bahasa yang berbeda. Sepertinya Anda menyukai Java, dan Anda pikir ada kemungkinan proyek ini mungkin akan dikonversi menjadi Java pada akhirnya. Seperti disebutkan dalam jawaban lain, Anda bisa ... mulai dengan Java.

Ada dua alasan mengapa Anda mungkin benar-benar perlu menggunakan sesuatu selain Java:

  1. Anda benar-benar membutuhkan kinerja run-time. Dalam hal ini, memperlakukan C ++ seperti Java mungkin tidak akan benar-benar membantu Anda, karena teknik mirip Java seperti pointer-bersama menurunkan kinerja run-time Anda.
  2. Anda memerlukan perangkat lunak untuk bekerja pada platform yang tidak jelas yang belum mendukung JVM. Dalam hal ini, Anda mungkin terjebak dengan bahasa yang memiliki antarmuka GCC atau Dentang. C dan C ++ adalah kandidat yang jelas, tetapi Anda juga bisa melihat sesuatu seperti Rust. (Sumbat cepat: Saya belum pernah menggunakan Rust secara luas, tetapi terlihat keren dan saya ingin segera mengerjakan proyek Rust utama, dan saya pikir semua orang yang mempertimbangkan memulai proyek C ++ harus mempertimbangkan Rust sebagai alternatif.)

Setiap fitur khusus bahasa C ++ (mis: multiple inheritance) harus memiliki alternatif untuk diimplementasikan di Java. Jika tidak, itu berarti pola desain atau arsitektur kode bermasalah.

Saya sudah membahas ini agak, tapi saya sengaja mengabaikan kalimat kedua Anda.

Saya tidak yakin bahwa sesuatu seperti constexpr, yang tidak masuk akal dalam bahasa JIT sebagian seperti Java, merupakan indikasi arsitektur yang tidak valid. Saya lebih terbuka pada gagasan bahwa penggunaan berlebihan meta-programming template mungkin lebih banyak masalah daripada nilainya, terutama sekarang yang constexprada untuk melakukan evaluasi fungsi waktu kompilasi, tetapi jelas dari kasus constexprbahwa tidak ada cacat desain jika Anda sedang menggunakannya: Anda hanya memastikan bahwa beberapa perhitungan terjadi bahkan sebelum menjalankan kode, yang merupakan peningkatan kinerja yang luar biasa (lihat misalnya entri ini untuk masalah n-tubuh The Benchmark Game , yang mengungguli setiap entri lainnya kecuali yang lain ditulis dalam C ++,

Kyle Strand
sumber
5
Penulis FQA pasti termasuk dalam kelompok "mengerti paling banyak 20% dari bahasa". Cukup banyak jawaban di sana yang secara faktual salah, dan lebih banyak lagi yang tidak tepat, diilustrasikan dengan stroberi setelah stroberi.
Ben Voigt
2
Banyak (hampir semua?) Keluhan dalam C ++ FQA adalah omong kosong. Bahasa modern sangat besar. C ++ agak kecil dibandingkan dengan Python, Ruby, Perl, dan ya, Java. Ajukan pertanyaan dasar dalam bahasa-bahasa tersebut di stackoverflow dan jawaban pertama hampir pasti di sepanjang baris "Mengapa Anda tidak import SomeVeryBasicPackagedan hanya melakukan ini ?" Ajukan pertanyaan lanjutan dan jawaban pertama hampir pasti di sepanjang baris "Mengapa kamu tidak import SomeMagicalPackagedan hanya melakukan itu ?"
David Hammen
1
@ Davidvidam Saya pikir perpecahan 80/20 mengacu pada fitur bahasa inti, bukan hanya komponen perpustakaan standar, dalam hal ini bahasa yang Anda sebutkan, dengan kemungkinan pengecualian Perl, benar-benar tampaknya tidak sebesar dan rumit seperti C ++. Bagaimanapun, itu adalah bagian yang sangat kecil dari jawaban saya, dan saya mengakui bahwa itu adalah sumber yang bias.
Kyle Strand
1
VM / bahasa yang dikelola jelas jauh lebih rumit di bawah permukaan, tapi maksud saya rumit dari perspektif penggunaan.
Kyle Strand
1
Saya tidak tahu apakah teori Anda benar, meskipun dalam kasus saya, saya pasti belajar C ++ dan C secara terpisah, dan kelas C ++ saya benar-benar sangat menyeluruh. Tapi kutipan lengkap tentang 20/80 perpecahan adalah bahwa setiap programmer tahu yang berbeda 20% dari bahasa, yang tidak akan dijelaskan oleh kebanyakan programmer yang diajarkan C bagian dari bahasa secara mandiri. Ngomong-ngomong, jika Anda ingin menjelaskan secara terperinci bagaimana C ++ memungkinkan pemrograman yang lebih kuat (saya klaim sudah pernah saya lihat tetapi tidak mengerti), kami mungkin sebaiknya melakukannya di ruang obrolan atau sesuatu daripada di komentar di sini .
Kyle Strand
5

Misalkan saya terbatas untuk menggunakan C ++ oleh lingkungan dalam proyek. Apakah baik untuk mencegah penggunaan beberapa fitur bahasa yang dimiliki C ++ tetapi Java tidak memiliki (mis: multiple inheritance, operator overriding)?

Tidak.

Jika "oleh lingkungan proyek" Anda terbatas untuk menggunakan C ++, maka ada sedikit, jika ada, titik bahkan berpikir tentang teknologi lain, tidak peduli berapa banyak Anda secara pribadi lebih suka / berharap untuk menggunakan / menginjili itu.
Apakah "Teknologi X" atau "Y" mendukung fitur yang diberikan tidak ada kaitannya dengan cara Anda membangun aplikasi C ++.
Ini adalah aplikasi C ++, mungkin untuk beberapa "Alasan Bagus" (sekarang atau di masa lalu) jadi Anda harus menuliskannya sebagai aplikasi C ++, menggunakan apa pun yang disediakan "kotak alat" itu.

Jika dan ketika ada Persyaratan untuk port aplikasi ke beberapa teknologi lain maka (dan hanya kemudian) Anda dapat mempertimbangkan fitur pada platform lain. Tidak ada gunanya "memotong hidung Anda untuk memuntahkan wajah Anda" jika ada kemungkinan sesuatu akan terjadi. Ingat, bagaimanapun, bahwa penulisan ulang grosir adalah operasi yang mahal dan berisiko yang tidak mungkin dilakukan Manajemen tanpa alasan yang sangat baik untuk melakukannya.

Ada debat yang serupa ("menggunakan atau tidak menggunakan") beberapa tahun yang lalu di Dunia Visual Basic [.Net], di mana seseorang memiliki ide cemerlang bahwa Anda harus menulis aplikasi Visual Basic tanpa menggunakan salah satu [bahasa inti] fungsionalitas yang disediakan oleh namespace Microsoft.VisualBasic. Ini seperti mencoba menulis aplikasi C ++ tanpa std :: namespace; Oke, itu mungkin, tetapi mengapa di dunia ini siapa pun yang waras mau repot-repot melakukannya?

Phill W.
sumber
1
Ke poin terakhir Anda tentang Visual Basic: Masalah dengan pustaka vendor tersebut adalah bahwa mereka adalah milik. Menggunakannya berarti merantai diri sendiri ke vendor itu. Vendor akan menyukai Anda dirantai, tetapi Anda tidak akan dalam jangka panjang: Anda tidak dapat menggunakan perangkat lunak vendor lain tanpa menulis ulang segala sesuatu yang bergantung pada fungsionalitas spesifik vendor. Semakin banyak Anda menggunakan fungsionalitas khusus vendor, semakin tinggi biaya perubahan vendor, memberdayakan vendor Anda untuk memaksakan perubahan pada Anda. Itulah salah satu alasan mengapa perangkat lunak bebas (seperti dalam kebebasan!) Adalah masalah besar.
cmaster
The Microsoft.VisualBasicnamespace hal adalah sedikit peregangan. Sudah bertahun-tahun sejak saya terakhir menggunakannya, tetapi setidaknya pada awalnya sebagian besar bertujuan untuk kompatibilitas dengan VB6 (dan / atau untuk membuat programmer VB6 merasa "di rumah"); sebagian besar menyediakan fungsionalitas yang sudah tersedia di sisa kerangka kerja dalam bentuk yang lebih modern (dan lebih terintegrasi), sehingga dalam proyek-proyek baru jarang masuk akal untuk menggunakannya. Sebaliknya, std::namespace adalah tempat seluruh pustaka standar berada - menghindarinya sama seperti menghindari seluruh BCL di .NET.
Matteo Italia
2

Semua jawaban saat ini mengatakan ini adalah hal yang buruk untuk dilakukan, karena Anda harus mengambil keuntungan dari bahasa yang Anda gunakan dan juga menjelaskan mengapa fitur C ++ tidak “buruk” hanya karena tidak ada di jave. Saya akan menjawab ini dari sudut yang berbeda.

Ini adalah satu hal untuk menghindari fitur C ++ yang kompleks seperti multiple inheritance, operator overloading dan mendefinisikan template Anda sendiri.

Tetapi setiap masalah yang melakukan lebih dari tugas paling sederhana:

  • mengalokasikan memori,
  • menghubungkan uang itu dengan poin
  • jadi bangun struktur data
  • kemudian memungkinkan memori untuk digunakan kembali ketika aman untuk melakukannya

Tidak ada subset umum Java dan C ++ yang memungkinkan hal di atas, oleh karena itu apa yang Anda minta tidak mungkin dilakukan. (Jika Anda bertanya tentang Jawa dan C #, Anda akan memiliki peluang yang jauh lebih baik, karena keduanya menggunakan pengumpul sampah.)

Namun Anda dapat meminta agar kode tersebut ditulis agar pengembang Java dapat memahami apa yang dilakukannya (tetapi bukan "bagaimana" yang terperinci) dan ini akan masuk akal.

Anda juga bisa mendesain bahasa Anda sendiri yang Anda implementasikan dalam C ++ dan JAVA .....

Ian
sumber
0

Tidak seorang pun boleh menulis kode apa pun yang tidak dimengerti oleh pembuat kode lain. Jika menurut Anda kunci bahasa adalah masalah, tunggu hingga Anda memiliki kunci pengembang. Yang satu lebih cenderung menyandera Anda daripada yang lain.

Tidak ada alasan teknis. Apa yang Anda buat adalah skenario di mana bahasa digunakan untuk alasan apa pun, tetapi banyak pengembang saat ini dan mungkin di masa depan tidak benar-benar memahaminya.

Dugaan saya adalah, pengembang Java cenderung menulis C ++ seperti cara mereka menulis di Jawa, jadi mengapa membuatnya menjadi aturan. Anda dapat menemukan beberapa fitur khusus C ++ yang lebih mudah untuk diimplementasikan dan dipelihara dengan sedikit instruksi C + / dokumentasi untuk pengembang Java Anda daripada bola besar kekacauan Java mereka kalau tidak akan terjebak dengan.

Ini telah menjadi argumen tentang masalah programmer BASIC pindah ke bahasa berorientasi objek. Bukannya mereka menerapkan praktik OOP dengan merugikan para dev baru yang tidak memahaminya, tetapi mereka tidak menerapkannya sama sekali. Jika ya, biasanya mereka salah. Jika sesuatu dilakukan dengan buruk, itu perlu dihapus terlepas dari alasannya.

Selain seseorang yang hanya menyalin dan menempelkan kode secara membabi buta, mereka akan melakukannya di banyak bidang yang tidak mereka mengerti.

JeffO
sumber