C ++ 'ın sahip olduğu fakat Java'nın sahip olmadığı dil özelliklerinden kaçınmalı mıyız?


110

Proje ortamındaki C ++ 'ı kullanmakla sınırlı olduğumu varsayalım. C ++ 'ta bulunan fakat Java'nın sahip olmadığı bazı dil özelliklerinin kullanılmasının engellenmesi iyi midir (örneğin: çoklu kalıtım, operatörün aşırı yüklenmesi)?

Bence nedenler:

  1. Java, C ++ 'dan daha yeni olduğundan, Java, C ++' nın sahip olduğu bir özelliği sağlamıyorsa, bu özelliğin iyi olmadığı anlamına gelir, bu yüzden kullanmaktan kaçınmalıyız.
  2. 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ı.
  3. Kodu bir gün Java'ya dönüştürmeniz istenebilir
  4. C ++ 'a özgü özelliklere sahip olmayan kod genellikle daha iyi korunur
  5. 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.

Bu doğru mu?


7
Önerilerinize bakarsanız bir kodlama standardı oluşturmaktan bahsediyorsunuz. Bir standart yaratıyor olmanız ve bir standardı takip etmeniz aslında sürdürülebilirliği artıracak şeydir.
Brandin

63
Java kodu aynı zamanda C ++ dilinde de bulunan özelliklerle de sınırlı olmalı mı? Öyleyse, örneğin Java volatile, özel paket sınıf üyelerine erişim, yansıma / iç gözlem, nihayet bloklar, işaretli istisnalar vb. Kullanmayın. Bütün soru biraz mantıklı değil ... C ++ ve Java yüzeysel olarak benzer, ama sonuçta çok farklı diller.
hyde

5
İnsanlar yeni özellikler kullanmak istemiyorsa diller nasıl gelişir? Yeni özelliklerin amacı, ortak problemleri çözerek hayatınızı kolaylaştırmaktır. Kullanıcılar yeni özellikler kullanmazlarsa, bunları uygulamak için kimsenin motivasyonu yoktur.
Matthew

72
Java istiyorsanız, Java'yı kullanın. C ++ kullanıyorsanız, C ++ sözdizimi ile Java'nın bazı korkunç, bükülmüş taklitlerini değil, C ++ kullanın. C ++ kullanmak, ancak kendinizi Java'nın özelliklerine göre kısıtlamak, size her iki dünyanın da en kötüsünü sunar.
Jerry Coffin

11
Farklılıkların sizi ne kadar hızlı ısırdığı (ve zor ) sizi şaşırtacaktır . Java ve C ++ ile çok farklı şeyler SomeObject a = previousObject;yapar . Java'da bir referansı, C ++ 'da nesneyi kopyalar. Java'da yapılacak değişiklikler önceki nesneyi de etkiler. C ++ 'da iki ayrı nesneniz var. a
Clockwork-Muse

Yanıtlar:


307

Hayır. Bu korkunç ve korkunç derecede yanlış yönlendirilmiş.

  • Java özellikleri bir şekilde C ++ özelliklerinden daha iyi değildir, özellikle de bir boşlukta.
  • Programcılar bir özelliğin nasıl kullanılacağını bilmiyorsa, daha iyi geliştiriciler yetiştirmek veya işe almak; geliştiricilerinizi ekibinizin en kötüsüyle sınırlamak, iyi geliştiricilerinizi kaybetmenin hızlı ve kolay bir yoludur.
  • YAGNI . Gerçek problemini bugün çöz, gelecekteki problemin hayaletini değil.

6
Son zamanlarda geliştiricilerin normalde yazmadıkları bir dilde kod incelemeleriyle ilgili bir soru vardı. Buradaki bilgeliğin burada geçerli olduğunu düşünüyorum: İyi bir geliştirici, herhangi bir dilde birçok temel hatayı görecektir, ancak her dilin o kadar çok alıcısı vardır ki, dil geliştiricileri incelemeyi yaparken maksimum faydanın sağlanabileceğini göstermektedir. C ++ sunucunuz "Yalnızca Java özellikleri" ise bu durum geçerlidir.
corsiKa

5
İkinci puanınıza ek olarak +1. OP, hangi özellikleri kullanmaları gerektiğine karar vermek için "C ++ En İyi Uygulamalar" hakkında okumaya zaman ayırmalıdır. C ++ hakkındaki son bilgilerim arkadaş fonksiyonları ve çoklu kalıtımın Bad Practices olduğu düşünülür . Şablonlar ve Operatör Aşırı Yüklemesi gibi şeyler , akıllıca kullanıyorsanız IMHO iyi uygulamalardır.
some_coder

4
@some_coder: Bunların ne zaman ve nerede olduğunu bilmek önemli. Politika tabanlı programlama yaptığımda, ana bilgisayar sınıfımın yapısını bu politika sınıflarının çalışması için gereken üyelerle genişletmek için (muhtemelen çoklu) politika sınıflarından miras alırım. Bu sadece nasıl çalıştığı. Ayrıca, operator<<( ostream &, T const & )genellikle üzerinden uygulanır friend. Bu, iyi bir dil özelliği ve kötü olan ile ilgili battaniye ifadelerindeki sorun:
Olmazsa

142

Sırf sözdiziminin yüzeyde benzer görünmesi iki dilin de uyumlu olduğu anlamına gelmez.

1, 4 ve 5 gerçekten aynı soru:

Şimdi, ben C ++ hayranı değilim, ancak "C ++ 'a özgü özellikleri olmayan kod genellikle daha iyi korunabilir" demek sadece saçma - Java'nın her şeyi doğru yaptığına ve tüm kötü olanları görmezden gelirken tüm iyi özellikleri kullandığına gerçekten inanıyor musunuz? Gerçekten evrensel olarak "kötü" veya "iyi" bir özellik olan bir şey olduğuna inanıyor musunuz? Varsa, neden tamamen iyi olan bir dile sahip değiliz? Ve hayır, Java kesinlikle o dil değil . Bu Java ve C ++ 'ın işe yaramaz olduğu anlamına mı geliyor? Tabii ki değil.

Liderleriniz Java yerine C # ile bağlantı kuracağınıza karar verirse ne olur? C # sadece geçersiz kılma operatörlerini desteklemiyor, aynı zamanda varsayılan olan da - örneğin insanların obj.Equals(obj2)yerine insanların kullanmalarını isteyecekseniz obj == obj2, insanlar her zaman hatalar yapacak. İki dilin yalnızca ortak özelliklerine devam etseniz bile, farklı beklentiler , farklı bir kültür var. if (myField == null)C ++ gibi bir şey yaparsanız , insanlar sizin bir acemi olduğunuzu göreceklerdir. Eğer kullanırsanız if (null == myField)C #, insanlar gerçekten henüz C # yerli değiliz göreceğiz - C geliştiriciler kullanmayı öğrendi nedenler "çevrilmiş" varyant artık C # bulunmaktadır.

Mantığınızı kullanarak, makine koduyla veya derlemeyle ya da COBOL ile sıkışmış olmalıyız, çünkü neden programcılarınızın öğrenmek zorunda kalacağı yeni özellikler eklediğinde, neden Pascal gibi bir şeye geçtiniz? Döngüler bile olmadığında neden SQL gibi bir şey kullanıyoruz ? SQL'de döngüler olmadığı ve X’in olmadığı durumlarda neden SQL’den başka bir şey kullanalım ?

C ++ kodu kesinlikle Java programcıları tarafından sağlanamaz. Bu fikri nereden edindiğinizi anlamıyorum - C ++ 'ı sadece Java ile aynı özelliklere sahip özelliklerle sınırladığınızda tam olarak ne kalıyor? Hatta yöntem çağrıları almayacaksınız - işlev çağrıları bile . Yine, her iki dilde de küme parantezi kullanması, dillerin herhangi bir şekilde değiştirilebilir olduğu anlamına gelmez.

Java benzeri C ++ kodlarını dönüştürmek, ne yaparsanız yapın, hataya açık olacak. Sadece çok fazla fark var. Uygulamanızı farklı bir dilde yeniden yazmak zorunda kalıyorsanız, her şeyi modüle etmenin makul yollarını düşünün, böylece parçaları tamamen kesmeden değiştirebilirsiniz. Ama sonuçta, YAGNI - ne yaparsanız yapın, kodunuzu "Java'ya dönüştürmeye hazır" hale getirmenin önemli bir maliyeti olacak. Bu, özelliklerinizi eklemek veya geliştirmek için harcanması daha iyi bir zaman geçirme zamanıdır.

Farklı dilleri kullanıyoruz, çünkü bize sorunları çözmek için farklı araçlar sunuyorlar. "Her yerde" çalışan yürütülebilir dosyalara ihtiyacınız varsa, Java ile gidin. "Her yerde" derleyen kod istiyorsanız , C ++ iyi çalışıyor. Anlaması ve ayrıştırması kolay bir kod istiyorsanız, LISP ya da her neyse gidin. Ama size bir şeyi söyleyebilirim - bir dilde başka bir dilde yazıyormuş gibi kod yazmak her zaman bir hatadır ve acı çekeceksiniz. Gerçekten bir C ++ adamını işe aldığınızda, o "Java-ish uyumlu" kodunu gördüğü anı çalıştıracaktan bahsetmiyor. Ve ... Java adamı da aynısını yapacak. Bilirsin, hem C ++ hem de Java'yı "bilmek" bile cehennem gibi koşarım :)

Aslında, sizin gibi düşünen bir Pascal geliştiricisi tarafından yazılmış (sade) C kodu üzerinde çalışmak zorundaydım. Daha #definesonra "BEGIN çevirileri {" için olanlarla tamamlanan, Pascal'a bakmak ve hissetmek için C'yi yeniden tanımlamak için kullandı . Sonuç oldukça tahmin edilebilirdi - ne C ne de Pascal geliştiricisinin anlayamadığı ve Pascal'ın C'nin üstüne “soyutlama” sının bir sonucu olan hatalarla dolu kod. Ve Pascal ve C bugünün bakış açısıyla neredeyse aynı . C <-> C ++ 'a gitmek bile çok daha fazla bir fark yaratıyor ve bu hala C ++ <-> Java gibi bir şeye benziyor.


9
“Anlaması ve ayrıştırması kolay bir kod istiyorsanız, LISP ile veya her neyse gidin.” Buna katılmıyorum. Lisp ayrıştırmak için önemsizdir, ancak tam da bu nedenle - ayrıştırıcıların ve onları etkili bir şekilde inşa etmenin ilkelerinin hâlâ başlangıç ​​aşamasında olduğu ve bu yüzden en saçma basan en basit şeyle uğraştıkları ve devam ettikleri bir zamanda yaratıldığı için. Bu muhtemelen işe yarayabilir - Modern dillerin sözdizimsel faydalarının çoğunu alamazsınız. Bu yüzden ayrıştırmak kolaydır, ancak anlaşılması kolay değildir . İnsanların buna "Gereksiz Parantez İçinde Kayıp" demesi için bir neden var.
Mason Wheeler

