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:
- 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.
- 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.
- Anda mungkin akan diminta untuk mengonversi kode ke Java suatu hari nanti
- Kode tanpa fitur spesifik C ++ biasanya lebih mudah dikelola
- 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?
java
c++
code-quality
ggrr
sumber
sumber
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.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, modifikasia
juga akan mempengaruhi objek sebelumnya. Di C ++, Anda memiliki dua objek terpisah.Jawaban:
Tidak. Ini menyedihkan dan sangat salah arah.
sumber
operator<<( ostream &, T const & )
biasanya diimplementasikan melaluifriend
. Itulah masalah dengan pernyataan selimut tentang apa fitur bahasa yang baik dan apa yang buruk: Mereka adalah saran yang bagus, kecuali ketika mereka tidak ...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-alihobj == 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 sepertiif (myField == null)
di C ++, orang akan segera melihat Anda seorang pemula. Jika Anda menggunakanif (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
#define
s 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.sumber
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.if (myField == null)
sebagaiif (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.Saya akan menjawab pertanyaan Anda secara berurutan.
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.
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.
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.
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.
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.
sumber
Saya hanya akan menjawab alasan Anda:
sumber
delete
keduanya.delete
. Dari apa yang saya ingat, setidaknya dalam salah satu kasus itu, alokasi dinamis (new
) juga tidak diperlukan.make_shared
.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.
sumber
Object
cukup banyakvoid*
digunakan - Masih, yuck.finally
bukan pengganti untuk mereka. Kedua bahasa itu pada dasarnya berbeda.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.
sumber
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.
sumber
Semua alasan Anda dapat dibantah:
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.
Oh, mungkinkah itu? Mari kita lihat kode C ++ yang paling sederhana:
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 "->.
Atau C #. Atau Haskell. Atau Python. Atau Ruby. Atau COBOL (ya, Anda bisa!). Bagaimana Anda bisa tahu masa depan?
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!
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 memperkenalkaninterface
tujuan satu-satunya adalah menjadi sesuatu yang tidak berasalObject
. 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.
sumber
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:
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.
sumber
Sudah ada beberapa poin bagus dalam jawaban lain, tetapi saya ingin memberikan jawaban yang lebih lengkap, menjawab pertanyaan dan pernyataan Anda secara individual.
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.
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
new
untuk membuat instance objek, seperti di Jawa:Tetapi objek yang dipakai dengan cara ini menggunakan
->
alih-alih.
memanggil metode, jadi jika Anda ingin panggilan metode terlihat seperti Java, Anda harus menulis: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*new
dengan menggunakan#define New *new
, atau, lebih buruk,,#define new *new
tetapi kemudian Anda hanya meminta rekan pengembang untuk membenci Anda.) Dan, seperti yang disebutkan di atas,delete
tidak 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: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_ptr
barang apa ini ? Apa "gotcha" rumit yang rumit itumake_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_ptr
memiliki metode sendiri.) Jika metode ituFoo::reset(void)
ada, pengembang yang tidak waspada mungkin mencoba memanggilnyafoo.reset()
, yang (jika hanya ada satu pointer bersama yang menunjuk ke instanceFoo
ketika panggilan terjadi) akan menghapus memori yang mendasari dan membatalkanfoo
, 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.
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,
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.
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
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:
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 yangconstexpr
ada untuk melakukan evaluasi fungsi waktu kompilasi, tetapi jelas dari kasusconstexpr
bahwa 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 ++,sumber
import SomeVeryBasicPackage
dan hanya melakukan ini ?" Ajukan pertanyaan lanjutan dan jawaban pertama hampir pasti di sepanjang baris "Mengapa kamu tidakimport SomeMagicalPackage
dan hanya melakukan itu ?"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?
sumber
Microsoft.VisualBasic
namespace 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.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:
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 .....
sumber
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.
sumber