2008年11月30日 星期日

cast - 轉換

reinterpret_cast
reinterpret_cast<T*>(a)
任何類型的指標均可以轉換成其它類型的指標(反正,就是無敵轉換)
表達式reinterpret_cast<T*>(a)能夠用於諸如char* 到 int*,或者One_class* 到Unrelated_class*等類似這樣的轉換,因此可能是不安全的。


class A { ... };
class B { ... };
void f()
{
  A* pa = new A;
  void* pv = reinterpret_cast<A*>(pa);// pv 現在指向了一個類型為B的對象,這可能是不安全的
  ...
}


static_cast
例:

int num = 0;
double number = 3.14;
num = static_cast<int> (number); // 由double強制轉換成int

在C中可以由以下取代

int num = 0;
double number = 3.14;
num = (int) number; // 由double強制轉換成int


const_cast
在某此情況下,我們需要改變唯讀區域的值,這時可以使用const_cast改變指標的型態
例:

#include <iostream>
using namespace std;

void foo(const int*);

int main() {
  int var = 10;
  cout << "var = " << var << endl;
  foo(&var);
  cout << "var = " << var << endl;
  return 0;
}

void foo(const int* p) {
  int* v = const_cast<int*> (p);
  *v = 20;
}


dynamic_cast
C++提供了dynamic_cast用來將一個基底類別的指標轉型至衍生類別指標,稱之為「安全向下轉型」(Safe downcasting),它在執行時期進行型態轉換動作,首先會確定轉換目標與來源是否屬同一個類別階層,接著才真正進行轉換的動作,檢驗動作在執行時期完成,如果是一個指標,則轉換成功時傳回位址,失敗的話會傳回0,如果是參考的話,轉換失敗會丟出 bad_cast例外。

由於dynamic_cast轉換失敗的話會傳回0,因而運算的結果不可使用,必須先行對轉換結果作檢查才可以。

如果使用參考的話,dynamic_cast在轉換失敗之後會丟出bad_cast例外,所以您必須使用try...catch來處理例外

#include <iostream>
#include <typeinfo>
using namespace std;

class Base {
public:
  virtual void foo() = 0;
};

class Derived1 : public Base {
public:
  void foo() {
    cout << "Derived1" << endl;
  }

  void showOne() {
    cout << "Yes! It's Derived1." << endl;
  }
};

class Derived2 : public Base {
public:
  void foo() {
    cout << "Derived2" << endl;
  }

  void showTwo() {
    cout << "Yes! It's Derived2." << endl;
  }
};

void showWho(Base &base) {
  try {
    Derived1 derived1 = dynamic_cast<Derived1&>(base);
    derived1.showOne();
  }
  catch(bad_cast) {
    cout << "bad_cast 轉型失敗" << endl;
  }
}

int main() {
  Derived1 derived1;
  Derived2 derived2;

  showWho(derived1);
  showWho(derived2);

  return 0;
}

總結C++中的所有強制轉換函數

沒有留言: