[C/C++]_[0基礎]_[static_cast,reinterpret_cast,dynimic_cast的使用情境和差別]

來源:互聯網
上載者:User

標籤:everyone   情況   ever   blog   不能   log   rom   logs   class   


情境:

1. C++的對象差別於C的原因是他們能夠有繼承關係, 方法有重載, 覆蓋關係等, 他們的對象記憶體資料結構因此也比較複雜.

2. 非常多情況下我們須要一個父類來儲存子類的指標對象進行通用方法的操作。涉及到詳細某個子類對象特定操作時又須要強制轉換為子類。那麼這時候該用什麼好呢?

答: 假設不須要類型檢查的話就直接用C的強制轉換就可以(B*)c. 可是C++ 之父並不推薦使用C的強制類型轉換;

原因1是沒有編譯器檢查.

原因2是對象指標在子類父類之間轉換時所相應的地址值可能會變化, 這樣用C的轉換會有誤導的可能在那裡.


看範例和凝視說明吧:

test.cpp

#include <iostream>class A{public:A(){}~A(){}int i;int j1;void Test(){ std::cout << "TestA" << std::endl;}/* data */};class C{public:C(){}~C(){}int j;void Test(){ std::cout << "TestC" << std::endl;}/* data */};class B : public A,public C{public:B(){}~B(){}void Test(){ std::cout << "TestB" << std::endl;}/* data */};class K{};// static_cast: 能夠進行類型上行和下行轉換,會進行類型檢查.// reinterpret_cast: 和C的強轉一樣,不做類型檢查,能夠從隨意指標類型轉換為其它指標類型,非指標類型不能轉,比方char to int.// dynimic_cast:  僅僅適用於多態的類(帶virtual)int main(int argc, char const *argv[]){A* a = new A();B* b = new B();C* c = b;std::cout << "(int*)a* :" << (int*)a << " (int)a:" << (int)a << " reinterpret_cast<int>(a):"       << reinterpret_cast<int>(a) << std::endl;std::cout << "(int*)b :" << (int*)b << " (int)b:" << (int)b << " reinterpret_cast<int>(b):"       << reinterpret_cast<int>(b) << std::endl;// 1.這裡假設把c轉換為(K*)c,編譯不會報錯,可是假設使用static_cast<K*>編譯會報錯.// 由於static_cast會進行上行的類型檢查.    // 注意: 這裡(int*)c的地址和上邊的(int*)b地址是不一樣的,由於他們不是多態關係,並且A,C有成員變數,因此會有位移量.(沒有virtual)std::cout << "(int*)c :" << (int*)c << " (int)c:" << (int)c << " reinterpret_cast<int>(c):"       << reinterpret_cast<int>(c) <<  " (B*)c: " << (B*)c << " static_cast<B*>(c):"       << static_cast<B*>(c) << " static_cast<C*>(b):"       << static_cast<C*>(b)      << std::endl;    // 下面編譯會報錯,dynimc_cast不同意非多態轉換,由於沒有virtual// ////error: cannot dynamic_cast ‘c‘ (of type ‘class C*‘) to type ‘class B*‘ (source type is not polymorphic)// 假設C的建構函式加virtual的話是能夠轉的,並且帶virtual表的地址不會變.// std::cout << "c* :" << (int*)c << ":" << (int)c << ":" //       << dynamic_cast<B*>(c) << ":"//       << std::endl;      return 0;}

輸出:

(int*)a* :0x2c64e0 (int)a:2909408 reinterpret_cast<int>(a):2909408(int*)b :0x2c2378 (int)b:2892664 reinterpret_cast<int>(b):2892664(int*)c :0x2c2380 (int)c:2892672 reinterpret_cast<int>(c):2892672 (B*)c: 0x2c2378 static_cast<B*>(c):0x2c2378 static_cast<C*>(b):0x2c2380

所以你看到下面static_cast的使用方法不要認為奇怪, 它是為了使用編譯器檢查.

    template<typename T> void** IID_PPV_ARGS_Helper(T** pp)     {        static_cast<IUnknown*>(*pp);    // make sure everyone derives from IUnknown        return reinterpret_cast<void**>(pp);    }



參考:

http://www.cnblogs.com/chio/archive/2007/07/18/822389.html



[C/C++]_[0基礎]_[static_cast,reinterpret_cast,dynimic_cast的使用情境和差別]

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.