9
@MasonWheeler Bu bir zevk meselesi - C programcıları buna LISPers değil P adını verdi. Parantezleri sayın - tipik C ++ programınızdaki kadar çok var. Asıl fark onların pozisyonudur ( myFunc()karşı (myFunc)) ve bunun çok iyi bir nedeni var. LISP tabanlı diller, özellikle matematik / fizik insanlarında hala popülerdir. Asıl mesele, gerçekten de LISPy dillerinin modern C tarzı programcılara yabancı olduğudur - ama bu onu görmezden gelmek için bir sebep değil. Şema, Clojure ve bir ölçüde ML tabanlı diller (OCaml, F # ...) gerçekten çok LISPy.
Luaan

4
@Luaan LISP'nin fizikte popüler olmadığını kesin olarak söyleyebilirim. Alandaki iki baskın dil FORTRAN ve C ++. FORTRAN 'popüler' çünkü birçok eski kod içinde yazılmıştı, ancak hemen hemen tüm yeni programlar C ++ dilinde yazılmıştır. Bir araştırma fizikçisi olarak, bir zamanlar bir LISP programı ile karşılaşmamıştım ya da hiç duymadım. Var olmadıklarını söylememekle birlikte, diller kesinlikle popüler değildir .
James Matta

4
@Luaan Daha fazla yazılım geliştiricisine ihtiyacımız olabilir veya gerekmeyebilir. Kesinlikle daha fazla CS mezununa ihtiyacımız yok. Bu, "daha fazla yapısal mühendise ihtiyacımız var, bu yüzden daha fazla teorik fizik mezununa ihtiyacımız var" demek gibi.
Miles Rout

4
@ Bu yanlış yazıyor keyifli etkilerinden kaçınmak için var user1717828 if (myField == null)olarak if (myField = null)gayet C / C ++ derleme, ama muhtemelen, hangi değil amaçladığınız şeyi yapın. Öte yandan, if (null = myField)bir sabit atayamayacağınız için bir hata atar.
Wlerin

94

Sorularınıza sırayla cevap vereceğim.

  1. Java, C ++ 'a sahip bir özellik sağlamıyorsa, bu özelliğin iyi olmadığı anlamına gelir, bu yüzden onu kullanmayı önlemeliyiz.

Evet, Java’da bulunmayan herhangi bir özellik, sabit sürücüdeki bir anatemadır. Kod tabanınızdan yazılmalıdır. İtaat etmeyenler korkutulur, ruhları RAID tanrılarını yatıştırır.

  1. 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ı.

Şüphe durumunda, ekibinizin en az yetkin üyesi için kod yazın. Kod, yazıldığından çok daha fazla okunur ve yazabildiğiniz kadar akıllı olan kod okumak için çok zekicedir. Ön büro personelinizin anlayamayacağı kod incelemeleri reddedilmelidir. Yardımcı olmak için, hafta sonları Visual Basic 2.0 ile nasıl programlanacaklarını öğretin, ardından kodlama stillerini hangi dilde kullanıyorsanız kullanın.

  1. Kodu bir gün Java'ya dönüştürmeniz istenebilir

Doğru! Peki neden Java'da dursun? Kodu bir gün basic, assembler ve / veya perl biçimine dönüştürmeniz istenebilir. Dışarıdaki her dilde perl tercümanlar olduğu için, programınızı uzun bir perl dizisi olarak yazın ve seçeceğiniz dilde marşal argümanlarını yazın.

Şimdi dilleri değiştirmeniz gerektiğinde, perl dizesini saran kodu tekrar yazmanız yeterlidir.

  1. C ++ 'a özgü özelliklere sahip olmayan kod genellikle daha iyi korunur

Daha az özellik kullanan kodun bakımı daha kolay olduğu doğrudur. Tüm diller bir Turing Makinesi ile aynı olduğundan ve bir Turing Makinesi herhangi bir programlama dilinin en az özelliğine sahip olduğundan, yukarıdaki perl yorumlayıcısının gerçekte sorununuzu çözen bir Turing Makinesi (bant ve diğerleri) çalıştırmasını sağlayın.

  1. 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.

C ++ diline özgü özellikler aslında değerli bir kullanıma sahiptir. Java olmadıkları için, anathema ve onu kullananlar heretik markalı olabilir. C ++ bu dil özelliklerine sahip olmasaydı, fedakarlık yapmanız gerekenleri bulamazdınız. C ++ dil özellikleri sorunları çözer!


Bakın, C ++ ve Java farklı yeteneklere sahip. C ++ ve Java'nın kesişimindeki programlama, her iki dilin de avantajlarının çoğunu ortadan kaldıran kodla sonuçlanır .

Java kısmen C ++ özelliklerinin kötüye kullanılmasına bir tepki olarak geliştirildi. Bu, özellikle özelliklerin olgunlaştığı yıllarda yıllar sonra reaksiyonun haklı olduğu anlamına gelmez.

Operatör aşırı yüklemesiyle korkunç şeyler yapabilirsiniz; ancak hiçbir dil, tüm kodların dilde yazılmasını engellemediği sürece, korkunç kodların dilde yazılmasını engelleyemez.

Ayrıca, operatörün aşırı yüklenmesi ile çok zarif şeyler yapabilirsiniz. Karmaşık sayı ya da matris gibi çalışan karmaşık sayı ya da matris sınıfı gibi basit şeyler.

Java'da bulunmayan C ++ özelliklerini kullanma konusunda dikkatli olunmalıdır. Sadece şu anki geliştiricilerinizin mevcut beceri seviyelerindeki bir özelliğin anlamadığı, asla kullanılmaması gerektiği anlamına gelmez; Aynı zamanda, sadece bir özellik kullanabildiğiniz için, yapmanız gerektiği anlamına gelmez. Bununla birlikte, Java'nın yoğun olduğu bir mağazada, direnç, Java-esque özelliklerine karşı olması gerekenden daha güçlü olacağına işaret ediyor.

Kodların diller arasında dönüştürülmesi, yapısal olarak ne kadar benzer olursa olsun, yeniden yazma ile en iyi şekilde yapılır. Böyle bir yeniden yazma olmadan bunu yapmak için yapılan herhangi bir girişim sefilce başarısız olacak.

C ++ 'a özgü özelliklerin çoğu bakım için harikadır. Silme türü (like std::function), bağımlılıkları azaltan hiyerarşileri birleştirmenize izin verir. Akıllı işaretçiler ve deterministik yaşam ömürleri ve RAII, çalışma zamanı sürprizlerini azaltır ve kaynak kazanını yoldan çeker. Ağır statik tip kontrolleri, çalışmamak yerine kodun derlenemediği anlamına gelir. Karışımlar kod çoğaltmayı azaltır. ADL, geçici olarak hiyerarşiler arasındaki arabirimlerin bağımsız olarak genişletilmesine izin verir. Lambda, kullanıldığı yerin yanına kod yazmanıza izin verir. İletme ve taşıma, kopyaları azaltır ve işlevsel stil (yan etki göstermeyen) programlamayı verimli hale getirir. Operatör aşırı yüklenmesi, hat gürültüsünü azaltır ve kodun, modellemekte olduğu matematik gibi görünmesini sağlar.

Turing Tar çukuruna dikkat edin. Her şeyi herhangi bir dilde uygulayabilirsiniz (Ham Bantlı Ham Turing Makinesi dahil), ancak bu yapmanız gerektiği anlamına gelmez . C ++ 'ta Java ++ esque yapılarını kullanarak öykünmek korkunç bir fikirdir; bu, hiç kimsenin okuyamadığı veya anlayamadığı sürdürülemez bir kodla sonuçlanacaktır.

Java tasarımlarından ilham alabilir ve bunları C ++ 'a taşıyabilirsiniz . Python'un dil özelliklerini kullanmanın ve bunları C ++ 'da uygulamanın harika bir hayranıyım çünkü sözdizimini seviyorum. Fakat bu, sınıf metotlarımı, açık bir benliğimi alarak statik metotlar olarak yazdığım, ardından statik olmayan metot çağrısını yönlendiren bir sarmalayıcı yazdığım anlamına gelmez.

Modern C ++, Java'nın taklit ettiği ve reddedildiği diline benzemiyor. Bir dilin özelliklerine göre kilitlenmeyin; "bir gerçek dil" yok. Yeni diller ve özellikleri hakkında bilgi edinin ve ayırt ediciliğini özümseyin.


1
-1, uzun soluklu ve net değil.
djechlin

4
-1 tartışmacı, straw-man tartışması
user949300

28
+1, sorulan soruların doğru şekilde imkansızlaştırılması ve güldüm :)
kedi

