Jawaban:
Ketika Anda menulis sebuah file implementasi ( .cpp
, .cxx
, dll) compiler Anda menghasilkan unit terjemahan . Ini adalah file sumber dari implementasi Anda plus semua tajuk yang ada #include
di dalamnya.
Tautan internal mengacu pada segala sesuatu hanya dalam ruang lingkup unit terjemahan .
Tautan eksternal mengacu pada hal-hal yang ada di luar unit terjemahan tertentu. Dengan kata lain, dapat diakses melalui seluruh program , yang merupakan kombinasi dari semua unit terjemahan (atau file objek).
const
variabel (serta tujuannya) benar-benar hilang di sini.
Seperti kata dudewat tautan eksternal berarti simbol (fungsi atau variabel global) dapat diakses di seluruh program Anda dan tautan internal berarti bahwa itu hanya dapat diakses dalam satu unit terjemahan .
Anda dapat secara eksplisit mengontrol hubungan simbol dengan menggunakan kata kunci extern
dan static
. Jika hubungan tidak ditentukan maka hubungan default adalah extern
untuk non- const
simbol dan static
(internal) untuk const
simbol.
// in namespace or global scope
int i; // extern by default
const int ci; // static by default
extern const int eci; // explicitly extern
static int si; // explicitly static
// the same goes for functions (but there are no const functions)
int foo(); // extern by default
static int bar(); // explicitly static
Perhatikan bahwa alih-alih menggunakan static
untuk tautan internal, lebih baik menggunakan ruang nama anonim di mana Anda juga dapat menempatkan class
es. Tautan untuk ruang nama anonim telah berubah antara C ++ 98 dan C ++ 11 tetapi yang utama adalah bahwa mereka tidak dapat dijangkau dari unit terjemahan lainnya.
namespace {
int i; // external linkage but unreachable from other translation units.
class invisible_to_others { };
}
extern
deklarasi yang cocok di file lain.static
. Variabel tersebut dikatakan memiliki hubungan internal .Pertimbangkan contoh berikut:
void f(int i);
extern const int max = 10;
int n = 0;
int main()
{
int a;
//...
f(a);
//...
f(a);
//...
}
f
menyatakan f
sebagai fungsi dengan tautan eksternal (default). Definisinya harus diberikan nanti di file ini atau di unit terjemahan lain (diberikan di bawah).max
didefinisikan sebagai konstanta integer. Tautan default untuk konstanta adalah internal . Keterkaitannya diubah menjadi eksternal dengan kata kunci extern
. Jadi sekarang max
bisa diakses di file lain.n
didefinisikan sebagai variabel integer. Hubungan default untuk variabel yang ditentukan di luar badan fungsi adalah eksternal .#include <iostream>
using namespace std;
extern const int max;
extern int n;
static float z = 0.0;
void f(int i)
{
static int nCall = 0;
int a;
//...
nCall++;
n++;
//...
a = max * z;
//...
cout << "f() called " << nCall << " times." << endl;
}
max
dinyatakan memiliki hubungan eksternal . Definisi yang cocok untuk max
(dengan tautan eksternal) harus muncul di beberapa file. (Seperti pada 1.cpp)n
dinyatakan memiliki hubungan eksternal .z
adalah didefinisikan sebagai variabel global dengan hubungan internal .nCall
menentukan nCall
menjadi variabel yang mempertahankan nilainya melintasi panggilan ke fungsi f()
. Tidak seperti variabel lokal dengan kelas penyimpanan otomatis default, nCall
akan diinisialisasi hanya sekali pada awal program dan tidak sekali untuk setiap doa f()
. Penentu kelas penyimpanan static
memengaruhi masa pakai variabel lokal dan bukan cakupannya.NB: Kata kunci static
memainkan peran ganda. Ketika digunakan dalam definisi variabel global, ini menentukan hubungan internal . Ketika digunakan dalam definisi variabel lokal, itu menentukan bahwa masa pakai variabel akan menjadi durasi program bukannya durasi fungsi.
Semoga itu bisa membantu!
static
memungkinkan inisialisasi tunggal malas (yang dapat berguna jika Anda memerlukan objek global-ish tetapi harus mengontrol ketika itu dibangun karena masalah dengan urutan konstruksi global dan tidak dapat secara dinamis mengalokasikannya menggunakan new
sementara skema inisialisasi yang lebih mendalam mungkin melampaui apa yang diperlukan untuk objek yang bersangkutan; dengan implikasi, ini terutama merupakan masalah pada sistem embedded yang menggunakan C ++).
Mari kita bicara tentang ruang lingkup yang berbeda di 'C'
RUANG LINGKUP: Pada dasarnya berapa lama saya bisa melihat sesuatu dan seberapa jauh.
Variabel lokal: Lingkup hanya di dalam fungsi. Itu berada di area STACK RAM. Yang berarti bahwa setiap kali suatu fungsi dipanggil semua variabel yang merupakan bagian dari fungsi itu, termasuk argumen fungsi yang baru dibuat dan dihancurkan setelah kontrol keluar dari fungsi. (Karena tumpukan memerah setiap fungsi kembali)
Variabel statis: Cakupan ini untuk file. Ini dapat diakses di mana saja di file
yang dideklarasikan. Itu berada di segmen DATA RAM. Karena ini hanya dapat diakses di dalam file dan karenanya tautan INTERNAL. Setiap
file lainnya tidak bisa melihat variabel ini. Sebenarnya kata kunci STATIC adalah satu-satunya cara di mana kita dapat memperkenalkan beberapa level data atau fungsi
bersembunyi di 'C'
Variabel global: Cakupan ini untuk seluruh aplikasi. Ini dapat diakses dari setiap tempat aplikasi. Variabel global juga berada di segmen DATA Karena dapat diakses di mana saja dalam aplikasi dan karenanya EKSTERNAL Linkage
Secara default semua fungsi bersifat global. Jika Anda perlu menyembunyikan beberapa fungsi dalam file dari luar, Anda dapat awalan kata kunci statis ke fungsi. :-)
Sebelum berbicara tentang pertanyaan, lebih baik untuk mengetahui istilah unit terjemahan , program dan beberapa konsep dasar C ++ (sebenarnya keterkaitan adalah salah satunya secara umum) tepatnya. Anda juga harus tahu apa itu ruang lingkup .
Saya akan menekankan beberapa poin penting, khususnya. yang hilang dalam jawaban sebelumnya.
Linkage adalah properti dari nama , yang diperkenalkan oleh deklarasi . Nama yang berbeda dapat menunjukkan entitas yang sama (biasanya, objek atau fungsi). Jadi, berbicara tentang hubungan suatu entitas biasanya tidak masuk akal, kecuali jika Anda yakin bahwa entitas tersebut hanya akan dirujuk dengan nama unik dari beberapa deklarasi tertentu (biasanya satu deklarasi).
Catatan objek adalah entitas, tetapi variabel tidak. Saat berbicara tentang keterkaitan variabel, sebenarnya nama entitas yang ditandai (yang diperkenalkan oleh deklarasi tertentu) terkait. Tautan nama dalam salah satu dari tiga: tidak ada hubungan, hubungan internal atau hubungan eksternal.
Unit terjemahan yang berbeda dapat membagikan deklarasi yang sama dengan file header / sumber (ya, itu adalah kata-kata standar) yang disertakan. Jadi, Anda dapat merujuk nama yang sama di unit terjemahan yang berbeda. Jika nama yang dideklarasikan memiliki tautan eksternal, identitas entitas yang dirujuk oleh nama tersebut juga dibagikan. Jika nama yang dideklarasikan memiliki hubungan internal, nama yang sama di unit terjemahan yang berbeda menunjukkan entitas yang berbeda, tetapi Anda dapat merujuk entitas dalam lingkup yang berbeda dari unit terjemahan yang sama. Jika nama tidak memiliki tautan, Anda tidak dapat merujuk entitas dari lingkup lain.
(Ups ... Saya menemukan apa yang saya ketik agak hanya mengulangi kata-kata standar ...)
Ada juga beberapa poin membingungkan lainnya yang tidak tercakup oleh spesifikasi bahasa.
__attribute__
atau__declspec
) atau opsi penyusun, dan gambar bukanlah keseluruhan program atau file objek yang diterjemahkan dari unit terjemahan, sehingga tidak ada konsep standar yang dapat menggambarkannya secara akurat. Karena simbol bukan istilah normatif dalam C ++, itu hanya detail implementasi, meskipun ekstensi dialek terkait mungkin telah diadopsi secara luas.The Aturan linkage lingkup namespace const
variabel adalah sesuatu yang istimewa (dan terutama yang berbeda dengan const
objek dideklarasikan di lingkup berkas dalam bahasa C yang juga memiliki konsep linkage pengidentifikasi). Karena ODR diberlakukan oleh C ++, penting untuk menjaga tidak lebih dari satu definisi variabel atau fungsi yang sama terjadi di seluruh program kecuali untuk inline
fungsi . Jika tidak ada aturan khusus const
, deklarasi const
variabel paling sederhana dengan inisialisasi (mis.= xxx
) dalam header atau file sumber (sering kali "file header") dimasukkan oleh beberapa unit terjemahan (atau disertakan oleh satu unit terjemahan lebih dari satu kali, meskipun jarang) dalam suatu program akan melanggar ODR, yang membuatnya digunakanconst
variabel sebagai penggantian beberapa makro objek-seperti tidak mungkin.
Saya pikir Hubungan Internal dan Eksternal di C ++ memberikan penjelasan yang jelas dan ringkas:
Unit terjemahan mengacu pada file implementasi (.c / .cpp) dan semua file header (.h / .hpp) yang disertakan. Jika suatu objek atau fungsi di dalam unit terjemahan tersebut memiliki hubungan internal, maka simbol spesifik tersebut hanya dapat dilihat oleh linker di dalam unit terjemahan itu. Jika suatu objek atau fungsi memiliki tautan eksternal, tautan tersebut juga dapat melihatnya saat memproses unit terjemahan lainnya. Kata kunci statis, ketika digunakan dalam namespace global, memaksa simbol untuk memiliki tautan internal. Kata kunci eksternal menghasilkan simbol yang memiliki tautan eksternal.
Kompiler secara default menautkan simbol sehingga:
Variabel global non-const memiliki hubungan eksternal secara default
variabel global Const memiliki hubungan internal secara default
Fungsi memiliki hubungan eksternal secara default
Linkage menentukan apakah pengidentifikasi yang memiliki nama identik merujuk pada objek, fungsi, atau entitas lain yang sama, bahkan jika pengidentifikasi tersebut muncul di unit terjemahan yang berbeda. Tautan pengenal tergantung pada bagaimana hal itu dinyatakan. Ada tiga jenis hubungan:
Khusus C ++ : Anda juga dapat memiliki keterkaitan antara fragmen kode C ++ dan non-C ++, yang disebut bahasa linkage .
Sumber: Tautan Program IBM
Pada dasarnya
extern linkage
variabel terlihat di semua fileinternal linkage
variabel terlihat dalam satu file.Jelaskan: variabel const tautan internal secara default kecuali dinyatakan sebaliknya sebagai eksternal
external linkage
const
variabel global adalahinternal linkage
extern const
variabel global adalahexternal linkage
Materi yang cukup bagus tentang tautan di C ++
http://www.goldsborough.me/c/c++/linker/2016/03/30/19-34-25-internal_and_external_linkage_in_c++/
Dalam C ++
Setiap variabel pada lingkup file dan yang tidak bersarang di dalam kelas atau fungsi, terlihat di seluruh unit terjemahan dalam suatu program. Ini disebut tautan eksternal karena pada waktu tautan nama tersebut dapat dilihat oleh tautan di mana saja, di luar unit terjemahan itu.
Variabel global dan fungsi biasa memiliki hubungan eksternal.
Objek statis atau nama fungsi pada lingkup file bersifat lokal ke unit terjemahan. Itulah yang disebut dengan Internal Linkage
Linkage hanya merujuk ke elemen yang memiliki alamat pada tautan / waktu buka; dengan demikian, deklarasi kelas dan variabel lokal tidak memiliki keterkaitan.