C ++ kullanarak ancak dilin belirli özelliklerini kullanmamak için C'ye geçmeli mi?


16

Boş zamanlarımda hobi olarak bir NES öykünücüsü geliştiriyorum. C ++ kullanıyorum çünkü en çok kullandığım dil, çoğunlukla biliyorum ve çoğunlukla seviyorum.

Ama şimdi projeye biraz ilerledim, C ++ 'ın neredeyse tüm spesifik özelliklerini kullanmadığımı fark ettim ve bunu düz C'de yapabilir ve aynı sonucu elde edebilirdim. Şablon, operatör aşırı yüklenmesi, polimorfizm, kalıtım kullanmıyorum. Ne söylerdin? C ++ 'da kalmalı mıyım yoksa C'de mi yeniden yazmalıyım?

Performans kazanmak için bunu yapmayacağım, bir yan etki olarak gelebilir, ama fikir neden ihtiyacım yoksa C ++ kullanmalıyım?

Kullandığım C ++ 'ın tek özellikleri veri ve yöntemleri kapsüllemek için sınıflardır, ancak yapı ve işlevlerle de yapılabilir, yeni ve siliyorum, ancak malloc ve ücretsiz de kullanabilirim ve ben mirasın sadece işlevlere işaretçilerle elde edilebilen geri aramalar için kullanılması.

Unutmayın, bu bir hobi projesi, son teslim tarihim yok, bu yüzden yeniden yazma gerektiren genel gider ve iş bir sorun değil, aynı zamanda eğlenceli olabilir. Yani, soru C veya C ++?


3
Görünüşe göre zaten kendinize cevap verdiniz: neden sadece C'ye ihtiyacınız varsa C ++ kullanıyorsunuz? C'nin mükemmel olduğu birçok durum vardır.
Giorgio

3
@Giorgio: Ve hepsi ilk altmış saniyeden sonra buharlaşıyor ve kodunuzu korumanız gerekiyor.
DeadMG

7
I use C++ because is the language I use mostly, know mostly and like mostly.Ve sorunuzun cevabı bu. Dilleri projenin ortasında yalnızca geçerli dilinizin çözemediği bir sorun olduğunda değiştirmelisiniz. I don't use templates, operator overloading, polymorphism, inheritance.Kavramları öğrenmek ve kullanmak için C'ye geçmekten çok daha değerli olurdu. Bu bir hobi projesi olduğundan, neden daha önce kullanmadığınız birkaç şeyi kullanmıyorsunuz? Her zaman C'de başka bir proje başlatabilir ve dili öğrenebilirsiniz, ancak mevcut projeniz için geçiş yapmak mantıklı değildir.
yannis

4
Yazdığım her projede de dilin% 100'ünü kullanmıyorum. C ++ 'ı en iyi bilirsiniz, daha önce kullanmadığınız özellikleri kullanmak için iyi nedenler bulabilirsiniz. Eğer standart kütüphanesi şeyler kullanmaya başlamak ve boost yapılar gibi bir kez, çok daha güvenli C ++ C tedavisinde başlayabilir std::shared_ptr, std::unique_ptr, boost::scoped_ptr, std::vector, std::deque, std::map, sizi, geri arama fonksiyonları vb, functors kullanımına içine göz ve C ++ 11 lambda işlevleri gibi şeyleri kullanmaya da başlayabilir.
wkl

3
@Giorgio: Evet. Sonsuz bağlantılı listenin yuvarlanması gereksiz hatalara neden olur.
DeadMG

Yanıtlar:


40

Artık kullanmadığınızda, ama bir dahaki sefere bellek sızdırıyor veya geri gelmek için yalvarıyor olacağım, çifte silme olsun std::vector<T>, std::unique_ptr<T, Del>ve std::shared_ptr<T>bu sorunların neredeyse trivially kolayca- çözebilir, hangi. Sonunda C ++ üzerinde C kullanan herkese olan budur ve daha akıllı olanlar, hareket etmeden önce hataların ortaya çıkmasını beklemez.

C ++ 'ı kullanan newve deletedoğrudan C ++' a ait olmayan kod, "C Sınıfı" olarak adlandırdığımız bu tür yarım eve aittir. Eğer C öğrenilen her yerde dil 1985 dolaylarında idi yıllardan bu Size sadece bunu maalesef oldukça ortak-ve daha iyi bir eğitim ile çok iyi-şey öğretmek vermedi ++, olasılıkla 2011'de dolaylarında, C ++ özellikle benzer değil olurdu bu özelliklerin kullanımını bulur.

Özellikle, yukarıda listelediğim gibi, C ++ 'ın genel veri yapıları ve kaynak yönetim sınıfları C'nin sunduğu her şeyden temelde büyük ölçüde daha üstündür. Dinamik olarak ayrılmış bir dizi istiyorsanız, kullanın std::vector<T>. Bu oldukça yaygın bir kullanım durumudur. Bunları kullanmıyorsanız, kodunuz gereksiz yere büyük bir hata riski altındadır - özellikle kaynak yönetimi ile ilgili. C ++, güvenliği ve yeniden kullanım kodunu C'nin asla dokunamayacağı şekilde garanti edebilir.

