Başlık dosyaları gerçekten iyi mi? [kapalı]


20

Üstbilgi dosyalarını C ++ kaynak dosyalarına göz atarken faydalı buluyorum, çünkü bir sınıftaki tüm işlevlerin ve veri üyelerinin bir "özetini" veriyorlar. Neden diğer pek çok dilin (Ruby, Python, Java, vb.) Böyle bir özelliği yok? Bu, C ++ 'ın ayrıntılarının işe yaradığı bir alan mı?


C ve C ++ araçlarına aşina değilim, ama çalıştığım çoğu IDE / kod editörleri bir "yapı" veya "anahat" görünümü var.
Michael K

1
Başlık dosyaları iyi değil - gerekli! - Ayrıca SO ile ilgili bu yanıta bakınız: stackoverflow.com/a/1319570/158483
Pete

Yanıtlar:


31

Başlık dosyalarının asıl amacı, C'de tek geçişli derlemeye ve modülerliğe izin vermekti. Yöntemleri kullanılmadan önce bildirerek, sadece tek derleme geçişine izin verdi. Güçlü bilgisayarlarımızın çok geçişli derlemeyi sorunsuz bir şekilde yapabilmesi ve bazen de C ++ derleyicilerinden bile daha hızlı olması nedeniyle bu yaş uzun zaman geçti.

C ++ 'ın C ile geriye dönük olarak uyumlu olması, başlık dosyalarını tutmak için gerekliydi, ancak bunların üzerine çok fazla şey eklendi, bu da oldukça sorunlu bir tasarımla sonuçlandı. FQA'da daha fazlası .

Modülerlik için modüllerde kod hakkında meta veri olarak başlık dosyalarına ihtiyaç duyulmuştur. Örneğin. hangi yöntemler (ve C ++ sınıflarında) hangi kitaplıkta kullanılabilir. Derleyici zaman pahalı olduğu için geliştiricinin bunu yazması açıktı. Günümüzde, derleyicinin bu meta verileri kodun kendisinden üretmesi sorun değil. Java ve .NET dilleri bunu normal şekilde yapar.

Yani hayır. Başlık dosyaları iyi değil. Onlar hala ayrı disketler üzerinde derleyici ve bağlayıcı olması gerekiyordu ve derleme 30 dakika sürdü. Günümüzde, sadece yoluna giriyorlar ve kötü tasarımın işareti.


8
Yazdıklarınızın çoğuna katılıyorum, ancak son paragraf işleri biraz basitleştiriyor. Başlık dosyaları hala genel arayüzleri tanımlamak için yararlı bir amaca hizmet eder.
Benjamin Bannier

3
@honk Sorumla başa çıkıyordum. Ama modern IDE'lerin (ElYusubov tarafından önerildiği gibi) bunu olumsuz yönde etkilediğini düşünüyorum.
Matt Fichman

5
C ++ komitesinin, C ve C ++ 'ın herhangi bir üstbilgi olmadan VEYA daha verimli bir şekilde kullanılan üstbilgiler olmadan çalışmasını sağlayacak Modüller üzerinde çalıştığını ekleyebilirsiniz. Bu, bu cevabı daha adil hale getirecektir.
Klaim

