C ++ başlık dosyalarından nefret edersem ne yapmalıyım?


25

Başlık dosyaları hakkında her zaman kafam karıştı. Çok garipler: .cpp içermeyen.

Son zamanlarda bir takım projesine katıldım ve tabii ki, hem .h hem de .cpp kullanıldı.
Bunun çok önemli olduğunu biliyorum, ancak sahip olduğumuz her bir sınıftaki her bir fonksiyon bildirimini kopyalayıp yapıştırarak yaşayamam.

2-dosya kuralını verimli bir şekilde nasıl idare ederim?
Buna yardımcı olacak veya aşağıdaki gibi görünen bir dosyayı otomatik olarak .h ve .cpp olarak değiştirecek herhangi bir araç var mı? (özellikle MS VC ++ 2010 için)

class A
{
...
    Type f(Type a,Type b)
    {
        //implementation here, not in another file!
    }
...
};

Type f(Type a)
{
     //implementation here
}
...

8
Bu soru birkaç yoldan gidebilir. "Neden c ++ kullanırken başlıklara ihtiyacımız var" ya da "Derlenmesi gereken modern bir dilin başlık kullanması gerektiğini düşünüyor musunuz?" Olduğu gibi, bayrakların bolluğunu ortaya çıkaran başlıkta “Ne yaparım” ve “nefret” i vardır
Tim Post

4
Sorunuz C ++ 'ı anlamadığınız gibi görünüyor ya da hangi sistemi kullanırsanız kullanın. Düzgün kullanmayı öğrenin ve daha öznel sorular sorun.
David Thornley

31
İlk cümleniz "başlıklar hakkında her şeyi anlamadığınızı" gösterir. Bir .h dosyasının dahil edilmesi, karşılık gelen .cpp dosyasının "bir şekilde de derlenmiş" olmasına neden olmaz. .Cpp dosyalarını kendi başlarına bağımsız olarak derlersiniz. Karşılık gelen .cpp dosyasını derlemediyseniz, karşılık gelen nesne dosyası olmayan bir başlığın eklenmesi, bağlayıcının başarısız olmasına neden olur.
Paul Butcher

5
Ne yapalım? Seni bu kadar sıkarsa başka bir dil bul.
Paul Nathan,

5
"Kopyala yapıştırma ile yaşayamaz" hakkında: Her biri bir işlevi güncellediğinde, yine de çağrıldığı tüm yerleri güncellemek zorunda. Arayanlar başlık dosyasındaki beyandan daha zor bulduklarından, başlığın güncellenmesi çok küçük bir ayrıntıdır.
Sjoerd

Yanıtlar:


15

Refactoring Friendly C ++ ile daha fazlası

C ++ sen yok olması hiç başlıklarını kullanmak. Tüm nesneyi tıpkı C # veya Java ile olduğu gibi tek bir dosyada tanımlayabilirsiniz. C geliştiricileri genellikle dış aramaları yalnızca bir başlık dosyasında tutar. Tüm dahili çağrılar .c dosyasında tanımlanır. Aynı şekilde, C ++ .h dosyalarınızı sınıflar / arayüzler (salt sanal soyut sınıflar) / etc için saklayabilirsiniz. DLL dışında paylaşılması amaçlanmıştır. Dahili sınıflar / yapı / arayüz vb. İçin ihtiyacınız olan .cpp dosyasını eklemelisiniz:

#include<myclass.cpp>

Bu en popüler yaklaşım gibi görünmüyor, ancak yasal C ++. Kesinlikle tüm dahili kodunuz için bir olasılık olurdu. Bu, kütüphanenizin / çalıştırılabilir kodun dışındaki kod için etkileşimde bulunmak için daha kararlı bir arabirim sağlarken, iç kodun ve sınıfların kümesinin çok daha radikal bir şekilde değişmesini sağlar.

