Contoh di mana pointer const sangat dapat diterapkan dapat ditunjukkan demikian. Pertimbangkan Anda memiliki kelas dengan array dinamis di dalamnya, dan Anda ingin memberikan akses pengguna ke array tetapi tanpa memberi mereka hak untuk mengubah pointer. Mempertimbangkan:
#include <new>
#include <string.h>
class TestA
{
private:
char *Array;
public:
TestA(){Array = NULL; Array = new (std::nothrow) char[20]; if(Array != NULL){ strcpy(Array,"Input data"); } }
~TestA(){if(Array != NULL){ delete [] Array;} }
char * const GetArray(){ return Array; }
};
int main()
{
TestA Temp;
printf("%s\n",Temp.GetArray());
Temp.GetArray()[0] = ' '; //You can still modify the chars in the array, user has access
Temp.GetArray()[1] = ' ';
printf("%s\n",Temp.GetArray());
}
Yang menghasilkan:
Input data
memasukkan data
Tetapi jika kita coba ini:
int main()
{
TestA Temp;
printf("%s\n",Temp.GetArray());
Temp.GetArray()[0] = ' ';
Temp.GetArray()[1] = ' ';
printf("%s\n",Temp.GetArray());
Temp.GetArray() = NULL; //Bwuahahahaa attempt to set it to null
}
Kita mendapatkan:
error: nilai diperlukan sebagai operan tugas kiri // Drat digagalkan lagi!
Jadi jelas kita bisa memodifikasi isi array, tetapi bukan pointer array. Baik jika Anda ingin memastikan pointer memiliki status yang konsisten ketika meneruskannya kembali ke pengguna. Namun ada satu tangkapan:
int main()
{
TestA Temp;
printf("%s\n",Temp.GetArray());
Temp.GetArray()[0] = ' ';
Temp.GetArray()[1] = ' ';
printf("%s\n",Temp.GetArray());
delete [] Temp.GetArray(); //Bwuahaha this actually works!
}
Kami masih dapat menghapus referensi memori pointer, meskipun kami tidak dapat memodifikasi pointer itu sendiri.
Jadi jika Anda ingin referensi memori selalu menunjuk ke sesuatu (IE tidak pernah dimodifikasi, mirip dengan cara kerja referensi saat ini), maka itu sangat berlaku. Jika Anda ingin pengguna memiliki akses penuh dan memodifikasinya, maka non-const adalah untuk Anda.
Edit:
Setelah mencatat komentar okorz001 karena tidak dapat menetapkan karena GetArray () menjadi operan bernilai tepat, komentarnya sepenuhnya benar, tetapi hal di atas masih berlaku jika Anda mengembalikan referensi ke pointer (saya kira saya berasumsi GetArray adalah merujuk referensi), misalnya:
class TestA
{
private:
char *Array;
public:
TestA(){Array = NULL; Array = new (std::nothrow) char[20]; if(Array != NULL){ strcpy(Array,"Input data"); } }
~TestA(){if(Array != NULL){ delete [] Array;} }
char * const &GetArray(){ return Array; } //Note & reference operator
char * &GetNonConstArray(){ return Array; } //Note non-const
};
int main()
{
TestA Temp;
Temp.GetArray() = NULL; //Returns error
Temp.GetNonConstArray() = NULL; //Returns no error
}
Akan kembali yang pertama menghasilkan kesalahan:
galat: penugasan lokasi hanya baca 'Temp.TestA :: GetArray ()'
Tetapi yang kedua akan terjadi dengan riang meskipun ada konsekuensi potensial di bawahnya.
Jelas, pertanyaan akan diajukan 'mengapa Anda ingin mengembalikan referensi ke pointer'? Ada contoh langka di mana Anda perlu menetapkan memori (atau data) langsung ke pointer asli yang bersangkutan (misalnya, membangun malloc Anda sendiri / front-end gratis / baru atau gratis), tetapi dalam kasus tersebut itu adalah referensi non-const . Referensi ke pointer const Saya belum pernah menemukan situasi yang akan menjamin itu (kecuali mungkin sebagai variabel referensi const dinyatakan daripada jenis kembali?).
Pertimbangkan jika kita memiliki fungsi yang mengambil pointer const (versus yang tidak):
class TestA
{
private:
char *Array;
public:
TestA(){Array = NULL; Array = new (std::nothrow) char[20]; if(Array != NULL){ strcpy(Array,"Input data"); } }
~TestA(){if(Array != NULL){ delete [] Array;} }
char * const &GetArray(){ return Array; }
void ModifyArrayConst(char * const Data)
{
Data[1]; //This is okay, this refers to Data[1]
Data--; //Produces an error. Don't want to Decrement that.
printf("Const: %c\n",Data[1]);
}
void ModifyArrayNonConst(char * Data)
{
Data--; //Argh noo what are you doing?!
Data[1]; //This is actually the same as 'Data[0]' because it's relative to Data's position
printf("NonConst: %c\n",Data[1]);
}
};
int main()
{
TestA Temp;
Temp.ModifyArrayNonConst("ABCD");
Temp.ModifyArrayConst("ABCD");
}
Kesalahan dalam const menghasilkan pesan:
kesalahan: penurunan 'data' hanya baca parameter
Mana yang baik karena kita mungkin tidak ingin melakukan itu, kecuali kita ingin menyebabkan masalah yang disebutkan dalam komentar. Jika kami mengedit penurunan dalam fungsi const, berikut ini terjadi:
NonConst: A
Const: B
Jelas, meskipun A adalah 'Data [1]', itu diperlakukan sebagai 'Data [0]' karena pointer NonConst mengizinkan operasi penurunan. Dengan const diterapkan, seperti orang lain menulis, kami menangkap bug potensial sebelum terjadi.
Salah satu pertimbangan utama lainnya, adalah bahwa pointer const dapat digunakan sebagai referensi semu, dalam hal referensi menunjuk ke tidak dapat diubah (orang bertanya-tanya, jika mungkin ini adalah bagaimana itu diterapkan). Mempertimbangkan:
int main()
{
int A = 10;
int * const B = &A;
*B = 20; //This is permitted
printf("%d\n",A);
B = NULL; //This produces an error
}
Ketika mencoba mengkompilasi, menghasilkan kesalahan berikut:
kesalahan: penugasan variabel hanya baca 'B'
Yang mungkin merupakan hal yang buruk jika referensi konstan ke A diinginkan. Jika B = NULL
dikomentari, kompiler akan dengan senang hati membiarkan kami memodifikasi*B
dan karena itu A. Ini mungkin tidak berguna dengan int, tetapi pertimbangkan jika Anda memiliki satu posisi aplikasi grafis di mana Anda ingin pointer yang tidak dapat dimodifikasi yang merujuk padanya yang dapat Anda lewati sekitar.
Penggunaannya adalah variabel (alasan permainan yang tidak diinginkan), tetapi digunakan dengan benar, itu adalah alat lain dalam kotak untuk membantu pemrograman.