【轉】C++標準轉換運算子const_cast

來源:互聯網
上載者:User

標籤:code   變數   數組   mod   決定   意義   一點   自增   void   

const_cast轉換符是用來移除變數的const或volatile限定符。

對於const變數,我們不能修改它的值,這是這個限定符最直接的表現。但是我們就是想違背它的限定希望修改其內容怎麼辦呢?

下邊的代碼顯然是達不到目的的:

const int constant = 10;int modifier = constant;

因為對modifier的修改並不會影響到constant,這暗示了一點:const_cast轉換符也不該用在對象資料上,因為這樣的轉換得到的兩個變數/對象並沒有相關性。

只有用指標或者引用,讓變數指向同一個地址才是解決方案,可惜下邊的代碼在C++中也是編譯不過的:

const int constant = 21;int* modifier = &constant // Error: invalid conversion from ‘const int*‘ to ‘int*‘

(上邊的代碼在C中是可以編譯的,最多會得到一個warning,所在在C中上一步就可以開始對constant裡面的資料胡作非為了)

把constant交給非const的引用也是不行的。

const int constant = 21;int& modifier = constant;// Error: invalid initialization of reference of type ‘int&‘ from expression of type ‘const int‘ 

於是const_cast就出來消滅const,以求引起程式世界的混亂。

下邊的代碼就順利編譯通過了:

const int constant = 21;const int* const_p = &constant;int* modifier = const_cast<int*>(const_p);*modifier = 7;

 

為何要去除const限定?

從前面代碼中已經看到,我們不能對constant進行修改,但是我們可以對modifier進行重新賦值。

但是但是,程式世界真的混亂了嗎?我們真的通過modifier修改了constant的值了嗎?修改const變數的資料真的是C++去const的目的嗎?

如果我們把結果列印出來:

cout << "constant: "<< constant <<endl;cout << "const_p: "<< *const_p <<endl;cout << "modifier: "<< *modifier <<endl;/**constant: 21const_p: 7modifier: 7**/

constant還是保留了它原來的值。

可是它們的確指向了同一個地址呀:

cout << "constant: "<< &constant <<endl;cout << "const_p: "<< const_p <<endl;cout << "modifier: "<< modifier <<endl;/**constant: 0x7fff5fbff72cconst_p: 0x7fff5fbff72cmodifier: 0x7fff5fbff72c**/

這真是一件奇怪的事情,但是這是件好事:說明C++裡是const,就是const,外界千變萬變,我就不變。不然真的會亂套了,const也沒有存在的意義了。

IBM的C++指南稱呼“modifier = 7;”為“未定義行為(Undefined Behavior)”。所謂未定義,是說這個語句在標準C++中沒有明確的規定,由編譯器來決定如何處理。

位元運算的左移操作也可算一種未定義行為,因為我們不確定是邏輯左移,還是算數左移。

再比如下邊的語句:v[i] = i++; 也是一種未定義行為,因為我們不知道是先做自增,還是先用來找數組中的位置。

對於未定義行為,我們所能做的所要做的就是避免出現這樣的語句。對於const資料我們更要這樣保證:絕對不對const資料進行重新賦值。

如果我們不想修改const變數的值,那我們又為什麼要去const呢?

原因是,我們可能調用了一個參數不是const的函數,而我們要傳進去的實際參數卻是const的,但是我們知道這個函數是不會對參數做修改的。於是我們就需要使用const_cast去除const限定,以便函數能夠接受這個實際參數。

#include <iostream>using namespace std;void Printer (int* val,string seperator = "\n"){    cout << val<< seperator;}int main(void) {        const int consatant = 20;    //Printer(consatant);//Error: invalid conversion from ‘int‘ to ‘int*‘    Printer(const_cast<int *>(&consatant));        return 0;}

出現這種情況的原因,可能是我們所調用的方法是別人寫的。還有一種我能想到的原因,是出現在const對象想調用自身的非const方法的時候,因為在類定義中,const也可以作為函數重載的一個標識符。

使用const_cast去掉const屬性,其實並不是真的改變原類類型(或基本類型)的const屬性,它只是提供了一個介面(指標或引用 ),使你可以通過這個介面來改變類型的值。也許這也是const_cast只能轉換指標或引用的一個原因吧。

 

【轉】C++標準轉換運算子const_cast

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.