Başka cevaplarda zaten bazı iyi noktalar var, ancak sorularınızı ve ifadelerinizi bireysel olarak ele alarak daha eksiksiz bir cevap vermek istiyorum.
Java, C ++ 'a sahip bir özellik sağlamıyorsa, bu özelliğin iyi olmadığı anlamına gelir, bu yüzden onu kullanmayı önlemeliyiz.
Bu oldukça iyi cevaplandı: Java, C ++ 'ın "iyi kısımları" değil, böyle düşünmenin de bir nedeni yok.
Özellikle, her bir C ++ özelliğinin esası tartışılabilir olsa da, Java tasarımcılarının kötü bir fikir olduğunu düşündüğü için, C ++ 11 / C ++ 14'ün Java'nın bir parçası olmayan özelliklerinin birçoğunun dışlanması gerekmez. Örnek olarak, sürüm 8'e kadar, Java'da lambdalar yoktu, ancak C ++ 11 standardında C ++ 'a tanıtıldılar. Java 8’den önce, Java’da eksik olan C ++ özelliklerinin tasarım açısından eksik olduğunu varsayıyorsunuz, çünkü "iyi değiller" dilin bir özelliği olan lambdaların "iyi değil" (LISPers’in dehşetine rağmen) muhtemelen görünüşe göre Java'yı sevdiğini duyacak kadar dehşete düşmüş ). Fakat şimdi Java tasarımcıları Onay Damgasını (TM) lambdalara koymuşlar, bu yüzden şimdi A Good Thing.
Biraz daha derine inmek için, Java 8'de bile, kapanma gibi lambdalar C ++ 14'ün lambdaları kadar esnek değildir, ancak bunun nedeni , daha esnek bir yaklaşımın daha esnek olduğu konusunda bilinçli bir karardan ziyade JVM mimarisi sınırlamaları olabilir. dil tasarımı perspektifi.
C ++ özel özelliklerine sahip C ++ kodu (örneğin: arkadaş işlevleri, çoklu kalıtım) yalnızca C ++ programcıları tarafından sağlanabilir veya gözden geçirilebilir, ancak Java'yı sadece C ++ gibi yazarsak (C ++ dile özgü özellik olmadan), kod her ikisi tarafından da korunabilir veya gözden geçirilebilir. C ++ ve Java programcıları.
Cevap vermek istediğim en önemli şey bu.
Genel olarak, kullandığınız dile yakından aşina olmayan programcılardan kod incelemeleri almanın bir değeri olabilir. İşlev / yöntem adlarının ve yorumlarınızın netliği hakkında size değerli geri bildirimler verebilir ve (sorunuzun doğru bir şekilde belirttiği gibi) eğer dil bildikleri bir veya daha fazla dile benzerse, temel program akışını izleyebilirler. ve potansiyel olarak mantık hatalarını yakalar.
Ancak, öyle değil inceleme bu tür hiç "kadar iyi" olacağını durumda ya aslında kullandığınız dili bilen geliştiricilerin incelemesi "ne denk". Tek dil yapım çünkü Esasen, bu bakış başka benzeri bir dil yaparken genellikle ince farklılıklar gizler davranacaksan (özellikle C ++ ve Java durumunda) başka benzeri / dil için un-deyimsel ve olabilir veya hala çok kafa karıştırıcı olabilir yorumcular için.
Öncelikle, C ++ 'ın Java gibi görünmesini sağlamanın ne demek olacağını düşünelim. Basit bir örnek olarak, new
Java'da olduğu gibi nesneleri başlatmak için kullanabilirsiniz :
Foo foo = new Foo();
Ancak bu şekilde örneklenen nesneler yöntemleri çağırmak ->
yerine kullanır .
, bu nedenle yöntem çağrıları'nın Java gibi görünmesini istiyorsanız bunun yerine şunu yazmalısınız:
Foo& foo = *new Foo();
Fakat bu aptalca değildir; Özellikle, bellek daha sonra kullanılarak temizlenmelidir delete &foo
hangi bazı deneyimli C ++ Devs hatta yasal kodudur farkında olmayabilir . Her iki şekilde de, boyunca serpilir komik olmayan Java benzeri semboller vardır, bu yüzden olamaz oldukça dili Java "gibi bakmak" olun. ( *new
Kullanarak #define New *new
veya daha da kötüsü kullanarak ortadan kaldırabilirsiniz #define new *new
, ancak o zaman sadece geliştirici arkadaşlarınıza sizden nefret etmeleri için yalvarırsınız.) Ve yukarıda da belirtildiği gibi, delete
Java'da mevcut değil, yani (başka bir cevapta belirtildiği gibi) Gerçekten de hiçbir nesne kullanımının Java'da bellek sızıntısı olmadan yaptığı gibi görünmesini sağlayamazsınız.
Ancak modern C ++, Java'nın bellek tarafından yönetilen değişken referansları gibi davranan akıllı paylaşılan işaretçiler içerir. Böylece Java’nın her yerinde yazabildiğiniz Foo foo = new Foo();
, bunun yerine yazabilirsiniz:
std::shared_ptr<Foo> foo = std::make_shared<Foo>();
Şimdi, Java'nın kaputun altına çok benzeyen bir dil özelliği kullanıyorsunuz. Fakat birdenbire C ++ yorumcularına açıklamak için çok şeyiniz var: bu shared_ptr
nedir? İnce zor "gotchas" make_shared
nedir? (Bazı başarısızlık durumları olan ve "yanlış" yapıcının çağrılmasına neden olan mükemmel iletme kullanır.) Yöntemlerin neden çağrılması gerekiyor ->
, ancak .
bazı yöntemlerle kullanılmasına derleyici tarafından izin veriliyor mu? ( shared_ptr
Kendi yöntemleri vardır.) Yöntemi ise Foo::reset(void)
var olan bir gafil geliştirici ile aramak deneyebilirsiniz foo.reset()
(bu örneğe tek paylaşılan işaretçi işaret varsa, hangi Foo
çağrı oluştuğunda) altta yatan hafızasını silmek ve geçersiz olacak foo
ve Java geliştiricileri bu sorunu yakalayamaz.
Üstelik C ++ sahip bir çok ait tuzaklar vardır spesifik için dilin. En iyi söyleyebileceğim gibi, çoğu C ++ geliştiricisi, genellikle kendilerine veya gelişim ekibine özgü olan "güvenli" C ++ uygulamaları için kendi deyimlerini yavaş yavaş geliştirerek bu tuzaklarla başa çıkmayı öğrenir (örneğin, Google kodlama uygulamaları ve bu konuda yaptığı açıklamada “Seasoned C ++ gazileri genellikle Google kodlama kurallarını reddetti” dedi. Dilin çok karmaşık olabileceğine dair tüm iddialar, görünüşe göre (en azından benim deneyimime göre), tipik olarak "iyi, yanlış kullanmayı bırakma" şeklinde bir değişiklikle karşılanıyor. Bu C ++ topluluğu son derece olumsuz bir görünümüdür gerçekleştirmek ve dil-öğrencilere yardım etmeye daha istekli deneyimli geliştiriciler kesinlikle var, ama orada does örneğin tanımsız davranış konusunda belirli bir savunmasızlık gibi görünüyor (örneğin yukarıdaki 'tuzaklar' bağlantımdaki tartışmanın çoğuna bakınız).
Java geliştiricileri bu tuzakları bulmak ve düzeltmek için kod incelemesiyle yardımcı olmayacaktır.
Kodu bir gün Java'ya dönüştürmeniz istenebilir.
Tasarım aşamasında iken gelecekte kodunuza ne olabileceğini göz önünde bulundurmaya çalışmak, hatta övgüye değer, tamamen geçerlidir.
Ancak, ilk olarak, bu özel değerlendirme uzak bir olasılık gibi gözüküyor: kod genellikle ya (örneğin çalışan C ++ kodunun bir kısmını ya da tamamını bir JNI arayüzü kullanarak gelecekteki bir Java yazılımına bağlayabilirsiniz) ya da tamamen yeniden yazılmış olabilir. doğrudan elle "kopyalanır".
Ve ikincisi, sonra söylersiniz ki
Her C ++ diline özgü özelliğin (örneğin: çoklu kalıtım) Java'da uygulanacak alternatifleri olması gerekir.
Bu aslında "Java'ya dönüştür" noktanızı iptal eder. Yazılım, idiomatik C ++ dilinde yazılır ve ardından idiomatik Java'ya dönüştürülürse, bu dönüşümün Java özelliklerine bire bir C ++ özellikleri eşlemesi uygulayarak (veya yapabileceğini) beklemenin bir nedeni yoktur.
C ++ 'a özgü özelliklere sahip olmayan kod genellikle daha fazla bakım gerektirebilir.
Burada ne demek istediğinizi açık değil, ama aslında bunun bir kısmına katılıyorum: çok dikkatli olmadığınız sürece ve dikkatli olsanız bile, C ++ özellikleri bakım sorunlarına yol açabilir. C ++ FQA Lite (dil ve en az aslında oldukça iyi anlamak görünmektedir birinden onun taraftarlarının kritik bir web sitesi) belirtiyor
... Geliştiricilerin% 80'i dilin en fazla% 20'sini anlıyor. Farklı insanlar için% 20 aynı değildir, bu nedenle birbirlerinin kodunu anlamak için onlara güvenmeyin.
LÜTFEN DİKKAT: Eğer bir C ++ hayranıysanız ve cevabımda bu noktaya varıyorsanız ve FQA'nın yazarının aslında C ++ 'ı anlamadığını ya da savlarının çoğunda anlamsız olduğunu iddia etmek için yorumlara düşme eğiliminde olduğunu düşünüyorsanız Not: (1) onu alıntı yaptıktan sonra tam olarak iki cümle FQA'nın çok taraflı bir kaynak olduğunu kabul ediyorum ve (2) FQA yazarının C ++ 'ı anlayıp anlamadığını söylemeye çalıştığım şey için gerçekten önemli değil. ve ben C ++ 'a basmaya çalışmıyorum ve FQA'dan alıntı yaptığım için anti-C ++ olduğumu varsaymadan yazının geri kalanını okumalısınız. Notun sonu.
Benzer şekilde, Linus Torvalds aslında bu sebepten dolayı C ++ 'dan nefret eder (uyarı: bağlantı gerçek rezil Linus tarzında çok fazla küfür içerir).
Açıkçası, bunlar konuyla ilgili çok önyargılıdır, ancak C ++ destekçileri bile, dil özellik kümesinin tamamını kullanmamanız gerektiğini söyler (bir kez daha, Google kodlama yönergelerine bakın; ayrıca, C ++ 'nın yaratıcısı Bjarne Stroustrup). , “C ++ 'ta çıkmak için daha küçük ve daha temiz bir dil var.
Bu nedenle, özellikle bir Java altyapısından geliyorsanız, C ++ özelliklerinin kötüye kullanımı çok kolay olabileceği fikrinin bazı yararları olduğunu düşünüyorum. Ayrıca, kendinizi bu dilin alt kümeleriyle sınırlayarak bu sorunları hafifletme fikrine değerdir.
Ancak, karar hangi farklı bir dilde göre kullanılacak alt kümesi yok değil "Farklı dil" C olmadıkça orada gerçekten C ++ dilinin bir C-benzeri alt kümesi olduğundan, doğru yaklaşım gibi görünüyor. (Linus bunu yukarıdaki rantında ifade eder ve Scott Meyers bile bu altküme "alt dil" olarak atıfta bulunur.) Java'nın çalışma zamanı paradigması (toplanan, VM'de çalışan) C ++ 'dan çok farklıdır. Açıkça C ++ kullanımı hakkında çizilecek faydalı dersler yoktur ve yukarıda belirtildiği gibi, doğrudan Java'dan C ++ hakkında ders çıkarmaya çalışmak, çok deyimsiz kodlara yol açabilir.
Bunun yerine, dilin deyimsel olarak nasıl kullanılabileceğini anlamak için dilin "kabul edilebilir alt kümesini" tanımlamaya çalışın. C ++ 'ın sunduğu özelliklerin çoğundan hala yararlanmaya devam eden oldukça kısıtlayıcı bir alt küme istiyorsanız, yukarıda belirtilen Google Kodlama kılavuzunun başlaması iyi bir yer olabilir. Elbette, Google’ın bazı kısıtlamaları için rasyonel bir tartışma olmadığını "söyleyen geliştiricilere sahip olacaksınız , ancak Alexandrescu’yu D diliyle ilgili çalışmalarından uzakta tutmak istemiyorsanız (ki bu size bir şey söylemeli). Muhtemelen tamam. C ++ 'ı Java'ya dönüştürmeye çalışmaktan kesinlikle daha iyi.
Bir dizi kod ilkesi için iyi bir başlangıç noktası , Bjarne Stroustrup ve Herb Sutter tarafından devam eden bir çalışma olan yeni C ++ Çekirdek İlkeleridir .
C ++ 'ın eksiklikleriyle başa çıkmanın tek yolu farklı bir dil seçmek. Java'ya benziyor gibi geliyor ve bu projenin sonunda Java'ya dönüştürülme olasılığı olduğunu düşünüyorsunuz. Başka bir cevapta belirtildiği gibi, sadece ... Java ile başlayabilirsiniz.
Java dışında başka bir şey kullanmanızın gerçekten gerekmesinin iki nedeni olabilir :
- Gerçekten çalışma zamanı performansına ihtiyacınız var. Bu durumda, C ++ 'ı Java gibi kullanmak muhtemelen size yardımcı olmaz, çünkü paylaşılan işaretçiler gibi Java benzeri teknikler çalışma zamanı performansınızı düşürür.
- Yazılımın henüz JVM'yi desteklemeyen karanlık bir platformda çalışması için ihtiyacınız var. Bu durumda, muhtemelen GCC veya Clang uçlarına sahip dillerle sıkışmışsınızdır. C ve C ++ açık adaylar, ancak Rust gibi bir şeye de bakabilirsiniz. (Hızlı fiş: Rust'i yoğun bir şekilde kullanmadım, ama harika görünüyor ve en kısa sürede büyük bir Rust projesinde çalışmak için çok istekliyim ve bence bir C ++ projesine başlamayı düşünen herkesin bir alternatif olarak düşünmesi gerektiğini düşünüyorum.)
Her C ++ diline özgü özelliğin (örneğin: çoklu kalıtım) Java'da uygulanması gereken alternatifleri olmalıdır. Olmazsa, bu tasarım deseni veya kod mimarisinin sorunlu olduğu anlamına gelir.
Bunu zaten bir şekilde çözdüm, ama ikinci cümlenizi bilerek bıraktım.
constexpr
Java gibi kısmen JIT dilinde anlam ifade etmeyen bir şeyin geçersiz bir mimarinin göstergesi olduğuna ikna olmadım . Onu özellikle şimdi, değerinden daha şablon meta-programlama aşırı kullanımının fazla sorun olabileceğini fikrine daha açığım constexpr
derleme zamanı fonksiyon değerlendirme yapmak için mevcut fakat durumunda da görüleceği üzere constexpr
hiçbir orada tasarım eğer kusur 'kullanmadan re: sadece bazı hesaplamalar bile müthiş bir performans artışı olduğu kod çalıştırmadan önce gerçekleşen sağlamak (örneğin bkz ediyoruz Benchmark Oyun n-beden problemi için bu girdiyi başka biri dışında diğer her girdiyi geride, C ++ ile yazılmış,