Neden C ++ 'da ileri bildirim gerekli?
Derleyici, yazım hataları yapmadığınızdan veya işleve yanlış sayıda argüman iletmediğinizden emin olmak istiyor. Bu nedenle, kullanılmadan önce bir 'add' (veya başka türler, sınıflar veya işlevler) bildirimi gördüğünde ısrar eder.
Bu gerçekten derleyicinin kodu doğrulamak için daha iyi bir iş yapmasına izin verir ve düzgün görünümlü bir nesne dosyası oluşturabilmesi için gevşek uçları toplamasına izin verir. Bir şeyleri iletmek zorunda kalmazsanız, derleyici 'add' fonksiyonunun ne olabileceğine dair olası tüm tahminler hakkında bilgi içermesi gereken bir nesne dosyası üretir. Bağlayıcının, aslında 'hangi' ekleme 'çağırmayı denemek ve çözmek için çok zekice bir mantık içermesi gerekir,' add 'işlevi farklı bir nesne dosyasında yaşıyorsa, linker üretmek için add kullanan biriyle birleşiyorsa bir dll veya exe. Bağlayıcının yanlış eklentiyi alması mümkündür. İnt add (int a, float b) kullanmak istediğinizi ancak yanlışlıkla yazmayı unuttuğunuzu, ancak bağlayıcı zaten var olan bir int add (int a, int b) ve bunun doğru olduğunu düşündüm ve bunun yerine bunu kullandılar. Kodunuz derlenir, ancak beklediğiniz gibi olmaz.
Yani, sadece şeyleri açık tutmak ve tahmin vb. Önlemek için, derleyici kullanılmadan önce her şeyi beyan ısrar ediyor.
Beyan ve tanım arasındaki fark
Bir yana, bir açıklama ile tanım arasındaki farkı bilmek önemlidir. Bir bildirim, bir şeyin neye benzediğini göstermek için yeterli kodu verir, bu nedenle bir işlev için bu, dönüş türü, çağrı kuralı, yöntem adı, bağımsız değişkenler ve türleri içindir. Ancak yöntemin kodu gerekli değildir. Bir tanım için, fonksiyonun koduna ve sonra koduna da ihtiyacınız vardır.
İleri bildirimler oluşturma sürelerini nasıl önemli ölçüde azaltabilir?
Bir işlevin bildirimini, işlevin bir bildirimini içeren üstbilgiyi # dahil ederek geçerli .cpp veya .h dosyanıza alabilirsiniz. Ancak, bu, derlemenizi yavaşlatabilir, özellikle de # başlığınızı programınızın .cpp yerine .hpp içine eklerseniz, # yazdığınız .h'yi içeren her şey tüm başlıkları # içerir Sen de #includes yazdın. Aniden, derleyicide yalnızca bir veya iki işlev kullanmak isteseniz bile derlenmesi gereken sayfalar ve kod sayfaları bulunur. Bundan kaçınmak için, bir ileri bildirimi kullanabilir ve sadece dosyanın üst kısmına işlevin bildirimini kendiniz yazabilirsiniz. Yalnızca birkaç işlev kullanıyorsanız, bu, derlemelerinizi başlık dahil her zaman # içeriğe göre gerçekten daha hızlı hale getirebilir. Gerçekten büyük projeler için,
İki tanımın birbirini kullandığı döngüsel referansları kır
Ayrıca, ileri bildirimler döngüleri kırmanıza yardımcı olabilir. İki fonksiyonun her ikisi de birbirini kullanmaya çalışmaktadır. Bu olduğunda (ve bunu yapmak gerçekten geçerli bir şeydir), bir başlık dosyasını dahil edebilirsiniz, ancak bu başlık dosyası # şu anda yazmakta olduğunuz başlık dosyasını dahil etmeye çalışır .... bu daha sonra # diğer başlığı içerir , bu # yazdığınızı içerir. Her başlık dosyası diğerini # eklemeye çalışırken bir tavuk ve yumurta durumunda sıkışıp kaldınız. Bunu çözmek için, ihtiyaç duyduğunuz parçaları dosyalardan birinde iletebilir ve #include'u bu dosyanın dışında bırakabilirsiniz.
Örneğin:
Car.h Dosyası
#include "Wheel.h" // Include Wheel's definition so it can be used in Car.
#include <vector>
class Car
{
std::vector<Wheel> wheels;
};
Dosya Tekerleği.h
Hmm ... Tekerlek bir Arabaya bir işaretçi olduğu için burada Araba beyanı gerekiyor, ancak Car.h buraya derlenemez çünkü derleyici hatasına neden olur. Car.h dahil edilmişse, Wheel.h'yi içeren Car.h'yi içeren ve bu sonsuza kadar devam edecek olan Wheel.h'yi içermeye çalışır, böylece derleyici bir hata oluşturur. Çözüm, bunun yerine Araba ilan etmektir:
class Car; // forward declaration
class Wheel
{
Car* car;
};
Eğer Wheel sınıfının araba yöntemlerini çağırması gereken yöntemler varsa, bu yöntemler Wheel.cpp'de tanımlanabilir ve Wheel.cpp artık bir döngüye neden olmadan Car.h'yi ekleyebilir.