İleri bildirim ve dahil etme


18

Reduce the number of #include files in header files. It will reduce build times. Instead, put include files in source code files and use forward declarations in header files.

Bunu burada okudum. http://www.yolinux.com/TUTORIALS/LinuxTutorialC++CodingStyle.html .

Dolayısıyla, başlık dosyasındaki bir sınıfın (A sınıfı) bir sınıfın (B sınıfı) gerçek tanımını kullanması gerekmediği yazıyor. O zaman, belirli (sınıf B) başlık dosyasını eklemek yerine ileri bildirimini kullanabiliriz.

Soru: Üstbilgideki sınıf (A sınıfı) belirli bir sınıfın (B sınıfı) gerçek tanımını kullanmıyorsa, o zaman ileri bildirim derleme süresini azaltmaya nasıl yardımcı olur?

Yanıtlar:


12

Derleyici, A sınıfı B sınıfı kullanıyorsa umursamaz. Yalnızca A sınıfı derlendiğinde ve önceden B sınıfı bildirimi (ileri bildirim veya başka bir şekilde) olmadığında panik yapar ve bir hata olarak işaretler.

Burada önemli olan, derleyicinin kediniz klavyenizde yürüdükten ve bir sınıf olarak yorumlanabilecek veya yorumlanmayacak bazı rastgele harfler oluşturduktan sonra bir program derlemeye çalışmadığınızı bilmesidir.

Bir içerme gördüğünde, içerdiği bilgileri kullanabilmek için, dosyayı açmalı ve ayrıştırmalıdır (gerçekten yapması gerekip gerekmediğine bakılmaksızın). Bu dosya daha sonra başka dosyalar içeriyorsa, bunların da açılması ve ayrıştırılması gerekir. Bu önlenebilirse, bunun yerine ileri bildirim kullanmak genellikle iyi bir fikirdir.

Düzenleme : Bu kuralın başlıkları önceden derlenmiş istisna. Bu durumda, tüm üstbilgiler derlenir ve gelecekteki derlemeler için saklanır. Üstbilgiler değişmezse, derleyici önceki derlemelerin önceden derlenmiş üstbilgilerini akıllıca kullanabilir ve böylece derleme sürelerini kısaltabilir, ancak yalnızca üstbilgileri değiştirmeniz gerekmiyorsa iyi çalışır.


Açıklama için teşekkürler. Sonra Tamam örnek olarak üç başlık dosyaları olduğunu düşünüyorum vehicle.h, bus.h, toybus.h. vehicle.htarafından dahil etmek bus.hve bus.hdahil etmek toybus.h. eğer biraz değişiklik yaparsam bus.h. derleyici vehicle.htekrar açılıp ayrıştırılıyor mu? tekrar derliyor mu?
Nayana Adassuriya

1
@NayanaAdassuriya Evet, her seferinde dahil edilir ve ayrıştırılır, bu nedenle bu dosyaların birden çok kez eklenmesini (veya en azından ifndef durumunda birden çok kez kullanılmasını) önlemek için başlık dosyalarında bildirimleri görür #pragma onceveya #ifndef __VEHICLE_H_yazabilirsiniz.
Neil

4

çünkü o zaman A.hpp'in #hh.hpp eklemesine gerek yoktur

böylece A.hpp olur

class B;//or however forward decl works for classes

class A
{
    B* bInstance_;
//...
}

A.hpp dahil edildiğinde B.hpp dolaylı olarak dahil edilmez ve yalnızca A.hpp'ye bağımlı olan tüm dosyaların b.hpp her değiştiğinde yeniden derlenmesi gerekmez


ancak kaynak dosyada (A.cpp). gerçek başlık dosyasını (Bh) içermesi gerekir. Yani her zaman derlenmesi gerekir. Son olarak Bh'nin her iki şekilde de değişikliklerle yeniden derlenmesi gerekir. Farklı mı?
Nayana Adassuriya

@NayanaAdassuriya bir tek B'ye bir işaretçi kullanır hiçbir nedeni ve B'ye değişiklikler A.hpp (veya dosyaları dahil) etkilemez
mandal ucube

@ NayanaAdassuriya: Evet.
Jan Hudec

3

Unutmayın, C / C ++ önişlemcisi ayrı, tamamen metinsel bir işlem adımıdır. #includeDahil başlığının içeriği direktif çeker ve derleyici bunu ayrıştırması gerekir. Dahası, her birinin derlenmesi .cpptamamen ayrıdır, bu yüzden derleyicinin B.hderleme sırasında sadece ayrıştırılması , derlerken B.cpptekrar ihtiyaç duyduğunda en azından yardımcı olmaz A.cpp. Ve derlerken tekrar C.cpp. Ve D.cpp. Ve bunun gibi. Ve içinde bulunan herhangi bir dosya değiştiyse, bu dosyaların her birinin yeniden derlenmesi gerekir.

Yani sınıf söylemek Akullanımları sınıfını Bve sınıfları Cve Dkullanım sınıfı A, ancak manipüle etmek gerekmez B. Sınıf Asadece ileri bildirimi ile bildirilebiliyorsa, iki kez derlenenden Bdaha fazladır B.h: derlerken B.cppve A.cpp(çünkü Bhala Ayöntemler içinde gerekli ).

Ama A.hiçerir B.h, derlenmiş dört derleme zamanlar- B.cpp, A.cpp, C.cppve D.cppdaha sonra iki şimdi dolaylı dahil olarak B.hda.

Üstbilgi birden çok kez dahil edildiğinde, önişlemcinin her seferinde yine de okuması gerekir . Korumalar nedeniyle içeriğinin işlenmesini atlayacaktır #ifdef, ancak yine de onu okur ve muhafazanın sonunu araması gerekir, bu da içindeki tüm önişlemci yönergelerini ayrıştırması gerektiği anlamına gelir.

(Diğer cevapta belirtildiği gibi, önceden derlenmiş başlıklar bu soruna geçici bir çözüm bulmaya çalışır, ancak bunlar kendi solucan kutularıdır; temel olarak bunları sistem başlıkları için ve yalnızca çok fazla kullanmıyorsanız, ancak projenizdeki başlıklar)


+1, üstbilgiler, yalnızca çok sayıda A ve B sınıfına sahip olduğunuzda değil, oldukça fazla sayıda sınıfınız olduğunda ciddi bir sorun haline gelir.
Doc Brown

2

İleri bildirimin ayrıştırılması, kendisi de daha fazla başlık dosyası içerebilecek bir başlık dosyasından daha hızlıdır.

Ayrıca, B sınıfı için başlık dosyasındaki bir şeyi değiştirirseniz, bu başlık dahil her şeyin yeniden derlenmesi gerekir. İleri bir bildirimle, bu yalnızca A uygulamasının bulunduğu kaynak dosya olabilir. Ancak A'nın başlığı aslında B'nin başlığını içeriyorsa a.hpp, B'den hiçbir şey kullanmasa bile dahil her şey yeniden derlenecektir.

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.