const_cast
函數原型:
const_cast < type-id > ( expression )
去掉const屬性:const_cast<int*> (&num),常用,因爲不能把一個const變量直接賦給一個非const變量,必須要轉換。
加上const屬性:const int* k = const_cast<const int*>(j),一般很少用,因爲可以把一個非const變量直接賦給一個const變量,比如:const int* k = j;
1.常量指針被轉化成非常量指針,轉換後指針指向原來的變量(即轉換後的指針地址不變)
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 // 由於ica存放在常量存儲區,這種情況下,似乎會在棧空間中開闢一塊區域存放ica的值,然後ia指向的是棧中的區域
}
2.常量引用轉爲非常量引用
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
}
3.常量對象(或基本類型)不可以被轉換成非常量對象(或基本類型)
void foo()
{
//常量對象被轉換成非常量對象時出錯
const A ca;
A a = const_cast<A>(ca); //不允許
const int i = 100;
int j = const_cast<int>(i); //不允許
}
這種轉換隻是開了一個接口,並不是實質上的轉換。(其實也算是實質上的轉換了,只不過表達上不允許這樣寫)
4.添加const屬性
int main()
{
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_cast只能轉換指針或引用的一個原因吧。
2. 使用const_cast添加const屬性,也是提供了一個接口,來不讓修改其值,不過這個添加const的操作沒有什麼實際的用途。
reinterpret_cast
reinterpret意爲“重新解釋”
reinterpret_cast是C++中與C風格類型轉換最接近的類型轉換運算符。它讓程序員能夠將一種對象類型轉換爲另一種,不管它們是否相關。
reinterpret_cast用在任意指針(或引用)類型之間的轉換;以及指針與足夠大的整數類型之間的轉換;從整數類型(包括枚舉類型)到指針類型,無視大小。
(所謂"足夠大的整數類型",取決於操作系統的參數,如果是32位的操作系統,就需要整形(int)以上的;如果是64位的操作系統,則至少需要長整形(long)。具體大小可以通過sizeof運算符來查看)。
【注意】reinterpret_cast不能用於內置類型之間的轉換,只能用於不同指針之間的轉換。
CBase* pBase = new CBase( ) ; CDerived* pDerived = reinterpret_cast<CDerived*>(pBase) ;
這種類型轉換實際上是強制編譯器接受static_cast通常不允許的類型轉換,它並沒有改變指針值的二進制表示,只是改變了編譯器對源對象的解釋方式。