11
+1. Komik ama konuyu koruyor. Aslında okuyan insanlar için son derece açık.
Luis Masuelli,

14
"C ++ ve Java'nın kesişimindeki programlama, her iki dilin de avantajlarının çoğunu ortadan kaldıran kodla sonuçlandı." Taşı gediğine oturtmak! +1
Ajedi32

56

Sadece nedenlerine cevap vereceğim:

  1. Bu sonuca nasıl geldiğini anlamıyorum. Farklı dillerin farklı özellikleri var. Kapsam, dilin mimarisi, bazen yaratıcıların tercihleri ​​ve daha birçok nedene bağlıdır. Bir dilin bazı özellikleri kötü olabilir, ancak genellemeniz IMHO'nun yanlış anlaşılmasıdır.
  2. Java gibi C ++ yazmak daha kötü kodlara yol açabilir. Örneğin bugünlerde C ++ 11 ile yeni / delete kullanmaktan kaçınıyorum ama paylaşılan işaretçiler kullanıyorum. Senaryoda sadece yeniye / silime güvenirim. Programlayıcılarınız yalnızca Java’yı anlarsa, onları eğitin veya daha iyisini kiralayın.
  3. Bu muhtemelen olacak mı? Neden başta Java yazmıyorsun? Programların sıfırdan yeni bir dilde yeniden yazılmasının genellikle kötü bir fikir olduğunu düşünüyorum ve böyle bir risk için gerçekten iyi bir gerekçeye ihtiyacınız olacağını düşünüyorum.
  4. Bu sadece bir varsayımdır.
  5. IMHO'ya yüksek oranda senaryo ya da kullanım senaryosuna bağlıdır.

27
Java-Programcıları da kullanmazlardı delete.
Paŭlo Ebermann

8
Java programcılarının bilmediği bellek sızıntılarını düzeltmek zorunda kaldım delete. Hatırladığım kadarıyla, bu vakalardan en az birinde, dinamik tahsise ( new) da gerek yoktu.
Ethan Kaminski

16
@EthanKaminski Evet, C ++ acemisini, özellikle de Java kökenli veya benzeri bir kişiyi kolayca tespit edebilirsiniz. Her şey için yeni kullanmayı bırak, kahretsin!
Luaan

1
@ PaŭloEbermann Evet, daha da kötüsü.
Simon

1
"Senaryoda sadece" yeni / sil "'e güvenecektim - komik," Java (sadece) özelliğine sahip "C ++ deyiminin yalnızca kullanacağını düşünürdüm make_shared.
Kyle Strand

26

Java, C ++ 'ın yerleşik, hızlı, güvenilir bir çöp toplayıcı, tek köklü bir nesne hiyerarşisi ve güçlü bir sorgulama gibi yapmadığı özelliklere sahiptir.

Java'nın diğer özellikleri, Java'ya özgü özelliklerle birlikte çalışmak üzere tasarlanmıştır ve yeni özelliklerin eksikliği için Java'nın C ++ özelliklerinin bir çok ihmali mümkündür. Örneğin, Java deterministik yıkıcılara sahip yığınla ayrılmış nesnelere sahip değildir, ancak nihayetinde bu eksikliği telafi etmek için nihayet (Java 7'den beri kaynaklar) ve çöp toplayıcıyı bloke etmiştir.

C ++ sonunda blok veya çöp toplama işlemi yapmaz. Yıkıcıları Java'da bulunmadıkları için kullanmıyorsanız (sonlandırıcıları saymıyorum), temizleme düzeyinizi gruplayamıyor olmanız dışında, C düzeyindeki kaynak yönetimi (yani, tüm kılavuz) Java'ya da gitmediğinden, gittiğiniz bir temizleme bloğuna. Bunun sürdürülebilirliği artırdığını düşünüyor musunuz?

Java, her sınıfın nihayetinde Nesneden türetildiği ve ilkel birkaç türün de bu tür sınıflara otomatik olarak kutulanabileceği kapsamlı bir nesne hiyerarşisine sahiptir. Bu, nesnelerin kaplarını bir kez yazmayı, işaretçileri Nesne'ye tutmayı sağlar. Java 5, bu tür konteynerlerin gerektirdiği yayınlardan kurtulabilen, ancak yine de hemen hemen aynı kodu derlemek için jenerik ürünler tanıttı.

C ++ böyle bir hiyerarşiye sahip değil. Birden fazla tür için çalışan kapların yazılmasını kolaylaştırmak için, derleyici tarafından farklı türler için gereken örneklemeler olan şablonlar kullanırsınız. Şablonların (ve makroların) kullanılmasını yasaklar ve aynı kap kodunu farklı tipler için tekrar tekrar yazmanın veya boşluk işaretleyicileri kullanmanın C yolunu izler misiniz? (Bekle, Java işaretçileri boş bırakmaz!) Bunun sürdürülebilirliği artıracağından emin misin?

İyi bir dil, birlikte çalışmak üzere tasarlanmış çok sayıda özelliğe sahiptir. A diline ait özellikleri yasaklayarak, B diline sahip olmadıkları için, A diline zarar verirsiniz, çünkü aynı zamanda B'yi uyumlu bir bütün yapan özellikler eklemezsiniz.

