static_cast


static_cast一般用來將枚舉類型轉換成整型,或者整型轉換成浮點型。也可以用來將指向父類的指針轉換成指向子類的指針。做這些轉換前,你必須確定要轉換的數據確實是目標類型的數據,因為static_cast不做運行時的類型檢查以保證轉換的安全性。也因此,static_cast不如dynamic_cast安全。對含有二義性的指針,dynamic_cast會轉換失敗,而static_cast卻直接且粗暴地進行轉換。這是非常危險的。

 

比如:

class B {};

class D : public B {};

void f(B* pb, D* pd) {
   D* pd2 = static_cast<D*>(pb);   // Not safe, D can have fields
                                   // and methods that are not in B.

   B* pb2 = static_cast<B*>(pd);   // Safe conversion, D always
                                   // contains all of B.
}

 

上面的第一個類型轉換是不安全的。比如,一旦使用pd2調用了一個子類D有而父類B沒有的方法,則程序就會因越界訪問而崩潰。

static_cast和dynamic_cast都可以用於類層次結構中基類和子類之間指針或引用的轉換。所不同的是,static_cast僅僅是依靠類型轉換語句中提供的信息(尖括號中的類型)來進行轉換;而dynamic_cast則會遍歷整個類的繼承體系進行類型檢查。比如:

class B {
public:
   virtual void Test(){}
};
class D : public B {};

void f(B* pb) {
   D* pd1 = dynamic_cast<D*>(pb);
   D* pd2 = static_cast<D*>(pb);
}

 

如果pb確實是指向一個D類型的對象,那pd1和pd2的值是相同的,即使pb為NULL。

如果pb實際指向的是一個B類型的對象,那dynamic_cast就會轉換失敗,並返回NULL(此時pd1為NULL);而static_cast卻依據程序員指定的類型簡單地返回一個指針指向假定的D類型的對象(此時pd2不為NULL),這當然是錯誤的。

static_cast還可以在兩個類對象之間進行轉換,比如把類型為A的對象a,轉換為類型為B的對象。如下:

class A;
class B;

A a;
B b;
b = static_cast<B>(a);

 

此過程可以看做是以a為參數構造一個B類型的臨時對象,然后再把這個臨時對象賦值給b。如下:

class A;
class B;

A a;
B b;

B c(a);

b = c;

 

所以,如果讓以上代碼通過編譯,那么B類必須含有以A類的對象(或對象的引用)為參數的構造函數。如下:

B(A& a)
{
	// ...
}

 

這實際上是把轉換的工作交給構造函數去做了。

static_cast最常用的是基本類型直接的轉換,比如char與int、int與float、enum與int之間的轉換。在把int轉換為char時,如果char沒有足夠的比特位來存放int的值(int>127或int<-127時),那么static_cast所做的只是簡單的截斷,及簡單地把int的低8位復制到char的8位中,並直接拋棄高位。在把int轉換為enum時,如果int的值沒有落進enum的范圍內,則enum的值將是“未定義”的。比如,定義一個枚舉類型Week,它包含周一到周日七天:

enum Week
{
	Monday = 1,
	Tuesday,
	Wednesday,
	Thursday,
	Friday,
	Saturday,
	Sunday
};

 

此時如果把值為8的int轉換為week類型,那么這個Week變量不會是周一到周日的任何一天。

Week noday = static_cast<Week>(8);

 

如果你用“%d”格式把它打印出來,你會發現,它的值確實是8。但這已經超出周一到周日了。世界上沒有“星期八”,不是嗎?

static_cast甚至可以把任何一個表達式轉換為void類型。

再次提醒,static_cast完全靠程序員自己去保證轉換的正確性。

static_cast轉換的目標類型可以帶const、volatile或__unaligned屬性。但static_cast不能把源類型的這些熟悉移除。如果想強制移除一個變量的const、volatile或__unaligned屬性,請參考const_cast操作符。

小結一下:

static_cast常用來進行基本類型直接的轉換,如char與int、int與float、enum與int之間;

static_cast也可以轉換用戶自定義類型,但目標類型必須含有相應的構造函數;

static_cast還可以轉換對象的指針類型,但它不進行運行時類型檢查,所以是不安全的;

static_cast甚至可以把任何表達式都轉換成void類型;

satic_cast不能移除變量的const屬性,請參考const_cast操作符;

static_cast進行的是簡單粗暴的轉換,所以其正確性完全由程序員自己保證。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM