Soru C ++ kodu başlıksız yazabilir miyim (tekrarlayan fonksiyon bildirimleri)?


İşlev bildirimlerini iki kez (üstbilgiler) yazmak zorunda kalmamak ve C ++ programlamasında tasarımda derleme, hata ayıklamada ve esneklikte aynı ölçeklenebilirliği korumak için herhangi bir yol var mı?


51
2018-06-16 13:55


Menşei


@ nOrd ... veya modüller (n2073) son olarak dilde kabul edilecektir - David Rodríguez - dribeas


Cevaplar:


kullanım Lzz. Tek bir dosya alır ve doğru yerde tüm beyanlar / tanımlar ile sizin için otomatik olarak bir .h ve .cpp oluşturur.

Lzz gerçekten çok güçlüdür ve şablonlar, uzmanlıklar vb. Dahil olmak üzere tam C ++ sözdiziminin% 99'unu kullanır.

150120 güncelleyin:

Daha yeni C ++ '11 / 14 sözdizimi yalnızca Lzz işlev gövdelerinde kullanılabilir.


55
2018-06-16 14:18



+1: Aslında, lzz tasarlandı iyi Etrafında: C ++ üreten bir kaynak dil olarak. - Steve Schnepp


C yazmaya başladığımda da aynı şekilde hissettim, bu yüzden buna da baktım. Cevap, evet, mümkün ve hayır, istemiyorsun.

İlk önce evet.

GCC’de bunu yapabilirsiniz:

// foo.cph

void foo();

#if __INCLUDE_LEVEL__ == 0
void foo() {
   printf("Hello World!\n");
}
#endif

Bu, istenen etkiye sahiptir: hem üstbilgiyi hem de kaynağı, hem dahil edilebilecek hem de bağlantılı olabilecek bir dosyaya birleştirirsiniz.

Sonra hayır:

Bu yalnızca derleyicinin tüm kaynağa erişimi varsa çalışır. Dağıtmak istediğiniz ancak kapalı kaynak tuttuğunuz bir kitaplığı yazarken bu numarayı kullanamazsınız. Ya tam .cph dosyasını dağıtın ya da .lib ile gitmek için ayrı bir .h dosyası yazmalısınız. Yine de, makro önişlemci ile otomatik olarak üretebilirsiniz. Yine de kıllı olurdu.

Ve sebep # 2 neden bunu istemiyorsunuz, ve bu muhtemelen en iyisi: derleme hızı. Normalde, C kaynakları dosyaları sadece dosyanın kendisi değiştiğinde veya içerdiği dosyaların herhangi biri değiştiğinde yeniden derlenmelidir.

  • C dosyası sık sık değişebilir, ancak değişiklik yalnızca değiştirilen bir dosyayı yeniden derlemeyi içerir.
  • Üstbilgi dosyaları arayüzleri tanımlar, bu yüzden sık sık değiştirmemeleri gerekir. Ancak ne zaman yaparlarsa, bir derlemeyi tetiklerler her kaynak dosya onları içerir.

Tüm dosyalarınız başlık ve kaynak dosyaları birleştirildiğinde, her değişiklik tüm kaynak dosyaların bir derlemesini tetikleyecektir. C ++ şu an bile hızlı derleme süreleriyle bilinmemektedir, tüm projenin her seferinde yeniden derlenmesi gerektiğinde ne olacağını hayal edin. Ardından bunu, karmaşık kaynaklara sahip yüzlerce kaynak dosyadan oluşan bir projeye hazırlayın ...


36
2018-06-16 14:12



Üstbilgi dosyaları C'de gerçekten iyi çalışır, buna katılıyorum. Ama C ++’da her zaman mantıklı değiller. Örneğin, bir sınıf beyannamelerinde özel yöntemleri beyan etmek çok mantıklı değildir. Dış dosyaları etkilemeden istediğiniz kadar özel yöntem tanımlayabilmeniz gerekir. - Zelenova


Üzgünüz, ancak C ++ başlıklarını ortadan kaldırmak için "en iyi uygulama" diye bir şey yoktur: Kötü bir fikir, dönem. Onlardan çok nefret ederseniz, üç seçeneğiniz vardır:

  • C ++ internals ve kullanmakta olduğunuz derleyiciler ile yakından tanıdık olun; ortalama C ++ geliştiricisinden farklı sorunlarla karşılaşacaksınız ve muhtemelen çok fazla yardım almadan bunları çözmeniz gerekecek.
  • Depresyonda olmadan "doğru" kullanabileceğiniz bir dil seçin
  • Onları sizin için üretmek için bir araç alın; Hala üstbilgiye sahip olacaksınız, ancak yazarak biraz çaba harcıyorsunuz

27
2018-06-16 14:07



