一. 函式描述:
const_cast ( expression )
主要是用來去掉const屬性,當然也可以加上const屬性。主要是用前者,後者很少用。
去掉const屬性:const_case (&num),常用,因為不能把一個const變數直接賦給一個非const變數,必須要轉換。
加上const屬性:const int* k = const_case(j),一般很少用,因為可以把一個非const變數直接賦給一個const變數,比如:const int* k = j;
二. 使用範圍:
1. 常量指標被轉化成非常量指標,轉換後指標指向原來的變數(即轉換後的指標地址不變)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
class A { public: A() { m_iNum = 0; } public: int m_iNum; }; void foo() { //1. 指標指向類 const A *pca1 = new A; A *pa2 = const_cast<A*>(pca1); //常量物件轉換為非常量物件 pa2->m_iNum = 200; //fine //轉換後指標指向原來的物件 cout<< pca1->m_iNum <<pa2->m_iNum<<endl; //200 200 //2. 指標指向基本型別 const int ica = 100; int * ia = const_cast<int *>(&ica); *ia = 200; cout<< *ia <<ica<<endl; //200 100 } |
2. 常量引用轉為非常量引用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
class A { public: A() { m_iNum = 1; } public: int m_iNum; }; void foo() { A a0; const A &a1 = a0; A a2 = const_cast<A&>(a1); //常量引用轉為非常量引用 a2.m_iNum = 200; //fine cout<< a0.m_iNum << a1.m_iNum << a2.m_iNum << endl; //1 1 200 } |
2. 常量物件(或基本型別)不可以被轉換成非常量物件(或基本型別)。
1 2 3 4 5 6 7 8 9 10 |
void foo() { //常量物件被轉換成非常量物件時出錯 const A ca; A a = const_cast<A>(ca); //不允許 const int i = 100; int j = const_cast<int>(i); //不允許 } |
記住這種轉換隻是開了一個介面,並不是實質上的轉換。(其實也算是實質上的轉換了,只不過表達上不允許這樣寫)
3. 新增const屬性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
int main(int argc, char ** argv_) { int i = 100; int *j = &i; const int *k = const_cast<const int*>(j); //const int *m = j; 感覺和這樣寫差不多 //指的地址都一樣 cout <<i<<","<<&i<<endl; //100, 0012FF78 cout <<*j<<","<<j<<endl; //100, 0012FF78 cout <<*k<<","<<k<<endl; //100, 0012FF78 *j = 200; //*k = 200; //error return 0; } |
三. 總結:
1. 使用const_cast去掉const屬性,其實並不是真的改變原類型別(或基本型別)的const屬性,它只是又提供了一個介面(指標或引用),使你可以通過這個介面來改變型別的值。也許這也是const_case只能轉換指標或引用的一個原因吧。
2. 使用const_case新增const屬性,也是提供了一個介面,來不讓修改其值,不過這個新增const的操作沒有什麼實際的用途(也許是我認識太淺了)。