C++進階——類型轉換符(參考百度文庫)

       標準C++中有四個類型轉換符:static_cast、dynamic_cast、reinterpret_cast、和const_cast。下面介紹其中的兩種。

第一種:static_cast

用法:static_cast < type-id > ( expression )

         圓括號、尖括號都不能少,否則編譯程序時會報錯

功能:該運算符把expression轉換爲type-id類型,但沒有運行時類型檢查來保證轉換的安全性。

        ①用於類層次結構中基類和子類之間指針或引用的轉換。

                  進行上行轉換(把子類的指針或引用轉換成基類表示)是安全的;

                  進行下行轉換(把基類指針或引用轉換成子類表示)時,由於沒有動態類型檢查,所以是不安全的。

        ②用於基本數據類型之間的轉換。如把int轉換成char,把int轉換成enum。這種轉換的安全性也要開發人員來保證。 
        ③把空指針轉換成目標類型的空指針。 

        ④把任何類型的表達式轉換成void類型。 
注意:static_cast不能轉換掉expression的const、volitale、或者__unaligned屬性。

第二種:dynamic_cast

       主要用於執行“安全的向下轉型(safe down casting)”,也就是說,要確定一個對象是否是一個繼承體系中的一個特定類型。

用法:dynamic_cast < type-id > ( expression )

       該運算符把expression轉換成type-id類型的對象。Type-id必須是類的指針、類的引用或者void *;如果type-id是類指針類型,那麼expression也必須是一個指針,如果type-id是一個引用,那麼expression也必須是一個引用。

       dynamic_cast主要用於類層次間的上行轉換和下行轉換,還可以用於類之間的交叉轉換。

       在類層次間進行上行轉換時,dynamic_cast和static_cast的效果是一樣的;在進行下行轉換時,dynamic_cast具有類型檢查的功能,比static_cast更安全。

       在類層次間進行上行轉換時,dynamic_cast和static_cast的效果是一樣的;在進行下行轉換時,dynamic_cast具有類型檢查的功能,比static_cast更安全。

#include <iostream>
using namespace std;
class B
{
public:
	B(int n)
	{
		m_iNum=n;
	}
	virtual ~B(){}
	virtual void foo(){};
private:
    int m_iNum;
};

class D:public B
{ 
public:
	D(int n):B(n)
	{ m_szName = 20; }
	~D(){}
	void set(int n)
	{
		m_szName = n;
	}
	int get()
	{
		return m_szName ;
	}
private:	
	int m_szName ; 
};
  
void func(B *pb)
{ 
    D *pd1 = static_cast<D *>(pb);
	pd1->set(30);
	cout<<"member of D: m_szName = "<<pd1->get()<<endl;
	
    D *pd2 = dynamic_cast<D *>(pb);	
	if(pd2==NULL)
	{
		cout<<"pd2 is NULL"<<endl;
		return ;
	}
	pd2->set(30);
	cout<<"member of D: m_szName = "<<pd2->get()<<endl;
}

int main()
{
	B b(10);
	D d(10);
	cout<<"pass on pointer of B:\n";
	func(&b);
	cout<<"pass on pointer of D:\n";
	func(&d);
	cout<<"\n";
	return 0;
}

運行結果:

        pass on pointer of B:
        member of D: m_szName = 30
        pd2 is NULL
        pass on pointer of D:
        member of D: m_szName = 30
        member of D: m_szName = 30

          在上面的代碼段中,在函數func的參數列表中pb爲基類對象指針,可接收B類型對象指針,也可以接收D類型對象指針。如果pb指向一個D類型的對象,pd1和pd2是最終結果一樣的,並且對這兩個指針執行D類型的任何操作都是安全的;但是,如果pb指向的是一個 B類型的對象,那麼pd1將是一個指向B類型對象的指針,對它進行D類型的操作將是不安全的(如訪問m_szName),而pd2將是一個空指針。另外要注意:B要有虛函數,否則會編譯出錯;static_cast則沒有這個限制。這是由於運行時類型檢查需要運行時類型信息,而這個信息存儲在類的虛函數表(關於虛函數表的概念,詳細可見<Inside c++ object model>)中,只有定義了虛函數的類纔有虛函數表,沒有定義虛函數的類是沒有虛函數表的。

        另外,dynamic_cast還支持交叉轉換。請看以下代碼:

class A
{ 
public: 
	int m_iNum;
 	virtual void f(){}
};  
class B:public A
{ };  
class C:public A
{ };  
void func()
{ 
	B *p = new B; 
	p->m_iNum = 100; 
	C *pd1 = static_cast<C *>(p); //編譯出錯
	C *pd2 = dynamic_cast<C *>(p); //pd2的結果爲NULL 
	delete b; 
}  

另外兩種類型轉換的具體使用見:http://wenku.baidu.com/view/a9356b80d4d8d15abe234e32.html

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