Bu, C ++ 'ın izin verilen özelliklerini kısıtlamamanız gerektiği anlamına gelmez. C ++, programcının güvenlik ve kullanım kolaylığı konusunda ne istediğini yapmasına olanak tanıyan büyük ve tarihsel olarak geliştirilmiş bir dildir ve tüm esnekliklerindeki özelliklerinin hepsinin iyi programlar oluşturmak için gerekli olması gerekmez. Bazı özelliklerin kullanımını kısıtlayan birçok kodlama standardı vardır; örneğin Google’ın yönergeleri çoğunlukla çoklu kalıtım, karmaşık şablonlar ve istisnalar hariçtir (en sonuncusu tarihsel nedenlerden dolayı olsa da). Ancak "Java'da bulunmadığı için" hiçbir özellik yasak değildir; özellikleri sadece C ++ çerçevesinde değerlendirilir.


27
Tecrübeli C ++ gazileri genellikle Google kodlama kurallarını reddeder. Modern C ++, bu özellikleri kullandığından kesinlikle daha iyidir . Evet, daha da farklı kılar.
Jan Hudec

17
C ++ 'ın nihayet blokları olmadığını, ancak çoğu durumda çok daha iyi olan RAII'ye sahip olduğunu unutmayın. Ve yine farklı.
Jan Hudec

7
Java'nın çoğu kullanım için Objecthemen hemen bir void*- Yine de, yuck.
Quentin

1
Özellik seçiminin ötesinde, stil ve deyim meselesi var. Programlar, yazdıkları dilin normal deyimlerini kullanıyorlarsa okunması ve bakımı genellikle daha kolaydır. C ++ programının bir kısmını yalnızca Java benzeri özellikler kullanarak yazabilse bile, sonuç garip ve stilize edilmiş C ++ olur.
Patricia Shanahan

2
Bu cevabı doğru yolda olduğum için ("yapma!") Abartırdım, ama Java’nın bir şekilde C ++ 'dan daha "ileri" olduğu fikrine dayanamıyorum. C ++ gelmez gerek üzgün ben çünkü cümleyi bitirmek için nasıl bilmiyorum ... Bir çöp toplayıcı veya tek kök nesne hiyerarşisini, Java gerekmez aynı şekilde ... err özledim Java deterministik yıkıcı ve finallyonların yerine geçmez. İki dil sadece temelde farklı.
DevSolar

25

Tamamen makul sonuçlar çıkaran bir sayıya ulaştığınızda başka bir cevap göndermeyi zahmete sokacağımı tartışmıştım: fikrinizin temelde gerçekleşmeyi bekleyen bir felaket olduğunu. Bununla birlikte, bu sonucun arkasındaki son derece önemli sebeplerden bazılarına işaret etmekte başarısız olduklarını düşünüyorum .

Java ve C ++ arasındaki farklar , odaklandığınız detaylardan çok daha derindir.

Örneğin, C ++ 'da çoklu kalıtımın yasaklanması hakkında konuşursunuz. İlk önce bunun sadece noktanın eksik olduğunu işaret edeceğim. Java “arayüzleri” “sınıflardan” ayrı şeyler olarak tanımlar. Bir sınıf yalnızca bir sınıftan miras alır, ancak keyfi sayıda arayüz uygulayabilir.

C ++ iki kavramı bu şekilde ayırmaz. Java bir arabirim uygulama sağlar ++ yakın analog Cı olduğu başka bir sınıftan miras. Bu nedenle, ikisinin makul derecede iyi bir şekilde hizalanmış olması için , muhtemelen C ++ 'da çoklu kalıtım kullanmanız gerekir , ancak bu temel sınıfların bazılarını kabaca aynı şekilde sınırlamak istiyorsunuz; Java, bir sınıfı bir sınıfa kıyasla (yani, esasen) sınırlar. işlev imzalarını belirttiği, ancak en azından çoğunlukla uygulamaları belirlemediği).

Bu ikisi arasındaki gerçek farklılıkların yüzeyini zar zor çiziyor. Gerçekte, Java kodunun arayüzleri tanımlaması muhtemel olduğunda ve bu arayüzleri uygulayan sınıflarda, C ++ kodunun, gereksinimlerini karşılayan herhangi bir sınıfla çalışacak bazı şablonları tanımlama olasılığı daha yüksektir (yalnızca arayüzü uygulamak için tanımlanmış olanları değil) (ler) belirtir).

Dürüst bir şekilde temelde "C ++ sözdizimini kullanarak Java" olan bir kod istiyorsanız, kesinlikle kesinlikle bir şey ve ikincisine benzer her şeyi yasaklamak zorunda kalacaksınız. Şablonları kullanımınızı, kabaca Java generics'in desteklediği "T kabı" seviyesine sınırlandırmanız gerekecektir. Ne yazık ki, bunun yapılması C ++ koduyla sonuçlanacak, böyle bir karmaşaya yol açacak, şu anda varlığını sürdürdüğü gibi, başka bir programlama diline çevirmenin uzun vadeli olasılığından bahsetmiyoruz.

Gelecekte başka bir dile çevrilebilecek bir kod istiyorsanız, onu olabildiğince temiz ve okunaklı hale getirmeye çalışın. İdeal sözde kodu yazmak ve hala yürütmesini sağlamaktır. İyi yazılmış modern C ++, önerdiğiniz alt kümeden çok daha ideal olan yaklaşımlara yaklaşıyor. Nasıl yazdığınız önemli değil, Java’ya çevirirseniz, yalnızca tek tek ifadelerin sözdizimini değil, kodu çevirmeniz gerekecektir.


Birçok C ++ özelliği, Java kavramlarına güzel bir şekilde eşleşen bazı şekillerde ve olmayan diğer yöntemlerde kullanılabilir. Bir programın bazı bölümleri, dillerin işlevselliğinin örtüşen alt kümesinin dışında bir şeye ihtiyaç duyacak ve "C ++ sözdizimini kullanarak Java" gibi bölümleri yazmaya çalışmak korkunç bir karmaşaya yol açacak. Öte yandan, kodun diğer birçok kısmı, paylaşılan alt kümenin dışındaki herhangi bir şeye ihtiyaç duyabilir ve kodun dışına çıkmak için zorlayıcı bir neden bulunmadığı kısımları için paylaşılanlar arasında kalmaya çalışmak yararlı olabilir.
supercat,

Muhtemelen "gerekebilir" dediğiniz yerde, gerçekten demek istersiniz: "gerekmeyebilir"? Varsaydım, o zaman kabul etmeye meyilliyim.
Jerry Coffin,

Evet. Java'yı destekleyen ancak C ++ 'ı destekleyen bir platformu desteklemek gerekirse, kodun bölümlerinin neredeyse kesinlikle sıfırdan yazılması gerekir ve bu bölümlerin bazı Java dostu teknikler kullanılarak yazılmış olup olmadıkları önemli değildir. Yine de yeniden yazacağım. Bununla birlikte, başka bölümleri, tam bir yeniden yazma olmadan geçirilmelerini sağlayacak şekilde geçirmeleri mümkün olacak şekilde yazmak mümkün olabilir ve bazı durumlarda, bunun için gereken ekstra maliyet minimum olabilir.
Supercat,

4
@supercat: OTOH, Java'yı destekleyen ancak C ++ 'ı destekleyen platform sayısı göz önüne alındığında, bu beni neredeyse bir sorun arayışında tamamen bir çözüm olarak ortaya koyuyor.
Jerry Coffin,

Bir süredir, Java uygulamaları için tarayıcı desteği C ++ uygulamalarından daha iyiydi. Bununla birlikte, JavsScript için tarayıcı desteği (Java ile ilişki yoktur), ancak temelde her ikisinden de alınacak kadar gelişmiş.
supercat,

11

X dilinde kod yazacaksanız, dili doğru bir şekilde öğrenmek ve sorunu çözmenize yardımcı olmak için sunduğu tüm özellikleri kullanmak için zaman ayırın. Japoncadan İngilizceye veya Java'dan C ++ 'ya, bir dilden diğerine "kelime için bir kelime" çevirisi yapmaya çalıştığınızda kötü şeyler oluyor. Sorunun iyi anlaşılması ile başlamak ve çözümü, kullanılan dil için en doğal olan şekilde ifade etmek çok daha iyidir.

Yıllar önce, girintisiz bir C programı gördüm ve her bir ifade 7. sütunda başladı, çünkü kodun yazarı C'yi kullanan bir Fortran programcısıydı. İşaretçilere işaretçilerden bahsedecek yüreğim yoktu, sanırım olay yerinde bayılacaklardı.

Gelecekte bu kodu saklamak için birini işe aldığınızı hayal edin. Eğer iyi bir C ++ kodu varsa, yetkili bir C ++ geliştiricisi işe alabileceksiniz ve onların yolunu bulabilecekler. Eğer "C ++ 'da Java" ise, ne C ++ ne de Java geliştiricileri kodu anlamak için kolay bir zamana sahip olmazlar.


7

Bütün nedenlerin ispatlanabilir:

Java, C ++ 'a sahip bir özellik sağlamıyorsa, bu özelliğin iyi olmadığı anlamına gelir, bu yüzden onu kullanmayı önlemeliyiz.

Özelliğin iyi olmadığı anlamına gelmez (hiçbir özellik doğal olarak kötü olamaz). Bu, yalnızca özelliğin sıklıkla kötüye kullanıldığı (veya doğrudan toplama gibi çöp toplama gibi temel kavramlar nedeniyle uygulanması imkansız olduğu) anlamına gelir. Java'nın tanımı gereği daha kolay ve programcı dostu olması amaçlanmıştır, bu nedenle kendilerini kolayca kötüye kullanabilecekleri kanıtlanmış özelliklerin kaldırılması.

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ı.

Oh olabilir mi? En basit C ++ kodunu görelim:

int len = mystring->size();

Hata! "Dile özgü" özellik kullanılmadı, ancak Java devs! Çünkü Java’da "." buradayken "->.

Kodu bir gün Java'ya dönüştürmeniz istenebilir

Veya C #. Veya Haskell. Veya Python. Veya Ruby. Veya COBOL (evet, yapabilirsiniz!). Geleceği nasıl anlatabilirsin?

C ++ 'a özgü özelliklere sahip olmayan kod genellikle daha fazla bakım gerektirebilir.

Tam tersi. Programlamayı kolaylaştırmak ve böylece bakımı daha da kolaylaştırmak için her özellik tanıtıldı. Örn: şamandıralarda çalışan bir program yapın. Şimdi karmaşık sayıları işlemek için yükseltin. Operatör kurtarmaya aşırı yükleniyor!

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.

Fakat Java DOES'in çoklu mirası var! Buna "arayüz" denir. Java uygulaması, her şeyin kaynaklanmasından kaynaklanan korkunç elmasları önlemek için sorunlu bir geçici çözümdür Object. interfaceHangi tek amacın türetilmeyen bir şey olduğunu tanıtmakla yapılır Object. C ++ bu problemi hiç yaşamadı - zorunlu ortak bir temel yoktur, böylece her sınıf korkak elmas olmadan bir arayüz olarak işlev görebilir.

Yan not: Java yakın zamanda tanıtıldı ... arayüzlerde somut yöntemler. C ++ özelliği her zaman orada bulunmayan bir sorunu çözmek zorunda kaldı.

Ayrıca sadece çok az "C ++ 'ın sahip olduğu fakat Java'nın sahip olmadığı" şeylerden bahsettiniz. C ++ ve Java arasındaki en büyük farklardan biri bellek düzeni üzerindeki kontrol. Nesnelere işaretçiler dizisi oluşturabilirsiniz (Java'da olduğu gibi) VEYA bitişik bellek bloğu oluşturabilirsiniz. Şimdi, Java devs'i yanlış yönlendirebilecek bir C ++ özelliği hakkında endişeleniyorsam, bunun gibi gizli ve incelikli bir şey listemde açıkça görülebilen ve çok sayıda devralma veya aşırı yüklenmiş operatörler gibi ilk görüşte tanınan şeylerden çok daha üst sıralarda yer alır.

Alt satır: Temiz kod temiz koddur. Java veya C ++ - aynı fark. Sadece basit tut. Gereksiz komplikasyonlar, kötü kodun önde gelen nedenidir.


Java, C ++ 'nın tüm özelliklerini sunan bir dilde desteklenmeyen bazı özellikler ve garantiler sunmaktadır. Örneğin bir dil, C ++ 'da yer alan çoklu kalıtım biçimlerinin genelleştirilmiş biçimlerini sunarken, dinamik tip yüklemeye ve Java'nın tüm kimlik koruma basamağı yelpazesine izin veremez.
supercat

@supercat Bunu neden burada söylediğinizi anlamıyorum. Soru, C ++ ile çoğaltılamayan Java özellikleriyle ilgili değil, Java'nın attığı C ++ özellikleriyle ilgili.
Ajan_L

Demek istediğim, Java’daki bazı özelliklerin C ++ 'da bulunmadığı, ancak Java’nın bazı özelliklerinin temelde C ++' a dahil olan diğer özelliklerle uyumlu olmadığı, yani hiçbir dilin her ikisini de destekleyen türlere sahip olamayacağı (C ++ / CLI gibi diller) C ++ özelliklerini destekleyen türleri ve Java-ish özelliklerini destekleyen türleri var, ancak birlikte çalışabilirliği sınırlı olan ayrı evrenlerde etkin olarak oturuyorlar).
Supercat,

