即使看了幾次《Effective C++》item 27 "Minimize casting", 還是不明白 C style cast 有什麼重大問題。只覺得新的 cast 比較明確安全, 但寫起來很囉唆, 又是角括號又是括號 (愛惜手指, 請從少按 shift 做起)。一直以為 C style cast 等同於 static_cast, 這樣的話, 在使用 static_cast 的場合, 就偷懶寫成 C style cast 吧。
今天看到 Ken 寫的 On C-Style Cast in C++, 才發覺情況和我想得不同。於是寫個小程式驗證一下:
$ cat b.cpp -n 1 class A {}; 2 class B : public A {}; 3 class C {}; 4 5 int main(void) { 6 A* a = new A(); 7 B* b = (B*)a; 8 C* c = (C*)a; 9 B* b2 = static_cast<B*>(a); 10 C* c2 = static_cast<C*>(a); 11 return 0; 12 } $ g++ b.cpp -o b b.cpp: In function ‘int main()’: b.cpp:10:28: error: invalid static_cast from type ‘A*’ to type ‘C*’
果真 C style cast 可以隨意轉換, static_cast 限制較為嚴格一些, 但是 pointer-to-base 仍可透過 static_cast 轉成 pointer-to-derived (即使轉型後會有問題)。若需要更安全的作法, 可以用 dynamic_cast, 看轉完的值是否為空指標, 可以知道是否能安全轉過去。代價是會增加執行時間, 詳細說明見《Effective C++》item 27 "Minimize casting"。關於轉型最重要的觀念, 大概就是盡量別轉型吧。
沒有留言:
張貼留言