#include .h veya .c / .cpp?


118

C veya C ++ ile kodlarken, #include's'leri nerede almalıyım ?

callback.h:

#ifndef _CALLBACK_H_
#define _CALLBACK_H_

#include <sndfile.h>
#include "main.h"

void on_button_apply_clicked(GtkButton* button, struct user_data_s* data);
void on_button_cancel_clicked(GtkButton* button, struct user_data_s* data);

#endif

callback.c:

#include <stdlib.h>
#include <math.h>

#include "config.h"

#include "callback.h"
#include "play.h"

void on_button_apply_clicked(GtkButton* button, struct user_data_s* data) {
  gint page;
  page = gtk_notebook_get_current_page(GTK_NOTEBOOK(data->notebook));

  ...

Tümü .h veya .c / .cpp biçiminde mi olmalı yoksa burada yaptığım gibi her ikisi de mi?


2
Bana Bunu tersine çevirmek ve soralım: Ne oldu senin callback.h içinde sndfile.h ve main.h koymak karar vermek için kriterler?
Owen S.

Yanıtlar:


161

Yapabildiğiniz kadar çok .cve mümkün olduğunca az koyun .h. Içerilenler .cyalnızca bir dosya derlendiğinde .hdahil edilir , ancak bunu kullanan her dosya tarafından dahil edilmesi gerekir.


6
Doğru, ama #ifndef _CALLBACK_H_en önemlisi, derleyicinin onu birden fazla işlemesini engellemiyor mu?
hytromo

11
@ user9379 Bu, .c veya .cpp dosyası başına birden fazla eklenmesini engelleyecektir. Her .c veya .cpp dosyası genellikle ayrı ayrı oluşturulur, bu da derlediğiniz her .c veya .cpp dosyası için bir .h'nin yeniden ayrıştırılacağı anlamına gelir.
Brendan Long

2
Bence mümkün olduğu kadar az koymak için ana neden .h, bazı durumlarda bir dahil etme döngüsü nedeniyle bir hatadan kaçınmaktır. Örnek: iki sınıf, uygulamaları için birbirine ihtiyaç duyar, ancak bildirimleri için değil. Her ikisini de e'lerin içine koymak .cppbir hatayı önleyecektir.
Codoscope

1
Qu'est-cet'yont @ Yani bir nedeni var olamaz .h dosyalarında bazı şeyleri koydu. Bu cevap, neden bundan daha azını koymanız gerektiği ile ilgilidir.
Brendan Long

@BrendanLong İçeriği yalnızca bir kez eklemek için doğru makroları içeri koyarsanız, benim açımdan birkaç kez aynı başlığın eklenmesi önemli değil. Bu nedenle, daha da az koymanın, gelecekte kodda yapılan değişikliklerle hata alma olasılığını azaltmak olduğunu düşünüyorum.
Codoscope

55

Başka bir .h dosyasına başlık eklemeniz gereken tek zaman, bu başlıktaki bir tür tanımına erişmeniz gerekmesidir; Örneğin:

#ifndef MY_HEADER_H
#define MY_HEADER_H

#include <stdio.h>

void doStuffWith(FILE *f); // need the definition of FILE from stdio.h

#endif

Yukarıdaki örnekte olduğu gibi A başlığı B başlığına bağlıysa, bu durumda A başlığı doğrudan B başlığını içermelidir. Do DEĞİL senin bağımlılıkları (yani başlık A önce başlık B içerme) karşılamak için .c dosyasında içerir sipariş deneyin; Bu, olmasını bekleyen büyük bir mide ekşimesi yığını. İçtenlikle söyledim. O filmde birkaç kez bulundum ve her zaman Tokyo alevler içinde sona erdi.

Evet, bu, dosyaların birden çok kez dahil edilmesine neden olabilir, ancak birden fazla bildirim / tanım hatalarına karşı koruma sağlamak için ayarlanmış uygun koruma korumaları varsa, birkaç saniye fazladan derleme süresi için endişelenmeye değmez. Bağımlılıkları manuel olarak yönetmeye çalışmak baş belasıdır.

Elbette, ihtiyaç duymadığınız dosyaları dahil etmemelisiniz .


10

Cpp'nize olabildiğince çok içerir ve yalnızca hpp dosyasındaki hpp dosyası için gerekli olanları koyun. Hpp dosyalarına daha az çapraz referans verileceğinden, bunun derlemeyi hızlandırmaya yardımcı olacağına inanıyorum.

Ayrıca , dahil etme bağımlılık zincirini daha da azaltmak için hpp dosyanızda ileriye dönük bildirimler kullanmayı düşünün .


1
Oo. İleriye dönük beyanlar meselesi ilginç.
Brendan Long

Parappa, ileri bildirimler döngüsel referans senaryolarında çok kullanışlıdır. Ama diğer senaryolarda iyi bir uygulama olurlar mı? (C ++ 'da
yeniyim

5

Eğer kodumun derlenmesini sağlamak #include <callback.h>için #includeçok sayıda başka başlık dosyasına sahip olmak istemiyorum . Buna callback.hkarşı derlemek için gereken her şeyi eklemelisiniz. Ama daha fazlası değil.

Başlık dosyanızda ileriye dönük bildirimler kullanmanın (örneğin class GtkButton;) yeterli olup olmayacağını #include, başlıktaki yönergelerin sayısını (ve dolayısıyla benim derleme zamanımı ve karmaşıklığımı) azaltmanıza izin verip vermeyeceğini düşünün .


Katılmıyorum. Tüm dünyayı H dosyalarına dahil etmek, bağımlılık zincirini ve dolayısıyla derleme sürelerini artırır.
John Dibling

Başlık dosyasına tüm dünyaya dahil tavsiye etmedi Benim cevabım, ben de dahil olmak üzere önerilen sadece yeterli API kullanıcı bağımlılıkları bulmak amacıyla zaman harcamak zorunda değildir böylece.
Johnsyweb
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.