6

Hayır, genellikle C ++ gibi bir Java gibi yazmamalısınız ve Java'da bulunmayan C ++ dil özelliklerini kesinlikle göz ardı etmemelisiniz .

Birincisi, Java çöp toplanan ve bu nedenle C ++ "delete" anahtar kelimesine eşdeğer yok. Tamam, yani silmeden bir program uyguluyorsunuz, çünkü kurallarınıza göre izin verilmiyor.

Tebrikler, artık bir bellek sızıntısı var;). Bu da teorik değil - Bu kesin durumun açık kaynaklı bir oyunda gerçekleştiğini gördüm.

Benzer şekilde, Java, pek çok ortak işlev çağrısı kuralını dışlayan C ++ işaretçilerine benzer bir şeye sahip değildir .

C ++ 'dan kaçınmanız gereken özellikler (aşağıya bakınız) vardır, ancak "Java'da olmamak" iyi bir turnusol testi değildir.


Daha iyi kurallar aşağıdaki olurdu:

  1. Dilinize, ortamınıza ve araçlarınıza uygun kodu yazın.
  2. Takımınızın anlayabileceği bir kod yazın .
  3. Takımınızın verilen alanda yetkin olduğundan emin olun.

Öğe (3), C ++ dilinde C ++ eğitimi almadan Java programcı koduna sahip olmamanız gerektiği anlamına gelir. Java'nın tuhaf bir lehçesi gibi davranmaya çalışıyorlarsa öğrenemeyecekleri bazı ince ancak çok önemli farklılıklar vardır.

Madde (2), eğer ekibiniz özellikle birden fazla kalıtımdan rahatsızlık duyuyorsa (örneğin) ve onu kullanmayan yeterli bir çözüm varsa, o zaman bu alternatif çözümü kullanmak en iyisi olabilir. Ancak, bu özellikle ekibinize bağlıdır. Öte yandan, eğer takımınız bu alternatif çözümden birden fazla mirasa göre daha rahatsızsa, birden fazla miras kullanın!


Son olarak, tartışmalı bir şekilde kaçınması gereken C ++ 'ın ARE dil özellikleri var. Bunların ne olduğunu bilmek istiyorsanız , farklı bir dilin programcıları yerine C ++ programcılarına danışın . Başlamak için bazı örnekler işaretçi aritmetik (evrensel fikir birliği yok) ve goto.