-1 Burada bir cevapta bahsedilen lzz-aracı, tarif ettiğiniz olumsuz etkiler olmaksızın "asker" in ima ettiği problemleri çözmektedir (lzz-aracı başlık kullanmaktadır. Aslında bunları yazmak zorunda değilsiniz). Bu, bu cevabı rekonstrüktif yapar. sry. - 0scar
Doğru tespit. 3. seçeneği kabul edeceğim - kusurun açıklanması için teşekkürler. - ojrac
Muhtemelen küçültüldü, çünkü bu, nonspesifik (örneğin "cehennem problemleri") ve dolayısıyla işe yaramazdı. Üstelik, kaydettiğiniz gibi, bu bir görüş ve bu nedenle, bu toplulukta genellikle yararsız olan özneldir. - weberc2
@ weberc2 Tamamen haklısınız - teşekkürler. Nokta 1'i daha az "ateş ve kenar taşı" olmak üzere güncelledim ve daha çok ayrıntılara odaklandım. - ojrac
@ojrac, Sorun değil. :) Ben C ++ (başlık dosyaları gibi diğer şeylerin) ile sorunun bir parçası olduğunu düşünüyorum tüm özellikleri doğru onları almak için sıkı disiplin gerektirir. Örneğin, PIMPL deyimini uygulamıyorsanız, başlıklar bir acıdır, ancak PIMPL deyimiyle, aslında Adalet özelliklerine benzemektedirler, bunlar gerçekten değerlidir. Çoğu dilden farklı olarak, C ++ sizi en iyi uygulama / geçici çözümü açıklayana kadar yanlış şeyi yapmaya (örneğin, başlık dosyalarındaki özel yöntemleri yayınlamaya) zorlar - ve hatta o zaman onlara bağlı kalmanız size kalır - derleyiciden yardım almayın. - weberc2


Yazısında C ++ 'da Sözleşme ile Tasarım için Basit DestekPedro Guerreiro şunları söyledi:

Genellikle, bir C ++ sınıfı iki gelir   dosyalar: başlık dosyası ve   tanım dosyası. Nerede yazmalıyız   iddialar: başlık dosyasında,   çünkü iddialar şartname midir?   Ya da tanım dosyasından beri   çalıştırılabilir Ya da her ikisinde de   tutarsızlık riski (ve   kopyalama işi) Öneririz,   bunun yerine, biz   geleneksel tarzı ve uzaklaşmak   tanım dosyası, sadece   başlık dosyası, sanki tüm işlevlermiş gibi   Java gibi çok satır içi tanımlanmış   ve Eyfel yap.

Bu çok sert   C ++ normalliğinden değiştir   çabaları öldürme riskleri   başlangıç. Diğer yandan,   Her sınıf için iki dosya çok   garip, er ya da geç bir C ++   geliştirme ortamı ortaya çıkacak   bunu bizden gizleyen, bize izin veren   sınıflarımıza konsantre olmak,   nerede oldukları konusunda endişelenmek   saklanmış.

Bu 2001 oldu. Şu anda 2009 ve hala "bunu bizden saklayan, bizim sınıflarımıza konsantre olmamıza izin veren bir kalkınma ortamı" ortaya çıkmadı. Bunun yerine, uzun derleme süreleri normdur.


Not: Yukarıdaki bağlantı şu anda ölü gibi görünüyor. Bu, yayınlarda göründüğü gibi yayının tam referansıdır. Yayınlar yazarın web sitesinin bölümü:

Pedro Guerreiro, C ++ 'da Sözleşme ile Tasarım için Basit Destek, TOOLS USA 2001, Bildiriler, sayfalar 24-34, IEEE, 2001.


10
2018-06-16 14:10



Benim deneyimimde C # C ++ daha hızlı derler ve bağımlılık denetimi (en az VS2008) çok daha iyi. - Mark Lakata
C ++ ağrı gerektirmeyen birçok dil var. Kişisel favorilerimden biri ol. - weberc2
@MarkLakata - Sorun, sistemdeki tüm kaynakları daha hızlı bir şekilde derleme değil. Sorun şu ki, bir sınıf uygulamasının ayrıntılarını düzenlerseniz ve büyük bir programdaki her sınıf bu sınıfa bağlıysa, C ++ ile yalnızca bir .cpp dosyasını yeniden derlemek ve bir ayrıştırma sistemi olmayan bir sistemle yeniden bağlantı kurmak zorundayım. muhtemelen yeniden derlemek zorunda her şey. - T.E.D.
@ T.E.D. - Evet doğru. Ancak Visual Studio C # kütüphanesi SO'yu C ++'dan çok daha hızlı bir şekilde derler, gerçekten önemli değil. Buna ek olarak, yeni bir uygulama geliştirirken, üstbilgi dosyalarını sürekli olarak değiştiriyorsunuz, böylece C ++ ile bile çok şey derliyor olacaksınız. Göstermek için bir ölçüt yok, ama C # derlemesini C ++'dan 10-20X daha hızlı olacak şekilde tahmin ediyorum. Buna ek olarak, Visual Studio C # sözdizimi derlemesini gerçek zamanlı olarak yapar (yazım denetimi gibi), böylece bitene kadar nadiren derleme düğmesine basmanız gerekir. - Mark Lakata
Bu yüzden, sadece sizin için işleri otomatik olarak ayıran bir sistem kuruyorsunuz. 2013. C ++ onyıllar geçti ve araçlar bu kadar ilerlemedi mi? İşte bu yüzden mühendisiz! İşleri otomatikleştirmek için! - phreakhead


