void test(int& in);
void test(const int& in){

}

int main(){
 int a = 5; 
 test(a);
 return 0;
}

Di atas tidak dapat dikompilasi dengan kesalahan tautan: undefined reference to `test(int&)'.

Saya punya 3 pertanyaan tentang ini:

1- Mengapa kami mendapatkan kesalahan tautan? apakah karena menambahkan const ke definisi membuatnya menjadi fungsi yang sama sekali berbeda? mengapa ini berfungsi ketika tidak menggunakan referensi, yaitu ini berfungsi dengan baik:

void test(int in);
void test(const int in){}
..
 int a = 5; 
 test(a);
..

2- Apakah const masuk dalam deklarasi fungsi, atau definisi atau keduanya? Sepertinya perilakunya berbeda jika referensi digunakan.

3- Apakah kata kunci const pada argumen mengatakan the parameter passed to me should be a constant in the caller atau this parameter is treated as a constant in this function scope, regardless of it being constant in the caller or not. Saya yakin itu tangga tetapi ingin memastikan.

c++
1
Dan 28 Mei 2021, 21:20

4 jawaban

Jawaban Terbaik

Dalam C++ dua fungsi:

void test(int& in);
void test(const int& in);

Adalah DUA yang berbeda, fungsi kelebihan beban. Yang pertama mengikat ke bilangan bulat "yang dapat ditulis", yang kedua - ke bilangan bulat konstan.

Dalam kode Anda:

int a = 5; 
test(a);

a adalah objek yang dapat dimodifikasi, oleh karena itu void test (int &) lebih cocok dari perspektif kompiler dan memilih fungsi ini untuk panggilan.

Alasan mengapa Anda mendapatkan kesalahan tautan adalah karena Anda mendeklarasikan tetapi tidak mendefinisikan fungsi ini.

Dalam kedua kasus di bawah fungsi const akan dipilih:

int const a = 5; 
test(a);
test(10);

Selain itu jika Anda hanya memiliki const versi yang dideklarasikan seperti di bawah ini, itu akan dipilih juga:

//void test(int &in);
void test(const int &in){}
..
 int a = 5; 
 test(a);
..

Adapun pertanyaan kedua dalam hal referensi - const pergi ke deklarasi dan definisi karena ini adalah fungsi yang berbeda.

Dengan nilai normal TIDAK ada perbedaan antara keduanya saat dideklarasikan:

void test(int in);
void test(const int in);

Mereka merujuk ke fungsi YANG SAMA. Versi const akan mencegah modifikasi parameter fungsi dalam definisi fungsi.

Untuk yang ketiga, bila diterapkan pada referensi itu berarti dua hal:

  1. Referensi akan diteruskan ke fungsi dan bukan salinan untuk objek.
  2. Ketika disertai dengan const ia berjanji kepada pemanggil untuk tidak mengubah objek yang direferensikan dan mencegah fungsi melakukannya.
4
Tomek 28 Mei 2021, 18:40

Sebaiknya lakukan keduanya, karena kata kunci const dimaksudkan untuk memberi petunjuk kepada pengguna bahwa variabel tidak akan diubah. Saya yakin sebagian besar kompiler akan memperlakukan tipe const sebagai tipe yang berbeda juga, jadi Anda akan mengalami kesalahan kompilasi.

-1
Guy Marino 28 Mei 2021, 18:22

Definisi fungsi selalu juga merupakan deklarasi fungsi.

Jadi, untuk membedakannya, yang terakhir sering disebut deklarasi maju jika itu bukan juga definisi.

Tanda tangan fungsi yang digunakan untuk resolusi kelebihan beban berasal dari deklarasi fungsi, dan ada beberapa keanehan dalam menurunkannya dari sumber tertulis:

  1. Penentu cv tingkat atas pada tipe argumen dibuang.

  2. Penentu cv tingkat atas pada tipe-kembali dibuang jika tipenya bukan tipe-kelas atau serikat-serikat. (A struct adalah tipe kelas.)

Fungsi ini tidak terpengaruh oleh aturan ini di luar resolusi kelebihan dan deklarasi yang cocok.

Diterapkan pada contoh Anda:

void test(int& in);
void test(const int& in) { // const is not top-level
// The above two declarations are for different functions

void test(int in);
void test(const int in){} // const is top-level
// Equivalent declarations above
1
Deduplicator 28 Mei 2021, 18:51

Definisi fungsi juga merupakan deklarasi fungsi. Jadi, Anda mendeklarasikan dua fungsi yang kelebihan beban, tetapi hanya satu fungsi yang didefinisikan, yang memiliki badan.

Kompilator memilih fungsi pertama, karena a bukan const dan pilihan pertama adalah sama persis.

Anda mendapatkan kesalahan tautan, karena fungsi pertama tidak memiliki definisi, mis.

1
S.M. 28 Mei 2021, 18:32