6

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, newJava'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 &foohangi 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. ( *newKullanarak #define New *newveya 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, deleteJava'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_ptrnedir? İnce zor "gotchas" make_sharednedir? (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_ptrKendi 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 foove 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 :

  1. 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.
  2. 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.

constexprJava 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 constexprderleme zamanı fonksiyon değerlendirme yapmak için mevcut fakat durumunda da görüleceği üzere constexprhiç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ış,


5
FQA yazarı kesinlikle "dilin en fazla% 20'sini anlayın" grubuna giriyor. Oldukça yanlış olan birkaç cevap var ve bir kaç kişiden daha fazlası var;
Ben Voigt

2
C ++ FQA'daki şikayetlerin çoğu (neredeyse tümü?) Anlamsız. Modern diller çok büyük. C ++ Python, Ruby, Perl ve evet, Java ile karşılaştırıldığında oldukça küçük. Stackoverflow bu dillerde temel soru sorun ve ilk cevap çizgisinde neredeyse kaçınılmaz olduğunu "Neden vermedi import SomeVeryBasicPackageve sadece bunu bu ?" Gelişmiş bir soru sorun ve ilk cevap çizgisinde neredeyse kaçınılmaz olduğunu "Neden vermedi import SomeMagicalPackageve sadece bunu o ?"
David Hammen,

1
@DavidHammen Bence 80/20, temel standart özelliklere değil, sadece standart kütüphane bileşenlerine atıfta bulunuyor, bu durumda bahsettiğiniz diller, Perl hariç, C ++ kadar büyük ve karmaşık görünmüyor. Her durumda, bu cevabımın çok küçük bir parçasıydı ve bunun önyargılı bir kaynak olduğunu kabul ettim.
Kyle Strand

1
VM / yönetilen diller açıkça yüzey altında çok daha karmaşık, ancak kullanım açısından karmaşık demek istiyorum.
Kyle Strand

1
Teorinizin doğru olup olmadığı hakkında hiçbir fikrim yok, ancak benim durumumda kesinlikle C ++ ve C'yi ayrı ayrı öğrendim ve C ++ dersim gerçekten çok iyiydi. Ama 20/80 bölünmüş hakkında tam alıntı her programcı bir bilmesidir farklı bağımsız dilin C bölümünü öğretiliyor çoğu programcılar ile açıklanabilir olmaz dil,% 20. Her neyse, C ++ 'ın daha sağlam bir programlamaya nasıl izin verdiğini ayrıntılı olarak açıklamak isterseniz (daha önce gördüğüm ancak anlamadım), muhtemelen bir sohbet odasında ya da buradaki yorumlar yerine bir şey yapmalıyız. .
Kyle Strand,

5

Proje ortamındaki C ++ 'ı kullanmakla sınırlı olduğumu varsayalım. C ++ 'ın sahip olduğu fakat Java'nın sahip olmadığı bazı dil özelliklerinin kullanılmasının engellenmesi iyi midir (örneğin: çoklu kalıtım, operatör geçersiz kılma)?

Hayır.

Eğer "projenin ortamı" ile, C ++ 'ı kullanmakla sınırlıysanız, o zaman, eğer varsa, kişisel olarak ne kadar kullanacağınızı / değiştirmeyi umursanız da, başka bir teknolojiyi düşünmeye bile dikkat edemezsiniz.
"Teknoloji X" veya İster "Y" herhangi bir özellik olmalıdır destekler ne olursa olsun hiçbir etkiye yolda hangi size C ++ uygulama oluşturmak.
Muhtemelen bazı "İyi Sebepler" için (şimdi veya geçmişte) bir C ++ uygulamasıdır, bu nedenle, belirli bir "araç kutusu" ne sağladığını kullanarak onu C ++ uygulaması olarak yazmalısınız .

Uygulamayı başka bir teknolojiye taşıma Gereksinimi varsa ve o zaman (ve yalnızca o zaman) diğer platformlardaki özellikleri göz önünde bulundurun. Bir şeyin olabileceği ihtimaline karşı, "yüzünü kırmak için burnunu kesmenin" bir anlamı yok . Ancak, toptan yeniden yazmanın, Yönetim'in bunu yapmak için çok iyi bir neden olmadan üstlenemeyeceği pahalı ve riskli bir işlem olduğunu unutmayın.

Visual Basic [.Net] Dünyasında bazılarının [çekirdek dili] kullanmadan Visual Basic uygulamaları yazmanız gerektiğine dair parlak bir fikre sahip olduğu bazı ("kullanmak veya kullanmamak") tartışmaları vardı. Microsoft.VisualBasic ad alanı tarafından sağlanan işlevsellik. Std :: namespace olmadan bir C ++ uygulaması yazmaya çalışmak gibi olurdu; Tamam, bu mümkün ama neden dünyadaki herhangi biri aklı başında bunu yapmayı rahatsız ediyor?


1
Visual Basic ile ilgili son noktaya gelince: Bu tür satıcı kütüphanelerinin sorunu , tescilli olmalarıdır. Bunları kullanmak, kendinizi satıcıya zincirlemek anlamına gelir. Satıcı sizi zincirlemekten hoşlanır, ancak uzun vadede olmayacaksınız: Başka bir satıcının yazılımını, satıcıya özgü işlevlere dayanan her şeyi yeniden yazmadan kullanamazsınız. Satıcıya özel işlevler ne kadar çok kullanırsanız, satıcılarda değişiklik yapma zorunluluğunu artırarak satıcıları değiştirme maliyeti artar. Özgür (özgürlük gibi!) Yazılımların bu kadar büyük olmasının sebeplerinden biri de budur.
cmaster

İsim Microsoft.VisualBasicalanı biraz gerdirilir. En son kullandığımdan bu yana yıllar geçti, ama en azından başlangıçta çoğunlukla VB6 ile geriye dönük uyumluluk sağlamak (ve / veya VB6 programcılarını “evde” hissettirmek) amaçlandı; Çoğunlukla çerçevenin geri kalanında mevcut olan işlevselliği daha modern (ve daha iyi entegre) bir biçimde sağladı, bu yüzden yeni projelerde onu nadiren kullanmak mantıklıydı. Bunun tersine, std::ad alanı tüm standart kütüphanenin bulunduğu yerdir - bundan kaçınmak, .NET'te tüm BCL'den kaçınmak gibi olur.
Matteo Italia

2

Mevcut tüm cevaplar, kullandığınız dilden faydalanmanız gerektiği ve C ++ özelliğinin neden sadece Jave'de olmadığı için “kötü” olmadığını açıklamanız gerektiği için bunun kötü bir şey olduğunu söylüyor. Buna farklı bir açıdan cevap vereceğim.

Çoklu kalıtım, operatörün aşırı yüklenmesi ve kendi şablonunuzu tanımlama gibi karmaşık C ++ özelliklerinden kaçınmak bir şeydir.

Fakat en basit görevden daha fazlasını yapan herhangi bir sorun:

  • bellek ayırır,
  • bu parayı puanla birleştirir
  • yani veri yapıları oluşturun
  • daha sonra güvenli olduğunda tekrar kullanılmasını sağlar.

Yukarıdakilere izin veren ortak bir Java ve C ++ alt kümesi yoktur, bu nedenle sorduğunuz işlemi yapmak imkansızdır. (Java ve C # hakkında sorularınız varsa, her ikisi de çöp toplayıcıları kullandığından daha iyi bir şansınız olur.)

Ancak, bir Java geliştiricisinin ne yaptığını (ancak ayrıntılı "nasıl" değil) anlayabilmesi için kodun yazılmasını isteyebilirsiniz ve bu mantıklı olacaktır.

C ++ ve JAVA dillerinde uyguladığınız kendi dilinizi de tasarlayabilirsiniz.


0

Hiç kimse diğer kodlayıcıların anlamadığı bir kod yazmamalıdır. Dil kilidinin bir sorun olduğunu düşünüyorsanız, geliştirici kilidini alana kadar bekleyin. Birinin seni diğerinden daha rehin tutması daha muhtemel.

Gerçekten teknik bir sebep yok. Yarattığınız şey, bir dilin hangi nedenle olursa olsun kullanıldığı bir senaryodur, ancak şimdiki ve muhtemelen gelecekteki geliştiricilerin çoğu gerçekten anlamıyor.

Tahminimce, Java geliştiricileri, C ++ 'ı Java'da yazdıkları şekilde yazarlar, bu yüzden neden bir kural haline getirmişlerdir. Java geliştiricileriniz için küçük bir C ++ talimatı / dokümantasyonu ile uygulanması ve bakımı daha kolay olan bazı C ++ 'a özgü özellikleri keşfedebilirsiniz, aksi takdirde tutulacakları büyük Java karmaşası.

Bu, BASIC programcılarının nesne yönelimli dillere taşınmasıyla ilgili problemleri tartışıyor. OOP uygulamalarını, anlamayan yeni devlerin zararına uyguladıkları değil, uygulanmadıkları için değil. Eğer yaparlarsa, genellikle yanlış anlarlar. Bir şey kötü yapılırsa, sebebi ne olursa olsun kaldırılması gerekir.

Sadece kör bir şekilde kodu kopyalayıp yapıştıranlar dışında, zaten anlamadıkları birçok alanda bunu yapacaklar.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.