Tüm sınıfınızı bir dosyada bulundurmak, istediğinizi yapmayı kolaylaştıracaktır. Bir yöntemi yeniden adlandırmak ve yöntemin çağrıldığı her yeri araştırmak zorunda kalmaz, ancak daha anlaşılır hata mesajlarınız olduğundan emin olur. Başlığınızın bir yöntemi bir yöntem olarak bildirmesinden daha kötü bir şey yoktur, ancak bunu farklı şekilde uygularsınız. Başlık dosyasını çağıran diğer kod düzgün bir şekilde derlenecek ve bir bağlantı istisnası alacaksınız, uygulama dosyası ise yöntemin tanımlanmadığından şikayet eden dosya olacak. Uygulanan her yöntemi (gerçek sınıf bildiriminde) tanımladığınızda, hangi dosyayı içerdiğinden bağımsız olarak aynı hata iletisini alırsınız.

Bu soruya da bakmak isteyebilirsiniz: C ++ için iyi refactoring araçları

C / C ++ Başlık / Uygulama Dosyalarını Nasıl Çözer?

Temel C düzeyinde (ve C ++ bu temel üzerine kuruludur), başlık dosyaları bir derleyicinin nesne dosyasını yaratmasına izin verecek bir fonksiyon / struct / değişken vaadini ilan eder . Benzer şekilde C ++ üstbilgi dosyaları, işlevlerin, yapıların, sınıfların vb. Vaadini ilan eder.

.C veya .cpp dosyaları uygulamaya sahiptir. Derleyici, her uygulama dosyasını bir nesne dosyasına dönüştürdüğü için, uygulanmayan kavramlara (başlıkta belirtilenler) kancalar vardır. Bağlayıcı, kancaları diğer nesne dosyalarındaki uygulamalara bağlar ve tüm kodu (paylaşılan kitaplık veya çalıştırılabilir) içeren daha büyük bir ikili dosya oluşturur.

Özel VS

Visual Studio'dakilerle çalışmak için işleri biraz daha kolaylaştıracak bazı sihirbazlar var. Yeni sınıf sihirbazı eşleşen başlık ve uygulama dosyalarınızı oluşturacaktır. Yeni yöntemler bildirmenize izin verecek bir sınıf tarayıcı özelliği bile var. Başlıktaki tanımı ve .cpp dosyasındaki uygulama saplamasını enjekte edecektir. Visual Studio, bu özelliklere on yıldan fazla bir süredir (kullandığım sürece) sahiptir.


Sorun şu ki, sınıfları sürekli değiştiriyorum, sadece yeni fonksiyonlar eklemiyorum, vs.
Oleh Prypin

5
@BlaXpirit: Peki, neden sürekli sınıfları değiştiriyorsunuz? OO tasarımının ardındaki fikirlerden biri oldukça istikrarlı yapı taşlarının bulunmasıdır. Sınıfları yoğun şekilde değiştiriyor olsaydım, Common Lisp ya da Python gibi daha dinamik bir dil istiyorum.
David Thornley

2
Ben de öyle yapıyorum. "Yapı taşlarını" geliştiriyorum / değiştiriyorum ve yenilerini ekliyorum
Oleh Prypin

C ++ hiçbir zaman dostça bir refactoring olmamıştır. Yeniden düzenleme kavramı, Java IDE'lerde yapmayı gerçekten kolaylaştıran araçlar bulunana kadar hız kazanmadı. NOT: bu özellikler Smalltalk geliştiricileri ve diğer diller için mevcuttu, ancak pek çok insan için mevcut olana kadar genel değildi. Şimdiye kadar C ++ için bunu akıllıca yapan birini görmedim. Belki JetBrains'ten Resharper? C # ve VB kodları olduğunu biliyorum, ancak size C ++ refactoring vereceklerinden emin değilim.
Berin Loritsch

@Berin: Bir veya iki yıl önce C ++ yeniden düzenleme araçlarını aramaya başladım ve iki şey buldum. O zamanlar oldukça pahalıydı ve deneme sürümlerini görmedim, bu yüzden ne yaptıklarını bilmiyorum. Dahası, yalnızca bir Visual Studio mağazasındaki etkinliğini sınırlayacak olan emacs ile çalıştı.
David Thornley

