練習19.3
已知存在如下的類繼承體系,其中每個類分別定義了乙個公有的預設建構函式和乙個虛析構函式:
class a;
class b : public a;
class c : public b;
class d : public b, public a;
下面的哪個dynamic_cast將失敗?
(a) a *pa = new c;
b *pb = dynamic_cast< b* >(pa);
(b) b *pb = new b;
c *pc = dynamic_cast< c* >(pb);
(c) a *pa = new d;
b *pb = dynamic_cast< b* >(pa);
解答:這裡需要注意的是」注意轉換指標的時候不會拋異常,只有在轉引用的時候才會拋異常「。
更新如下:
測試**如下:
#include using namespace std;
class a
};class b : public a
};class c : public b
};class d : public b, public a
};#define choose 1
int main()
這裡我們將編譯器換為clang3.4。
這裡使用巨集choose的原因是為了分開不同的小題(因為不同的題會在runtime和compiling-time有問題)
a) 當choose為1時,轉換是沒有問題的,你會在終端或命令列視窗中看到指標指向的位址。
b) 當choose為2時,轉換就會出問題了,這個時候你會在命令列或終端視窗中看到指標指向的位址為0。這是c++在執行時對型別的檢查。
這裡原因可以參見msdn(的 dynamic_cast_3.cpp上的解釋。
c) 當choose為其他值時,編譯都會出問題。我們來看看clang和gcc給出的錯誤資訊:
clang3.4
test.cc:42:11: error: ambiguous conversion from derived class 'd' to base class 'a':
class d -> class b -> class a
class d -> class a
a *pa = new d;
^~~~~
1 error generated.
gcc4.9.2
test.cc:42:15: error: 『a』 is an ambiguous base of 『d』
a *pa = new d;
^
這裡gcc的提示很簡練,clang的提示很豐富。要表達的意思都是乙個,因為這裡使用到了多重繼承,所以這裡轉換有二義性。
這裡有疑問的是從那種繼承方式往a進行轉換(如同clang給出的提示那樣)。
練習19.4
使用上乙個練習定義的類改寫下面的**,將表示式*pa轉換成型別c&:
if(c *pc = dynamic_cast< c* >(pa)) else
catch (bad_cast &e)
}練習19.5
在什麼情況下你應該使用dynamic_cast替代虛函式?
解答:【引用】我們想使用基類物件指標或引用執行某個派生類操作並且該操作不是虛函式。
第十九章 19 1 1節練習
練習19.1 使用malloc編寫你自己的operator new size t 函式,使用free編寫operator delete void 函式。解答 這個也就參考書中實現吧。不過這裡我更傾向於使用模板來實現,不把new的引數寫死。練習19.2 預設情況下,allocator類使用operat...
第十九章 事務
redis的事務是指將多個命令請求打包,一次性地,按順序執行的機制。通過multi exec watch等命令實現事務功能。19.1.1 事務的開始 multi命令的執行代表了乙個事務的開始,會將執行該命令的客戶端由非事務狀態切換成事務狀態 在客戶端狀態的flags屬性中開啟redis multi標...
第十九章 收服蟻獸
第十九章 收服蟻獸 傲天還是一臉的費解,不可思議地看著不斷顫抖變小的蟻獸,同時感覺眉心胎記的位置越來越熱,而在其父的紫眸中則是另外一番景象,只見傲天眉心胎記處的那根線條隨著蟻獸體型越來越小也變得越來越黑,而且是越靠近蟻獸的地方越是顏色越深,並且緩緩地向回拉動,而蟻獸在收縮到 拳頭大小時則慢慢公升空向...