Ancak, çok fazla beklediğinizi de düşünüyorum. Şablon yazma ve operatör aşırı yüklemeleri kütüphane tüketicileri için yaygın değildir. Kodunuz kullanıyorsa std::vector<T>, bunun için bir şablon yazmanız gerekmez . Kodunuz kullanılırsa std::string, kimse sizi operatörlerinizi aşırı yüklemeye zorlamaz. Bunları yazmak için yapmanız yeterlidirstd::vector<T> ve std::stringyine de bunlardan tam olarak yararlanabilirsiniz.

Polimorfizm / kalıtım da sadece belirli bir kullanım durumuna sahiptir. Kodunuz herhangi bir şablon yazmanızı veya sanal işlevleri kullanmanızı gerektirmezse, bunu yapmaz ve kendi şablonlarınızı yazmanız gerekmeyen programlar veya program bölümleri vardır.

Ayrıca, C ++ 'da performansta bir kazanç yoktur.


1
@Giorgio: make_sharedvar ve make_uniqueaynı işi yapan önemsiz bir şablon yazabilirsiniz . Bu daha guvenli.
DeadMG

4
Mükemmel cevap. Kafasına çivi. C ++ her zaman kullanmamız gereken bu küçük kütüphaneler için çok değerlidir.
Andres Jaan Tack

2
@Giorgio: Güvensizdir, çünkü böyle birden fazla argüman çağırırken, istisna durumunda bir bellek sızıntısı alabilirsiniz ve make_shareddaha verimlidir. Yalnızca fabrika fonksiyonları garantili istisna güvenliği sunabilir.
DeadMG

6
@ tp1: WTF? İngilizce lütfen.
DeadMG

2
@Lohoris Sağduyu için bir alıntıya ihtiyacınız yok. C hangi şekilde C ++ 'dan daha iyi performans göstermelidir?
Chris, Reinstate Monica'ya

7

C ++ 'a özgü özellikler kullanmasanız bile, bir C ++ derleyicisi, C ++' ın daha katı tip sistemi nedeniyle C'den daha fazla sorun yakalar.


6

Ona diğer yönden bakardım. Eğer Will kazanmak C kodu yeniden yazarak şey? Tamamen hobici bir projede bile, böyle bir yeniden yazma ile ilişkili bir maliyet var. Başka hiçbir şey varsa, fırsat maliyeti denir - yani, C'de yeniden yazmak için zamanınızı boşa harcamasaydınız, o zaman yapmış olabileceğiniz diğer şeyler .

Alt satır: Kodun C ++ erişiminin gerçekten sınırlı olduğu (veya var olmadığı) bazı ortamlarda kullanılabileceğini düşünmüyorsanız, en iyi ihtimalle anlamsız bir zaman kaybı olacaktır. Tecrübelerime En azından, genellikle çok hızlı bir şekilde bununla da sınırlı kalmıyor - kod ben C ++ ile yazılmış ettik üzerinde düşünme geri vardı C'ye dönüştürülecek, oldukça net bir şekilde hatta neye görünüyordu epeyce durumlarda hatırlayabiliriz önemsiz olmalı, başlangıçta fark ettiğimden çok C ++ 'a özgü çok daha fazla özellik kullanıyordum. Hiç faydalı olma umuduna sahip olmak için, C89 / 90'ı hedeflemeniz gerekir, bu durumda bir bloğun başlangıcında tüm değişkenleri gerçekte oldukları yerine tanımlamak gibi şeyleri hızlı bir şekilde hatırlatırsınız. Kullanılmış.

Kısacası, C'de yeniden yazmanın gerçek bir fayda sağlayacağından emin değilseniz, kaçınılmaz olarak yapılacak daha iyi şeyler vardır.


+1 Bir süre önce başka bir C projesinde kullanılacak bir kütüphane yazmak zorunda kaldım ve o zamana kadar ne kadar aptalca bir aptal olduğumu düşünerek C'de de uygulamak iyi bir fikirdi.
Chris, Reinstate Monica'nın

1

Daha genel bir cevap olarak:

Sadece bazı benzersiz özelliklerini kullandığınız için C ++ 'ya geçmeyin. Bir gün bu özelliklere ihtiyacınız olabilir ve C'yi kullandığınız için sadece başınızı vurursunuz.


1

Hobi uzmanı gelişimi için, düz C'ye geri dönmeyi düşünürüm. C ve C benzeri dillerin küçük hobi geliştirme modüllerinde desteklenmesi daha olasıdır.

Buradaki yanıtların çoğu profesyonel yazılım türlerinden olabilir. Bir hobi olarak, sürekli veya tam zamanlı kodlama yapmayacaksınız. Bu nedenle, projenizi bir yıl boyunca masaya yatırıp geri dönüp kodlamada paslandıktan sonra kodunuzu okumaya çalıştığınızda, hangi dili hatırlama veya tuhaflıkları unutma olasılığınızı düşünün. Daha zengin bir özellik kümesine sahip olan C ++, kodlama stilinize bağlı olarak yeniden edinilmesi daha fazla veya daha az zaman alabilir.


1