13

Bir Java geliştiricisi olun.

Gerçekten C ++ ile geliştirmeye devam etmek zorundaysanız, bir IDE kullanmayı deneyebilirsiniz. Genellikle bir sınıfa bir yöntem ekleyebileceğiniz bazı mekanizmalar sunarlar ve bildirimi otomatik olarak .h dosyasına ve tanımı .cpp dosyasında yerleştirir.


2
kthx, biraz Java biliyorum ama onunla düşük seviyeli Win32 DLL dosyaları yapamazsınız, değil mi?
Oleh Prypin

41
Nedenini bilmiyorum ama 'Java geliştiricisi ol' bir şekilde hakaret gibi geliyor: D.
Oliver Weiler,

2
Düşük seviye yapmak istiyorsanız, 'kolay diller' ile ilgili her şeyi unutun. Düşük seviye ter ve gözyaşı maliyeti.
Batibix

5
Özellikle yararlı bir cevap değil.
ChrisF

1
@OliverWeiler "Java geliştiricisi haline gelmek" hakaret olarak algılanmıyor. Hem C ++ hem de Java programlarım, ancak şu ana kadar tercihim Java. Çünkü çalışan ve (ve daha taşınabilir) çalışan bir kod yazıp oturmak çok daha kolay. Herhangi bir nedenden dolayı başlık dosyalarının varlığını göz ardı ederseniz, Java'yı denemek doğru seçim olabilir (başlık dosyalarından nefret etmenize rağmen garip; IDE'de bir değişiklik düşünebilirim).
Trixie Wolf,


4

Yeni bir sınıfın ilk satırlarını yazdığınızda, bunun nedeni genellikle o zaman bir yerde ihtiyaç duymanızdır. Daha sonra, daha fazla yerde kullanılabilir, ancak başlangıçta genellikle değildir.

Sınıflarımın çoğu geçerli .cpp dosyasının en üstünde başlar. Birden fazla yerde kullanmak için yeterince stabilize olduğunda, onu bir başlığa kesip yapıştırırım. Sık sık, sınıf göründüğü kadar hızlı kaybolur.


-1

C ++ üstbilgi dosyalarını işlemenize yardımcı olacak bir öneri olarak, "GCC" kitaplıkları gibi dosya uzantısı veya dosya soneki olmadan bunları kullanmak yaygındır.

Bu durumda, bir " .hpp" (veya unleast " .hxx") dosya uzantısı veya dosya soneki kullanmanızı öneririm .

Derleyicinizi, geliştirici ortamınızı veya Yapılmış programınızı yapılandırmanız gerekebilir.


3
Nasıl bir dosya ekleyeceğinizden mi bahsediyorsunuz #include <iostream>? Bunlar sadece GCC kütüphanesi için değil. Aslında, 1997 C ++ standardında tanımlanmıştır , bölüm 17.3.1.2. Böyle dosyaları adlandırmaktan kaçınırdım. Yapabilirsiniz, ancak C ++ standart kütüphanesinin bunu yapmasının sebebi muhtemelen adlandırma çakışmalarını engellemekti. Bir başlık eklediğinizde derleyiciler otomatik olarak '.h' eklediğinde gerçekten çok garip buluyorum, bana oldukça standart görünüyor. Ve c ++ standart kütüphanesi haricinde hiç kimsenin isim başlığını sonek olmadan göremiyorum.
vedosity

1
Ayrıca, kullandığım tüm derleyicilerin (çok fazla nefret ettiğim) borland dışında, denemeye çalıştığınızda otomatik olarak '.h' veya '.hpp' veya '.hxx' eklemediğini unutmayın. soneksiz bir dosya eklemek için. Tüm derleyicilerde #include <someclass>olduğu gibi okunmasını beklemeyin #include <someclass.hpp>. Kodunuz kırılacak.
vedosity
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.