Bagikan melalui


Unit dan tautan terjemahan

Dalam program C++, simbol, misalnya variabel atau nama fungsi, dapat dinyatakan berapa kali dalam cakupannya. Namun, itu hanya dapat didefinisikan sekali. Aturan ini adalah "Satu Aturan Definisi" (ODR). Deklarasi memperkenalkan (atau memperkenalkan kembali) nama ke dalam program, bersama dengan informasi yang cukup untuk kemudian mengaitkan nama dengan definisi. Definisi memperkenalkan nama dan menyediakan semua informasi yang diperlukan untuk membuatnya. Jika nama mewakili variabel, definisi secara eksplisit membuat penyimpanan dan menginisialisasinya. Definisi fungsi terdiri dari tanda tangan ditambah isi fungsi. Definisi kelas terdiri dari nama kelas diikuti oleh blok yang mencantumkan semua anggota kelas. (Badan fungsi anggota dapat secara opsional didefinisikan secara terpisah dalam file lain.)

Contoh berikut menunjukkan beberapa deklarasi:

int i;
int f(int x);
class C;

Contoh berikut menunjukkan beberapa definisi:

int i{42};
int f(int x){ return x * i; }
class C {
public:
   void DoSomething();
};

Program terdiri dari satu atau beberapa unit terjemahan. Unit terjemahan terdiri dari file implementasi dan semua header yang disertakannya secara langsung atau tidak langsung. File implementasi biasanya memiliki ekstensi .cpp file atau .cxx. File header biasanya memiliki ekstensi .h atau .hpp. Setiap unit terjemahan dikompilasi secara independen oleh pengkompilasi. Setelah kompilasi selesai, linker menggabungkan unit terjemahan yang dikompilasi ke dalam satu program. Pelanggaran aturan ODR biasanya muncul sebagai kesalahan linker. Kesalahan linker terjadi ketika nama yang sama didefinisikan dalam lebih dari satu unit terjemahan.

Secara umum, cara terbaik untuk membuat variabel terlihat di beberapa file adalah dengan mendeklarasikannya dalam file header. Kemudian tambahkan arahan #include di setiap .cpp file yang memerlukan deklarasi. Dengan menambahkan menyertakan penjaga di sekitar konten header, Anda memastikan bahwa nama yang dideklarasikan header hanya dideklarasikan sekali untuk setiap unit terjemahan. Tentukan nama hanya dalam satu file implementasi.

Di C++20, modul diperkenalkan sebagai alternatif yang ditingkatkan untuk file header.

Dalam beberapa kasus, mungkin perlu untuk mendeklarasikan variabel atau kelas global dalam .cpp file. Dalam kasus tersebut, Anda memerlukan cara untuk memberi tahu pengkompilasi dan linker jenis tautan yang dimiliki namanya. Jenis tautan menentukan apakah nama objek hanya terlihat dalam satu file, atau di semua file. Konsep tautan hanya berlaku untuk nama global. Konsep tautan tidak berlaku untuk nama yang dideklarasikan dalam cakupan. Cakupan ditentukan oleh sekumpulan kurung kurawal penutup seperti dalam definisi fungsi atau kelas.

Tautan eksternal vs. internal

Fungsi gratis adalah fungsi yang didefinisikan pada cakupan global atau namespace. Variabel global non-const dan fungsi gratis secara default memiliki tautan eksternal; variabel tersebut terlihat dari unit terjemahan apa pun dalam program. Tidak ada objek global lain yang dapat memiliki nama tersebut. Simbol dengan tautan internal atau tidak ada linkage hanya terlihat dalam unit terjemahan di mana ia dideklarasikan. Ketika nama memiliki tautan internal, nama yang sama mungkin ada di unit terjemahan lain. Variabel yang dideklarasikan dalam definisi kelas atau badan fungsi tidak memiliki tautan.

Anda dapat memaksa nama global untuk memiliki tautan internal dengan secara eksplisit mendeklarasikannya sebagai static. Kata kunci ini membatasi visibilitasnya ke unit terjemahan yang sama di mana ia dideklarasikan. Dalam konteks ini, static berarti sesuatu yang berbeda dari saat diterapkan ke variabel lokal.

Objek berikut memiliki tautan internal secara default:

  • const Objek
  • constexpr Objek
  • typedef Objek
  • static objek dalam cakupan namespace

Untuk memberikan const linkage eksternal objek, nyatakan sebagai extern dan tetapkan nilainya:

extern const int value = 42;

Untuk informasi selengkapnya, lihat extern .

Baca juga

Konsep dasar