Gerçek şu ki, C ++ 'da bu, C başlığı / kaynak organizasyonundan biraz daha karmaşıktır.
Derleyici ne görüyor?
Derleyici, başlıkları düzgün şekilde dahil edilmiş büyük bir kaynak (.cpp) dosyası görür. Kaynak dosya, bir nesne dosyasına derlenecek derleme birimidir.
Öyleyse, başlıklar neden gerekli?
Çünkü bir derleme birimi, başka bir derleme birimindeki bir uygulama hakkında bilgiye ihtiyaç duyabilir. Dolayısıyla, örneğin bir işlevin bir kaynakta gerçekleştirilmesi yazılabilir ve bu işlevin bildirimi, onu kullanmak isteyen başka bir kaynakta yazılabilir.
Bu durumda, aynı bilginin iki kopyası vardır. Hangisi kötü ...
Çözüm, bazı ayrıntıları paylaşmaktır. Uygulamanın Kaynakta kalması gerekirken, işlevler gibi paylaşılan sembollerin beyanı veya yapıların, sınıfların, numaralandırmaların vb. Paylaşılması gerekebilir.
Başlıklar, bu paylaşılan ayrıntıları koymak için kullanılır.
Başlığa, birden çok kaynak arasında nelerin paylaşılması gerektiğine dair bildirimleri taşıyın
Daha fazlası yok mu?
C ++ 'da, başlığa eklenebilecek başka şeyler de vardır çünkü bunların da paylaşılması gerekir:
- satır içi kod
- şablonlar
- sabitler (genellikle anahtarların içinde kullanmak istedikleriniz ...)
Paylaşılan uygulamalar da dahil olmak üzere paylaşılması gereken HER ŞEYi başlığa taşıyın
Bu, başlıkların içinde kaynaklar olabileceği anlamına mı geliyor?
Evet. Aslında, bir "başlık" içinde olabilecek (yani kaynaklar arasında paylaşılan) pek çok farklı şey vardır.
- İleri beyanlar
- bildirimler / işlevlerin / yapıların / sınıfların / şablonların tanımı
- satır içi ve şablonlu kodun uygulanması
Karmaşık hale gelir ve bazı durumlarda (semboller arasındaki döngüsel bağımlılıklar) tek başlıkta tutulması imkansız hale gelir.
Başlıklar üç bölüme ayrılabilir
Bu, aşırı bir durumda şunlara sahip olabileceğiniz anlamına gelir:
- ileri bildirim başlığı
- bir bildirim / tanım başlığı
- bir uygulama başlığı
- bir uygulama kaynağı
Bir MyObject şablonumuz olduğunu hayal edelim. Sahip olabilirdik:
template<typename T>
class MyObject ;
.
#include <MyObject_forward.hpp>
template<typename T>
class MyObject
{
public :
MyObject() ;
} ;
void doSomething() ;
.
#include <MyObject_declaration.hpp>
template<typename T>
MyObject<T>::MyObject()
{
doSomething() ;
}
.
#include <MyObject_implementation.hpp>
void doSomething()
{
} ;
Vaov!
"Gerçek hayatta", genellikle daha az karmaşıktır. Çoğu kodun, kaynakta bazı satır içi kodlarla birlikte yalnızca basit bir başlığı / kaynak kuruluşu olacaktır.
Ancak diğer durumlarda (birbirini tanıyan şablonlu nesneler), bazı derleme hatalarını görmeme yardımcı olmak için her nesne için ayrı bildirim ve uygulama başlıklarına sahip olmak zorunda kaldım, bu başlıkları içeren boş bir kaynak.
Başlıkları ayrı başlıklara bölmenin bir başka nedeni, derlemeyi hızlandırmak, gerekli olan katı ile ayrıştırılan simgelerin miktarını sınırlamak ve bir satır içi yöntem uygulaması değiştiğinde yalnızca ileri bildirime önem veren bir kaynağın gereksiz yeniden derlenmesinden kaçınmak olabilir.
Sonuç
Kod organizasyonunuzu hem olabildiğince basit hem de olabildiğince modüler yapmalısınız. Kaynak dosyaya mümkün olduğunca çok koyun. Yalnızca paylaşılması gerekenleri başlıklarda gösterin.
Ancak şablonlu nesneler arasında döngüsel bağımlılıklarınız olacağı gün, kod organizasyonunuz, düz başlık / kaynak organizasyonundan biraz daha "ilginç" hale gelirse şaşırmayın ...
^ _ ^