Saat membagi kode Anda menjadi beberapa file, apa sebenarnya yang harus dimasukkan ke dalam file .h dan apa yang harus dimasukkan ke file .cpp?
c++
header-files
Enrico Tuvera Jr
sumber
sumber
.hpp
file sementara deklarasi C masuk ke dalam.h
file. Ini sangat membantu saat mencampur kode C dan C ++ (misalnya modul lama di C).Jawaban:
File header (
.h
) dirancang untuk memberikan informasi yang akan dibutuhkan dalam banyak file. Hal-hal seperti deklarasi kelas, prototipe fungsi, dan enumerasi biasanya masuk dalam file header. Singkatnya, "definisi".File kode (
.cpp
) dirancang untuk memberikan informasi implementasi yang hanya perlu diketahui dalam satu file. Secara umum, badan fungsi, dan variabel internal yang seharusnya / tidak akan pernah diakses oleh modul lain, adalah milik dalam.cpp
file. Singkatnya, "implementasi".Pertanyaan paling sederhana untuk ditanyakan pada diri Anda sendiri untuk menentukan milik mana adalah "jika saya mengubah ini, apakah saya harus mengubah kode di file lain untuk membuat semuanya terkompilasi lagi?" Jika jawabannya adalah "ya", kemungkinan itu ada di file header; jika jawabannya "tidak", kemungkinan itu termasuk dalam file kode.
sumber
export
). Satu-satunya cara # 1 adalah PIMPL. # 2 akan dimungkinkan jikaexport
didukung dan dimungkinkan menggunakan c ++ 0x danextern
template. IMO, file header di c ++ kehilangan banyak kegunaannya.Faktanya, dalam C ++, ini agak lebih rumit daripada organisasi header / sumber C.
Apa yang dilihat kompilator?
Kompilator melihat satu file sumber besar (.cpp) dengan header yang disertakan dengan benar. File sumber adalah unit kompilasi yang akan dikompilasi menjadi file objek.
Jadi, mengapa header diperlukan?
Karena satu unit kompilasi mungkin memerlukan informasi tentang implementasi di unit kompilasi lain. Jadi seseorang dapat menulis misalnya implementasi suatu fungsi di satu sumber, dan menulis deklarasi fungsi ini di sumber lain yang perlu menggunakannya.
Dalam kasus ini, ada dua salinan dari informasi yang sama. Yang mana yang jahat ...
Solusinya adalah membagikan beberapa detail. Meskipun implementasinya harus tetap di Source, deklarasi simbol bersama, seperti fungsi, atau definisi struktur, kelas, enum, dll., Mungkin perlu dibagikan.
Header digunakan untuk meletakkan detail yang dibagikan tersebut.
Pindah ke tajuk deklarasi tentang apa yang perlu dibagikan antara berbagai sumber
Tidak ada lagi?
Di C ++, ada beberapa hal lain yang dapat diletakkan di header karena, mereka juga perlu dibagikan:
Pindah ke tajuk SEMUANYA yang perlu dibagikan, termasuk penerapan bersama
Apakah itu berarti bahwa mungkin ada sumber di dalam tajuk?
Iya. Faktanya, ada banyak hal berbeda yang mungkin ada di dalam "header" (yaitu, dibagikan antar sumber).
Ini menjadi rumit, dan dalam beberapa kasus (ketergantungan melingkar antar simbol), tidak mungkin untuk menyimpannya dalam satu tajuk.
Header dapat dibagi menjadi tiga bagian
Artinya, dalam kasus ekstrem, Anda dapat memiliki:
Mari kita bayangkan kita memiliki MyObject template. Kami dapat memiliki:
.
.
.
Wow!
Dalam "kehidupan nyata", biasanya tidak terlalu rumit. Kebanyakan kode hanya akan memiliki tajuk / organisasi sumber sederhana, dengan beberapa kode sebaris di sumbernya.
Tetapi dalam kasus lain (objek templated mengetahui satu sama lain), saya harus memiliki untuk setiap objek deklarasi terpisah dan header implementasi, dengan sumber kosong termasuk header tersebut hanya untuk membantu saya melihat beberapa kesalahan kompilasi.
Alasan lain untuk memecah tajuk menjadi tajuk yang terpisah bisa jadi untuk mempercepat kompilasi, membatasi jumlah simbol yang diuraikan hingga batas yang diperlukan, dan menghindari kompilasi ulang yang tidak perlu dari sumber yang hanya peduli pada deklarasi maju ketika penerapan metode sebaris berubah.
Kesimpulan
Anda harus membuat organisasi kode Anda sesederhana mungkin, dan sesederhana mungkin. Letakkan sebanyak mungkin di file sumber. Hanya tampilkan di header apa yang perlu dibagikan.
Tetapi jika Anda memiliki ketergantungan melingkar antara objek template, jangan heran jika organisasi kode Anda menjadi lebih "menarik" daripada organisasi header / sumber biasa ...
^ _ ^
sumber
Selain semua jawaban lainnya, saya akan memberi tahu Anda apa yang TIDAK Anda tempatkan di file header:
using
deklarasi (yang paling umumusing namespace std;
) tidak boleh muncul di file header karena mereka mencemari namespace dari file sumber yang disertakan .sumber
using
untuk membawa barang ke namespace global di header.static inline
di C99, karena ada hubungannya dengan apa yang terjadi saat Anda menggabungkan tautan internal dengan template. Ruang nama Anon memungkinkan Anda "menyembunyikan" fungsi, sambil mempertahankan tautan eksternal.Apa yang dikompilasi menjadi tidak ada (jejak biner nol) masuk ke file header.
Variabel tidak dikompilasi menjadi apa-apa, tetapi deklarasi tipe melakukan (karena mereka hanya menjelaskan bagaimana variabel berperilaku).
fungsi tidak, tetapi fungsi sebaris melakukannya (atau makro), karena mereka menghasilkan kode hanya jika dipanggil.
template bukanlah kode, mereka hanya resep untuk membuat kode. jadi mereka juga masuk ke file h.
sumber
Secara umum, Anda meletakkan deklarasi di file header dan definisi di file implementasi (.cpp). Pengecualian untuk ini adalah template, di mana definisi juga harus ditempatkan di header.
Pertanyaan ini dan yang serupa dengan itu telah sering ditanyakan di SO - lihat Mengapa file header dan file .cpp di C ++? dan File Header C ++, Pemisahan Kode misalnya.
sumber
Deklarasi kelas dan fungsi Anda ditambah dengan dokumentasi, dan definisi untuk fungsi / metode inline (meskipun beberapa lebih suka meletakkannya dalam file .inl terpisah).
sumber
Terutama file header berisi kerangka kelas atau deklarasi (tidak sering berubah)
dan file cpp berisi implementasi kelas (sering berubah).
sumber
file header (.h) harus untuk deklarasi kelas, struct dan metodenya, prototipe, dll. Implementasi objek tersebut dibuat di cpp.
dalam .h
sumber
Saya berharap untuk melihat:
jawaban sebenarnya adalah apa yang tidak harus dimasukkan:
sumber
Header Mendefinisikan sesuatu tapi tidak menceritakan apapun tentang implementasinya. (Tidak termasuk Template di "metafore" ini.
Dengan demikian, Anda perlu membagi "definisi" ke dalam sub-kelompok, dalam hal ini, dua jenis definisi.
Sekarang, saya tentu saja berbicara tentang subkelompok pertama.
Header ada di sana untuk menentukan tata letak struktur Anda untuk membantu perangkat lunak lainnya menggunakan implementasi. Anda mungkin ingin melihatnya sebagai "abstraksi" dari implementasi Anda, yang dengan jelas dikatakan tetapi, menurut saya itu cukup cocok untuk kasus ini.
Seperti yang dikatakan dan ditunjukkan poster sebelumnya, Anda mendeklarasikan area penggunaan pribadi dan publik dan headernya, ini juga termasuk variabel privat dan publik. Sekarang, saya tidak ingin membahas desain kode di sini, tetapi Anda mungkin ingin mempertimbangkan apa yang Anda masukkan ke header, karena itu adalah Layer antara pengguna akhir dan implementasinya.
sumber
sumber
Tajuk (.h)
Tubuh (.cpp)
Sebagai aturan praktis, Anda meletakkan bagian "bersama" dari modul di .h (bagian yang perlu dilihat modul lain) dan bagian "tidak dibagikan" di .cpp
PD: Ya, saya sudah memasukkan variabel global. Saya telah menggunakannya beberapa kali dan penting untuk tidak mendefinisikannya di header, atau Anda akan mendapatkan banyak modul, masing-masing mendefinisikan variabelnya sendiri.
EDIT: Diubah setelah komentar David
sumber