Başlıkların etrafında dolaşmanın pratik bir yolu yoktur. Yapabileceğiniz tek şey, tüm kodu bir büyük c ++ dosyasına koymaktır. Bu, umairilemez bir karmaşaya dönüşecek, lütfen bunu yapma.

Şu anda C ++ başlık dosyaları bir nessesary kötülüktür. Onları sevmiyorum, ama onların etrafında hiçbir yolu yoktur. Yine de, sorunla ilgili bazı iyileştirmeler ve yeni fikirler görmeyi çok isterim.

Btw - buna alıştıktan sonra değil o artık kötü .. C ++ (ve diğer herhangi bir dil) daha fazla anoying şeyler var.


8
2018-06-16 13:59



Aslında, "bir büyük c ++ dosyası" çözümünüz biraz kullanarak ayrıştırılabilir #includes. Bunlar ayrı ayrı derlenmiş kaynak dosyaları için "başlık" olmak zorunda değildir (böylece karışıklığı önlemek / kolaylaştırmak için bunları .cpp olarak adlandırabilirsiniz). Onun kötü IMHO, ama bunu gördüm. - T.E.D.


Senin gibi bazı insanlar gördüğüm şey yazmak her şey başlıklarda. Bu, sadece metod profillerini bir kere yazmak zorunda kalman için arzu ettiğiniz mülkiyeti verir.

Şahsen ben beyanı ve tanımı ayırmak için daha iyi olduğunu çok iyi nedenler olduğunu düşünüyorum, ama bu sizi üzdüğünde, ne istediğinizi yapmak için bir yol var.


8
2018-06-16 14:07





Fonksiyonu yazmalısın deklarasyon iki kez, aslında (bir kez başlık dosyasında, bir kez uygulama dosyasında). Fonksiyonun tanımı (AKA uygulaması), uygulama dosyasında bir kez yazılacaktır.

Tüm kodları başlık dosyalarına yazabilirsiniz (aslında C ++'da genel programlamada çok kullanılan bir uygulamadır), ancak bu başlık dahil olmak üzere her C / CPP dosyasının, bu başlık dosyalarından uygulamanın yeniden derlenmesini ima ettiği anlamına gelir.

C # veya Java'ya benzer bir sistem düşünüyorsanız, C ++ 'da mümkün değildir.


5
2018-06-16 13:59



"Bu, bu başlığı içeren her C / CPP dosyasının, bu üstbilgi dosyalarından uygulamanın yeniden derlenmesini ima edeceğini ima eder." Aslında tüm kodunuz başlıklardaysa daha küçük bir problemdir, çünkü derlenecek tek bir cpp dosyasına sahip olursunuz. Yani büyük bir derlemeniz olacak, ama en azından bir tane olacak. Header cehennemindeki tipik C ++ projesinde, her biri daha fazla iş için başlık kodlarının çoğunu veya tamamını derleyen birçok cpp dosyası vardır. - Steve Jessop
Tamam. Pahalı olarak haklısın. Ancak, yüzlerce veya binlerce çeviri biriminiz varsa, bunları bir çeviri birimi (dosya içerme yoluyla) yapmaya çalışmak bir kabus olacaktır. Bu şekilde asla denemem. - Cătălin Pitiș
teşekkürler, beyanı / tanımı ile karıştırmayı düzeltildi. - thewreck
@onebyone: ama eğer tüm kodlarınızı ehaderlere yazıyorsanız ve tek bir cpp'den içeriyorsanız, o zaman sadece tek bir çeviri üniteniz var ve ehader'lerden herhangi birini değiştirmek, kodları başlıklar arasında düzgün bir şekilde bölerseniz yeniden derlenmesini gerektirir. cpp dosyaları, daha sonra sadece değiştirilen çeviri birimleri yeniden derlenmelidir. - Dan
@Dan: İyi nokta. Neden unuttuğumu merak ediyorum. Bu en açık neden :-) - Cătălin Pitiș