Saya tidak dapat menemukan banyak informasi tentang const_cast
. Satu-satunya info yang dapat saya temukan (di Stack Overflow) adalah:
Yang
const_cast<>()
digunakan untuk menambah / menghapus const (an) (atau volatil-an) dari variabel.
Ini membuatku gugup. Bisakah menggunakan const_cast
penyebab perilaku yang tidak terduga? Jika ya, apa?
Atau, kapan boleh digunakan const_cast
?
c++
casting
const-cast
Mag Roader
sumber
sumber
const
objek aslinya melaluiconst
referensi / penunjuk de- ed. Sebaliknya, jika Anda hanyaconst_cast
ingin bekerja di sekitar API dengan spesifikasi yang buruk (atau, dalam kasus saya, malas) yang hanya menerima non-const
referensi tetapi hanya akan digunakan dalamconst
metode ... tidak ada masalah sama sekali.Jawaban:
const_cast
aman hanya jika Anda mentransmisikan variabel yang awalnya bukan-const
. Misalnya, jika Anda memiliki fungsi yang mengambil parameter aconst char *
, dan Anda meneruskan sebuah modifiablechar *
, maka aman untukconst_cast
parameter itu kembali ke achar *
dan memodifikasinya. Namun, jika variabel aslinya ternyataconst
, maka penggunaanconst_cast
akan menghasilkan perilaku yang tidak terdefinisi.void func(const char *param, size_t sz, bool modify) { if(modify) strncpy(const_cast<char *>(param), sz, "new string"); printf("param: %s\n", param); } ... char buffer[16]; const char *unmodifiable = "string constant"; func(buffer, sizeof(buffer), true); // OK func(unmodifiable, strlen(unmodifiable), false); // OK func(unmodifiable, strlen(unmodifiable), true); // UNDEFINED BEHAVIOR
sumber
§7.1.5.1/4 says Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const object during its lifetime (3.8) results in undefined behavior
Upaya apa pun ! Tidak ada kata-kata tentang variabel asli.const_cast
untuk menghapusconst
dari sesuatu yang awalnya dinyatakanconst
. Tapi itu adalah UB untuk benar-benar mencoba untuk menulis ke objek. Selama Anda baru saja membaca Anda baik-baik saja danconst_cast
itu sendiri tidak menyebabkan UB. Itu ide yang buruk, tapi itu bukan UB secara inheren.Saya dapat memikirkan dua situasi di mana const_cast aman dan berguna (mungkin ada kasus valid lainnya).
Salah satunya adalah ketika Anda memiliki instance, referensi, atau pointer const, dan Anda ingin meneruskan pointer atau referensi ke API yang tidak benar, tetapi Anda TERTENTU tidak akan mengubah objek. Anda dapat const_cast penunjuk dan meneruskannya ke API, percaya bahwa itu tidak akan benar-benar mengubah apa pun. Sebagai contoh:
void log(char* text); // Won't change text -- just const-incorrect void my_func(const std::string& message) { log(const_cast<char*>(&message.c_str())); }
Yang lainnya adalah jika Anda menggunakan kompiler lama yang tidak mengimplementasikan 'mutable', dan Anda ingin membuat kelas yang secara logis const tetapi bukan const bitwise. Anda bisa const_cast 'this' dalam metode const dan memodifikasi anggota kelas Anda.
class MyClass { char cached_data[10000]; // should be mutable bool cache_dirty; // should also be mutable public: char getData(int index) const { if (cache_dirty) { MyClass* thisptr = const_cast<MyClass*>(this); update_cache(thisptr->cached_data); } return cached_data[index]; } };
sumber
const_cast
dapat menyebabkan perilaku yang tidak terdefinisi, bukan aplikasi berguna apa darinyaconst_cast
merupakan jawaban yang valid. Tidak adahe
pertanyaan karena pertanyaannya sendiri adalah subjeknya.Saya merasa sulit untuk percaya bahwa itulah satu - satunya informasi yang dapat Anda temukan tentang const_cast. Mengutip dari hit Google kedua :
sumber
const_cast
. Atau panggil metode const di atasnya.Apa yang Adam katakan. Contoh lain di mana const_cast dapat membantu:
struct sample { T& getT() { return const_cast<T&>(static_cast<const sample*>(this)->getT()); } const T& getT() const { /* possibly much code here */ return t; } T t; };
Pertama kita menambahkan const ke tipe
this
poin ke, lalu kami memanggil versi constgetT
, dan kemudian kami menghapus const dari tipe kembalian, yang valid karenat
harus non-const (jika tidak, versi non-konst darigetT
tidak dapat memiliki telah dipanggil). Ini bisa sangat berguna jika Anda memiliki badan fungsi yang besar dan Anda ingin menghindari kode yang berlebihan.sumber
const_cast
ataustatic_cast
lebih.const_cast
hanya dapat melakukan apa yang Anda inginkan: ubah cv-qualifier.static_cast
dapat 'diam-diam' melakukan operasi lain yang tidak Anda inginkan. Namun, pemeran pertama sepenuhnya aman, danstatic_cast
cenderung lebih aman daripadaconst_cast
. Saya pikir ini adalah situasi di manaconst_cast
mengkomunikasikan niat Anda dengan lebih baik, tetapistatic_cast
mengkomunikasikan keamanan tindakan Anda dengan lebih baik.Jawaban singkatnya adalah tidak, ini tidak aman.
Jawaban panjangnya adalah jika Anda cukup tahu untuk menggunakannya, maka itu harus aman.
Saat Anda mentransmisi, yang pada dasarnya Anda katakan adalah, "Saya tahu sesuatu yang tidak diketahui kompilator." Dalam kasus const_cast, yang Anda katakan adalah, "Meskipun metode ini menggunakan referensi atau penunjuk non-const, saya tahu bahwa itu tidak akan mengubah parameter yang saya berikan."
Jadi jika Anda benar-benar tahu apa yang Anda klaim tahu dalam menggunakan pemeran, maka tidak masalah untuk menggunakannya.
sumber
Anda menghancurkan peluang keamanan thread, jika Anda mulai memodifikasi hal-hal yang menurut compiler adalah const.
sumber
const
.const
adalah kepercayaan.const_cast
melanggar kepercayaan itu :(