http://blog.csdn.net/star530/article/details/21990081
這篇博文其實和Cocos2dx 3.0關聯性並不大,只是我近來對強制類型轉換惡補了下,寫在這裡當筆記用吧...
抱著羞愧的心理,我決定本文儘量說的簡單、嚴肅點...
以前用C時,習慣用(int)a這樣的格式來強制轉換類型。用cocos2dx,例如下面這種寫法:
- Sprite* sp = (Sprite*)this->getChildByTag(1);
為了完成強制類型轉換,C++中已經為我們提供了4中標準方法,它們是dynamic_cats, static_cast, const_cast, reinterpret_cast,用法形式如:dynamic_cast<類型說明符>(表達式),之所以分成4類,就表示他們各自有著不同的使用環境。
我覺的通常情況下用dynamic_cast最好,它檢查的更嚴格些,其次是static_cast,而後兩者也就是const_cast和reinterpret_cast較之前兩者貌似不太常用(我會告訴你我根本就沒用過嗎...),而且也不推薦使用,const_cast在用於去除const的地方還是有所發揮的,reinterpret_cast在轉換時,不會在內存中進行補足比特位(例如int轉換到double,需要補足4字節),這往往是不安全的,而且代碼也是不可移植的。
所以我主要介紹的還是static_cast和dynamic_cast。
1、static_cast
static_cast類似C風格的強制類型轉換。它適用於基類和子類之間轉換:其中子類指針轉換成父類指針是安全的;但父類指針轉換成子類指針是不安全的。用法如下:
- class A { ... };
- class B { ... };
- class D : public B { ... };
- void f(B* pb, D* pd)
- {
- D* pd2 = static_cast<D*>(pb); // 不安全, pb可能只是B的指針
- B* pb2 = static_cast<B*>(pd); // 安全的
- A* pa2 = static_cast<A*>(pb); //錯誤A與B沒有繼承關係
- }
- auto boy = Sprite::create("boy.png");//創建一個精靈
- boy->setPosition(Point(200,400));
- boy->setTag(99);//設置精靈的tag
- this->addChild(boy,2);
- //在其他函數裡,我們要使用到精靈boy,用下面的方法調用
- auto boy = static_cast<Sprite*>(this->getChildByTag(99));
- boy->setPosition(Point(50,50));//運行後精靈boy的坐標發生改變,說明獲取成功
1、取出一個骰子;
2、使出吃奶的力氣搖骰子;
3、根據點數的大小決定該轉換成什麼類型...................
這裡假設要轉換成LabelTTF類型的(很明顯猜錯了,應該是Sprite型的)
- auto label = static_cast<LabelTTF*>(this->getChildByTag(99));
- label->setString("天才一般的我肯定猜對了,哇哈哈,動感超人!");//呵呵,呵呵
其實我只是想通過這種方法告訴小夥伴們,珍愛生命,遠離賭博。
那麼,有什麼辦法可以避免上述這種不靠譜的強制類型轉換嗎?回答當然是有的,那就是比安全那啥還安全的dynamic_cast
2、dynamic_cast
與其他強制類型轉換不同,dynamic_cast在轉換過程中涉及類型檢查。如果綁定到引用或指針的對象不是目標類型的對象,則dynamic_cast失敗,並返回nullptr。
換句話說:如果你要將Sprite* 強制轉化為LabelTTF,dynamic_cast絕對不允許你這麼亂搞的!它會用返回nullptr的形式告訴你,LabelTTF和Sprite並不是同一物種,重口味者慎入!
下面修改之前的代碼:
與其他強制類型轉換不同,dynamic_cast在轉換過程中涉及類型檢查。如果綁定到引用或指針的對象不是目標類型的對象,則dynamic_cast失敗,並返回nullptr。
換句話說:如果你要將Sprite* 強制轉化為LabelTTF,dynamic_cast絕對不允許你這麼亂搞的!它會用返回nullptr的形式告訴你,LabelTTF和Sprite並不是同一物種,重口味者慎入!
下面修改之前的代碼:
- auto label = dynamic_cast<LabelTTF*>(this->getChildByTag(99));
- if( label )
- {
- label->setString("有了dynamic_cast,老闆再也不用擔心我亂來了");
- }
- else
- {
- CCLOG("Attention : label doesn't point to LabelTTF Objective");
- }
沒有留言:
張貼留言