C++強制類型轉換操作符 const_cast


const_cast也是一個強制類型轉換操作符。《C++ Primer》中是這樣描述它的:

1.將轉換掉表達式的const性質。

2.只有使用const_cast才能將const性質性質轉化掉。試圖使用其他三種形式的強制轉換都會導致編譯時的錯誤。(添加const還可以用其他轉換符,如static_const

3.除了添加const或刪除const特性,使用const_cast符來執行其他任何類型的轉換都會引起編譯錯誤。(volatile限定符也包括,不過我不怎么了解,本文主要說const)

 

對於第一點,轉換掉表達式的const性質,意思是可以改變const對象的值了嗎?一開始我的確是這樣子認為的,於是我敲出了如下的代碼:

int main() { const int constant = 26; const int* const_p = &constant; int* modifier = const_cast<int*>(const_p); *modifier = 3; cout<< "constant: "<<constant<<endl; cout<<"*modifier: "<<*modifier<<endl; system("pause"); }

然而程序並沒有像預想的那樣輸出兩個3,運行結果是這樣的:

 

 

看來C++還是很厚道的,聲明為const的變量來說,常量就是常量,任你各種轉化,常量的值就是不會變。這是C++的一個承諾。

那既然const變量的值是肯定不會發生變化的,還需要這個const_cast類型轉化有何用?這就引出了const_cast的最常用用法:

如果有一個函數,它的形參是non-const類型變量,而且函數不會對實參的值進行改動,這時我們可以使用類型為const的變量來調用函數,此時const_cast就派上用場了。

例如:

 

void InputInt(int * num) { cout<<*num<<endl; } int main() { const int constant = 21; //InputInt(constant); //error C2664: “InputInt”: 不能將參數 1 從“const int”轉換為“int *”
    InputInt(const_cast<int*>(&constant)); system("pause"); }

 除此之外,還有另外一種情況const指針能夠派上用場。如果我們定義了一個非const的變量,卻使用了一個指向const值的指針來指向它(這不是沒事找事嘛),在程序的某處我們想改變這個變量的值了,但手頭只持有指針,這是const_cast就可以用到了

int main() { int constant = 26; const int* const_p = &constant; int* modifier = const_cast<int*>(const_p); *modifier = 3; cout<< "constant: "<<constant<<endl; cout<<"*modifier: "<<*modifier<<endl; system("pause"); }

 

 總結一下上文:const_cast絕對不是為了改變const變量的值而設計的!

        在函數參數的傳遞上const_cast的作用才顯現出來。

>>>>>>>>>>>>>>>>>> >>>分割線>>>>>>>>>>>>>>>>>>>>>>>>>

const_cast中的未定義行為

 上面的第一段程序,輸出變量constant與*modefier的地址后....

int main() { const int constant = 26; const int* const_p = &constant; int* modifier = const_cast<int*>(const_p); *modifier = 3; cout<< "constant: "<<constant<<" adderss: "<< &constant <<endl; cout<<"*modifier: "<<*modifier<<" adderss: " << modifier<<endl; system("pause"); }

運行結果:

它們的地址是一樣的,值卻不同。具體原因我還是不大清除。在另外一些博客中看到, *modifier = 3; 這種操作屬於一種“未定義行為”,也即是說操作結果C++並沒有明確地定義,結果是怎樣的完全由編譯器的心情決定。對於未定義的行為,我們只能避免之。

關於const_cast是否安全的討論

逛了一些網站,大致有如下觀點:

const_cast is safe only if you're casting a variable that was originally non-const. For example, if you have a function that takes a parameter of a const char *, and you pass in a modifiable char *, it's safe to const_cast that parameter back to a char * and modify it. However, if the original variable was in fact const, then using const_cast will result in undefined behavior.

也即是上文中所說的const_cast的二種適用情況。

 

I would rather use static cast for the adding constness: static_cast<const sample*>(this). When I'm reading const_cast it means that the code is doing something potentially dangerous, so i try to avoid it's use when possible.

也有人認為const_cast本身就給潛在危險帶來可能,所以還是盡可能不用它了。
當需要給變量添加const屬性時,使用更為安全的static_cast來代替const_cast。

這里附上討論鏈接。const_cast是否安全?

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM