const_cast and reinterpret_cast

原文鏈接:https://www.cnblogs.com/tianzeng/p/9062074.html

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通常不允許的類型轉換,它並沒有改變指針值的二進制表示,只是改變了編譯器對源對象的解釋方式。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章