Pertama, untuk menjawab pertanyaan pertama Anda:
Jika Anda melihat ini di file .h :
#ifndef FILE_H
#define FILE_H
#endif
Ini adalah teknik preprocessor untuk mencegah file header dimasukkan beberapa kali, yang dapat menjadi masalah karena berbagai alasan. Selama kompilasi proyek Anda, setiap file .cpp (biasanya) dikompilasi. Secara sederhana, ini berarti kompilator akan mengambil file .cpp Anda , membuka file apa pun #included
dengannya, menggabungkan semuanya menjadi satu file teks besar, dan kemudian melakukan analisis sintaks dan akhirnya akan mengubahnya menjadi beberapa kode perantara, mengoptimalkan / melakukan yang lain tugas, dan akhirnya menghasilkan keluaran perakitan untuk arsitektur target. Karenanya, jika sebuah file #included
beberapa kali berada di bawah satu .cppfile, kompilator akan menambahkan konten file dua kali, jadi jika ada definisi di dalam file itu, Anda akan mendapatkan kesalahan kompilator yang memberi tahu Anda bahwa Anda mendefinisikan ulang variabel. Ketika file diproses oleh langkah preprocessor dalam proses kompilasi, pertama kali isinya tercapai, dua baris pertama akan memeriksa apakah FILE_H
preprocessor telah ditentukan. Jika tidak, itu akan mendefinisikan FILE_H
dan melanjutkan pemrosesan kode antara itu dan #endif
direktif. Saat konten file tersebut dilihat di lain waktu oleh preprocessor, pemeriksaan terhadapnya FILE_H
akan salah, jadi itu akan segera memindai ke bawah #endif
dan melanjutkan setelahnya. Ini mencegah kesalahan definisi ulang.
Dan untuk mengatasi kekhawatiran kedua Anda:
Dalam pemrograman C ++ sebagai praktik umum, kami memisahkan pengembangan menjadi dua jenis file. Salah satunya adalah dengan ekstensi .h dan kami menyebutnya "file header". Mereka biasanya menyediakan deklarasi fungsi, kelas, struct, variabel global, typedefs, makro dan definisi preprocessing, dll. Pada dasarnya, mereka hanya memberi Anda informasi tentang kode Anda. Kemudian kami memiliki ekstensi .cpp yang kami sebut "file kode." Ini akan memberikan definisi untuk fungsi tersebut, anggota kelas, anggota struct apa pun yang membutuhkan definisi, variabel global, dll. Jadi file .h mendeklarasikan kode, dan file .cpp mengimplementasikan deklarasi itu. Untuk alasan ini, kami biasanya selama kompilasi mengkompilasi setiap .cppfile ke dalam suatu objek dan kemudian tautkan objek tersebut (karena Anda hampir tidak pernah melihat satu file .cpp menyertakan file .cpp lainnya ).
Bagaimana eksternal ini diselesaikan adalah pekerjaan untuk linker. Ketika kompilator Anda memproses main.cpp , ia mendapatkan deklarasi untuk kode di class.cpp dengan menyertakan class.h . Hanya perlu mengetahui seperti apa fungsi atau variabel ini (yang diberikan deklarasi kepada Anda). Jadi itu mengkompilasi file main.cpp Anda menjadi beberapa file objek (sebut saja main.obj ). Demikian pula, class.cpp dikompilasi menjadi class.objmengajukan. Untuk menghasilkan eksekusi akhir, linker dipanggil untuk menghubungkan kedua file objek tersebut bersama-sama. Untuk variabel atau fungsi eksternal yang belum terselesaikan, kompilator akan menempatkan stub di mana akses terjadi. Linker kemudian akan mengambil stub ini dan mencari kode atau variabel di file objek terdaftar lainnya, dan jika ditemukan, linker akan menggabungkan kode dari dua file objek menjadi file output dan menggantikan stub dengan lokasi akhir fungsi atau variabel. Dengan cara ini, kode Anda di main.cpp dapat memanggil fungsi dan menggunakan variabel di class.cpp JIKA DAN HANYA JIKA MEREKA DITERAPKAN DI class.h .
Saya harap ini membantu.