dynamic_cast, reinterpret_cast, static_cast and const_cast 學習

dynamic_cast, reinterpret_cast, static_cast and const_cast

在C語言中,經常會遇到類型轉換的一些東西。類型轉換分爲:顯示類型轉換和隱式類型轉換。

隱式類型轉換:

所謂隱式類型轉換就是語言本身,使用編譯器,自動就給我們轉成了我們需要的類型

比如如下代碼:

short a=2000;
int b;
b=a;

但是要主要一點,數據類型轉換,可以低長度的轉換成高長度的,否則會丟失數據,出現意想不到的問題。

顯示類型轉換:

在c語言裏,我們使用

short a=2000;
int b;
b = (int) a;    // c-like cast notation
b = int (a);    // functional notation

但是在c++中,我們使用顯示類型轉換使用瞭如下四個關鍵字
dynamic_cast, reinterpret_cast, static_cast and const_cast

使用方法,如

dynamic_cast <new_type> (expression)
reinterpret_cast <new_type> (expression)
static_cast <new_type> (expression)
const_cast <new_type> (expression)

尖括號裏是我們想要expression轉換而成的類型。

他們都各司其職,在不同的語義環境下使用,


1.dynamic_cast

只能使用在類的指針或者引用之上。因此我們使用它子類轉換成父類時候使用

如下例子:

class CBase { };
class CDerived: public CBase { };

CBase b; CBase* pb;
CDerived d; CDerived* pd;

pb = dynamic_cast<CBase*>(&d);     // 可以: derived-to-base
pd = dynamic_cast<CDerived*>(&b);  // 錯誤: base-to-derived


完成實現

// dynamic_cast
#include <iostream>
#include <exception>
using namespace std;

class CBase { virtual void dummy() {} };
class CDerived: public CBase { int a; };

int main () {
  try {
    CBase * pba = new CDerived;
    CBase * pbb = new CBase;
    CDerived * pd;

    pd = dynamic_cast<CDerived*>(pba);
    if (pd==0) cout << "Null pointer on first type-cast" << endl;

    pd = dynamic_cast<CDerived*>(pbb);
    if (pd==0) cout << "Null pointer on second type-cast" << endl;

  } catch (exception& e) {cout << "Exception: " << e.what();}
  return 0;
}

從以上例子可以看到,成功轉換是返回其地址,如果沒成功,就返回一個0值。

2.static_cast
常量性的轉換,比如我們可以將int轉換成float類型,將父類轉換成子類的類型。但是這個並不在運行時檢查類型安全,類型安全取決於程序員。

class CBase {};
class CDerived: public CBase {};
CBase * a = new CBase;
CDerived * b = static_cast<CDerived*>(a);
double d=3.14159265;
int i = static_cast<int>(d); 

3.const_cast

This type of casting manipulates the constness of an object, either to be set or to be removed. For example, in order to pass a const argument to a function that expects a non-constant parameter:

解除常量性變量。

// const_cast
#include <iostream>
using namespace std;

void print (char * str)
{
  cout << str << endl;
}

int main () {
  const char * c = "sample text";
  print ( const_cast<char *> (c) );
  return 0;
}

可以可以正常輸出。並不會報編譯異常

4.reinterpret_cast

像低級類型轉換。

reinterpret_cast converts any pointer type to any other pointer type, even of unrelated classes. The operation result is a simple binary copy of the value from one pointer to the other. All pointer conversions are allowed: neither the content pointed nor the pointer type itself is checked.

class A {};
class B {};
A * a = new A;
B * b = reinterpret_cast<B*>(a);

最後,想說的是,不建議使用強制類型轉換,Effective c++ 條款27:儘量少做轉型動作。

更多文章,歡迎訪問:http://blog.csdn.net/wallwind,轉載請註明出處



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