2
@MattFichman: Bir başlık dosyası oluşturmak bir şeydir (çoğu programcının editörleri / IDE'leri bir şekilde otomatik olarak yapabilir), ancak genel bir API ile ilgili konu, gerçek bir insan tarafından etkili bir şekilde tanımlanması ve tasarlanması gerektiğidir.
Benjamin Bannier

2
@honk Evet. Ancak bunun ayrı dosyalarda tanımlanmasına gerek yoktur. Uygulama ile aynı kodda olabilir. Tıpkı C #'ın yaptığı gibi.
Euphoric

17

Bir belge biçimi olarak sizin için yararlı olsalar da, başlık dosyalarını çevreleyen sistem olağanüstü derecede verimsizdir.

C, her derleme geçişinin tek bir modül oluşturacağı şekilde tasarlanmıştır; her kaynak dosya, derleyicinin ayrı bir çalışmasında derlenir. Diğer yandan, üstbilgi dosyaları, bunlara başvuran kaynak dosyaların her biri için bu derleme adımına enjekte edilir.

Bu, başlık dosyanız 300 kaynak dosyasına dahil edilirse, programınız oluşturulurken 300 ayrı kez ayrıştırılır ve derlenir. Tekrar tekrar aynı sonuçla aynı şey. Bu büyük bir zaman kaybıdır ve C ve C ++ programlarının oluşturulmasının bu kadar uzun sürmesinin temel nedenlerinden biridir.

Tüm modern diller kasıtlı olarak bu saçma sapan verimden kaçınırlar. Bunun yerine, genellikle derlenmiş dillerde gerekli meta veriler derleme dosyasının içinde depolanır ve derlenen dosyanın derlenmiş dosyanın ne içerdiğini açıklayan bir tür hızlı arama başvurusu olarak işlev görmesini sağlar. Bir üstbilgi dosyasının tüm avantajları, sizin tarafınızdan ek bir çalışma olmadan otomatik olarak oluşturulur.

Alternatif olarak, yorumlanan dillerde, yüklenen her modül bellekte kalır. Bazı kitaplıklara başvuruda bulunmak ya da bunlara yer vermek ya da bunlara gereksinim duymak, program sona erene kadar yerleşik kalan ilgili kaynak kodunu okur ve derler. Ayrıca başka bir yere gereksinim duyarsanız, zaten yüklendiği için ek bir iş yoktur.

Her iki durumda da, dilin araçlarını kullanarak bu adımda oluşturulan verilere "göz atabilirsiniz". Genellikle IDE bir tür sınıf tarayıcısına sahip olacaktır. Dilin bir REPL'si varsa, genellikle yüklü nesnelerin belge özetini oluşturmak için de kullanılabilir.


5
kesinlikle doğru değil - çoğu olmasa da, derleyiciler başlıkları gördükleri gibi derlerler, böylece bir sonraki derleme birimine dahil etmek, önceden derlenmiş kod bloğunu bulmaktan daha kötü değildir. Diyelim ki, .NET kodu tekrar tekrar derlediğiniz her C # dosyası için system.data.types 'yapı'. C / C ++ programlarının bu kadar uzun sürmesinin nedeni, aslında derlenmiş (ve optimize edilmiş) olmasıdır. Tüm .NET programlarının IL'ye ayrıştırılması gerekir, çalışma zamanı JIT aracılığıyla gerçek derlemeyi yapar. Bununla birlikte, C # kodundaki 300 kaynak dosyasının da derlenmesi biraz zaman alır.
gbjbaanb

7

İşlevler ve veri üyeleri için dosyaya göz atarak ne demek istediğiniz açık değildir. Ancak, çoğu IDE sınıfa göz atmak ve sınıf veri üyelerini görmek için Araçlar sağlar .

Örneğin: Visual Studio vardır Class Viewve Object browsero güzel İstediğiniz işlevsellik sağlar. Aşağıdaki ekran görüntülerinde olduğu gibi.

resim açıklamasını buraya girin

resim açıklamasını buraya girin


4

Üstbilgi dosyalarının ek bir dezavantajı, programın dahil edilme sırasına bağlı olması ve programcının doğruluğunu sağlamak için ek adımlar atması gerektiğidir.

Bu, C'nin makro sistemi (C ++ tarafından miras alınan) ile birleştiğinde birçok tuzağa ve kafa karıştırıcı duruma yol açar.

Bir başlık, kullanımı için makrolar kullanarak bir sembol tanımladıysa ve başka bir başlık, sembolü bir işlev adı gibi başka bir şekilde kullandıysa, dahil etme sırası nihai sonucu büyük ölçüde etkiler. Böyle birçok örnek var.


2

Sınıf değişkenleri gibi bazı ekstra bilgilerle birlikte, görüntülenmesi kolay bir dosyada uygulamaya bir arabirim biçimi sağladığından başlık dosyalarını her zaman sevdim.

Sınıf başına 2 dosya - biri gerçek sınıf uygulama ve başka bir arabirim ile yazılmış C # kodu (sınıf başına 2 dosya gerekmez) bir sürü görüyorum. Bu tasarım alay için iyidir (bazı sistemlerde gereklidir) ve derlenmiş meta verileri görüntülemek için IDE'yi kullanmak zorunda kalmadan sınıfın belgelerini tanımlamaya yardımcı olur. Şimdiye kadar iyi bir uygulama olduğunu söyleyebilirim.

Bu nedenle, C / C ++ üstbilgi dosyalarında bir arabirimin eşdeğerini (çeşit) zorunlu kılmak iyi bir şeydir.

'İki dosyaya bir şeyler koymak zorunda kalırsanız sadece kodu kesmek daha zor' gibi nedenlerle sevmeyen diğer sistemlerin taraftarları olduğunu biliyorum, ama benim tutumum sadece kod kesmek zaten iyi bir uygulama değil ve biraz daha düşünülmüş bir kod yazmaya / tasarlamaya başladığınızda, üstbilgileri / arayüzleri elbette tanımlayacaksınız.


Arayüz ve Farklı Dosyalarda Uygulama? Tasarım gereği buna ihtiyacınız varsa, Java / C # gibi dillerde arayüz (veya soyut sınıf) tanımlamak ve diğer dosyalarda uygulamaları gizlemek hala çok yaygındır. Bu, eski ve zor başlık dosyaları gerektirmez.
Petter Nordlander

ha? söylediğim gibi değil - arayüzü ve sınıf uygulamasını 2 dosyada tanımlarsınız.
gbjbaanb

2
başlık dosyaları gerektirmez ve başlık dosyalarını daha iyi yapmaz. Evet, mirası olan dillerde gereklidir, ancak bir kavram olarak arayüz / uygulamayı farklı dosyalara bölmek gerekmez (aslında, daha da kötüleştirir).
Petter Nordlander

@Petter yanlış anladığınızı düşünüyorum, kavramsal olarak farklı değiller - C dilinde bir arayüz sağlamak için bir başlık var ve haklı olsanız da - 2'yi (yalnızca başlık C koduyla olduğu gibi) bir birçok yerde izlediğim en iyi uygulama. Gördüğüm tüm C # geliştiricileri, arabirimi sınıftan ayırdı. Bu, arayüz dosyasını kirlilik olmadan diğer birçok dosyaya dahil edebileceğiniz gibi yapmak için iyi bir uygulamadır. Şimdi, eğer bu bölünmenin en iyi uygulama olduğunu düşünüyorsanız (C) o zaman onu C'de elde etmenin yolu başlık dosyalarını kullanmaktır.
Ocak 14:55

Üstbilgiler arayüz ve uygulamayı ayırmak için gerçekten yararlı olsaydı, özel bileşenleri gizlemek ve son kullanıcıları bunlara karşı derlemek zorunda kalmamak için PImpl gibi şeylere gerek kalmazdı. Bunun yerine, her iki dünyanın en kötüsünü alıyoruz. Üstbilgiler, hızlı bir şekilde işten çıkarılmış bir ayrım cephesini sayarken, etraflarında çalışmanız gerekiyorsa, ayrıntılı demirbaş kodu gerektiren sayısız tuzak açar.
underscore_d

1

Aslında, üstbilgi dosyalarının harika olmadığını söyleyebilirim çünkü arayüz ve uygulamayı çamurluyorlar. Genel olarak programlama ve özellikle OOP ile ilgili amaç, tanımlanmış bir arayüze sahip olmak ve uygulama ayrıntılarını gizlemektir, ancak bir C ++ başlık dosyası size hem yöntemleri, kalıtım, hem de genel üyelerin (arayüz) yanı sıra özel yöntemleri ve özel üyeleri gösterir (uygulamanın bir kısmı). Bazı durumlarda, üstbilgi dosyasında satır içi kod veya yapıcılarla sonuçlandığınızı ve bazı kütüphanelerin başlıklarda şablon kodunu içerdiğini ve uygulamayı gerçekten arayüzle karıştırdığından bahsetmiyoruz.

Asıl niyet, bence, kodun, komut dosyasının tüm içeriğini içe aktarmak zorunda kalmadan diğer kütüphaneleri, nesneleri vb. Kullanmasını sağlamaktı. Tek ihtiyacınız olan derleme ve bağlantı için başlık. Zaman kazandırır ve bu şekilde döngü yapar. Bu durumda, bu iyi bir fikir, ancak bu sorunları çözmenin sadece bir yolu.

Programın yapısına göz atmaya gelince, çoğu IDE bu yeteneği sağlar ve kapakların altında neler olduğunu görebilmeniz için arayüzleri başlatacak, kod analizi, kod çözme vb. Yapacak birçok araç vardır.

Diğer diller neden aynı özelliği uygulamıyor? Çünkü diğer diller diğer insanlardan geliyor ve bu tasarımcıların / yaratıcıların işlerin nasıl çalışması gerektiği konusunda farklı bir vizyonu var.

En iyi cevap, yapmanız gereken işi yapan ve sizi mutlu eden şeylere bağlı kalmaktır.


0

Birçok programlama dilinde, bir program birden fazla derleme birimine ayrıldığında, bir birimdeki kod yalnızca derleyicinin bu şeylerin ne olduğunu bilmek için bazı araçları varsa başka bir tanede tanımlanan şeyleri kullanabilecektir. Bir derleme birimini işleyen bir derleyicinin, mevcut birim içinde kullanılan herhangi bir şeyi tanımlayan her bir derleme biriminin tüm metnini incelemesini istemek yerine, derleyicinin her bir birimi işlerken derlenecek birimin tam metnini alması en iyisidir. diğerlerinden küçük bir bilgi ile.

C'de, programcı her birim için iki dosya oluşturmaktan sorumludur - biri sadece bu birimi derlerken ihtiyaç duyulacak bilgileri içerir ve diğeri diğer birimleri derlerken de gerekli bilgileri içerir. Bu oldukça kötü, hacky, bir tasarımdır, ancak derleyicilerin ara dosyaları nasıl üretmesi ve işlemesi gerektiği hakkında bir dil standardına sahip olma ihtiyacını ortadan kaldırır. Diğer birçok dil farklı bir yaklaşım kullanır, burada bir derleyici her kaynak dosyadan dış kod tarafından erişilebilir olması gereken kaynak dosyadaki her şeyi açıklayan bir ara dosya oluşturur. Bu yaklaşım, iki kaynak dosyada yinelenen bilgilere sahip olma ihtiyacını ortadan kaldırır, ancak bir derleme platformunun dosya semantiğini C için gerekli olmayan bir şekilde tanımlamasını gerektirir.

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.