Sorularınıza cevap vermek kolay değildir, çünkü dile özgü becerilerinizi geliştirmek için (C ile C ++) veya diğer programlama becerilerini (tasarım, problem çözme vb.) Geliştirmek için proje üzerinde çalışıp çalışmadığınızı bilmiyoruz.

Msgstr "Kullandığım C ++ 'ın tek özellikleri, verileri ve yöntemleri kapsüllemek için sınıflardır, ancak bu yapı ve işlevlerle de yapılabilir." Bu doğru değil. structsC'de kapsüllemeyi desteklemez ve işlev (yöntem) içeremez - en azından işlevlere işaretçiler gibi teknikler kullanmadan. Ayrıca, C'deki işlevler aşırı yüklenemedikleri için zayıftır.

"Ben yeni ve siliyorum, ama malloc ve ücretsiz de kullanabilirsiniz ve miras sadece işlevler için işaretçiler ile elde edilebilir geri aramalar için kullanıyorum." Deadmg'den bahsedildiği gibi, doğrudan newve deleteC ++ 'da kullanılması teşvik edilmez. Ayrıca, OOP'ta IMHO (ve GoF) kalıtımı, sadece polimorfizm gerektiğinde kompozisyona göre tercih edilmelidir. Ve fonksiyonlarda işaretçiler kullanarak C'de polimorfizme (geç bağlanma) ulaşmanın önemsiz olduğunu düşünmüyorum.

Bunun dışında, C ++ 'ın C'den "daha iyi" olduğuna ikna etmeye çalışmayacağım çünkü bu bir tercih meselesidir ve her zaman çözmeye çalıştığınız soruna bağlıdır (NES emülatörünüzü geliştirmek için OOP özelliklerini kullanmak olabilir) iyi bir fikir).


1
structsC de aslında yöntemleri kapsüllemek için kullanılabilir. Sadece bir işlev işaretçileri yapısı oluşturur ve bunları istediğiniz işlevleri işaret edecek şekilde başlatırsınız. Örnek için lxr.linux.no/linux+v3.3/include/linux/fs.h#L1598 adresine bir göz atın .
Robert Martin

Doğru. Yorum için teşekkürler, cevabı uzattım.
sakisk

Güzel. Bir daha nit: C fonksiyonları olabilir (düşünmek aşırı yüklü printf), ancak herhangi bir tür denetlemesi kaybetmek bunu yaparken. Sonlu kabul edilebilir beyanlar kümesine sahip olmanın bir yolu yoktur: ya 1 (ve tip kontrolünü alırsınız) ya da "çok" (ve büyük risk altında tüm tür kontrolünü kaybedersiniz). C'deki çoğu şeyde olduğu gibi, bu mümkün ama genellikle rahatsız edici.
Robert Martin

Fonksiyonlara işaret eden ileri bir C tekniğidir? Gerçekten mi?
Donal Fellows

@DonalFellows Haklısın, abarttım. Gelişmiş kaldırıldı ... :)
sakisk

0

Ben çok acemiyim, işte 2 bitim geliyor.

Bazı güzel temel videotutorials ile Wibit.net C ve C ++ öğreniyorum, belki onlar "durumu" (bir reklam değil) bir bakış almak için çok yardımcı olabilir!

Bir hobici olduğunuz için, bu bir zevk değil, bir problem olacak, C'yi değiştirmenizi tavsiye ediyorum.

Daha çok tavsiye ederim. Her iki dilde de yapın. Bulacağınız ve kullanacağınız çözümleri ve çözümleri karşılaştırın. Eminim beklediğiniz gibi "o kadar kolay" olmayacaktır ... ama çok şey öğreneceksiniz!


1
Çok teşekkür ederim, ama öğrenmiyorum, zaten C ve C ++ biliyorum, bu özel proje için hangisini kullanacağımı soruyorum.
Petruza

ayy, öğrenme zamanı! = P
H_7

1
Ayrıca, video dersleri yerine, Kernigan ve Stroustrup'un kitaplarını, güzel bir IDE'yi (Visual Studio, Eclipse, Xcode) almanızı ve örnekleri, deneme yanılma kodunu yazarak ve stackoverflow'a başvurarak öğrenmenizi tavsiye ederim.
Petruza

-1

İşte C ++ ve C'nin artıları ve eksileri:

  1. C'ye geçmek, seçilen C ++ alt kümesinin içinde kalmayı kolaylaştıracaktır, çünkü derleyici bunun dışına çıktığınızda hata verecektir. Eğer asıl sorun karar verilen alt kümede kalmaksa, bu alternatif seçilmelidir. (bunun için neden derleyici desteğimiz yok?)
  2. Bir kez seçilen c ++ özellik alt kümesi içinde kalabilir, sonra bir sonraki şey, kodu kırmak kötü sözleşmeler kurtulmak için alt kümesini değiştirmek için denemektir. Bu, bütün c ++ 'ın kullanılmasını gerektirir.
  3. Hem "alt kümenin içinde kalmak" hem de "iyi bir alt küme" olduğunda, c ++ özelliklerinin dışına çıkın ve gereksinimler hakkında düşünmeye başlayın.
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.