class ca{public:private:int a;};class cb:public ca{public:virtual void vf(int){}private:int b;};class cc:public cb{public: virtual void vf(int){}private:int c;};cc*pc = new cc;cb*pb = pc;ca*pa = pa;
則,此時pc 指向的記憶體地區為:
cc中所包含的記憶體有四部分:
1.虛指標(vptr)
2.基類ca中的資料
3.基類cb中的資料
4.cc自己私人的資料
基本按繼承的方向排布。
進行:pb = pc操作時,指標casting是有類型的,pb所指向的只是cc類中所包含cb那一部分。
在這個例子裡,比較幸運,cc與cb的前半部分是相同的,因此pb的值與pc相同。
但pa = pc,就不一樣了。
ca中沒有virtual函數,也就沒有vptr。因此,cc類中包含ca的那一部分,並不是從最cc最開始那段記憶體開始 ,因此這裡pa 就不等於 pc了。
更加直觀的一個例子是多重繼承的時候:
class ca2
{
private:
int a;
};
class cb2
{
private:
int b;
};
class cc2:public ca2,public cb2
{
private:
int c;
};
考慮:
cc2*pc2 = new cc2;
cb2*pb2 = pc2;
ca2*pa2 = pc2;
此時pc2指向的記憶體
但pb2所指向的卻是:
習慣了c的程式猿在這種類型轉換上大概會覺得不可思議,但從c++的角度來看,這卻是繼承,多態的本質,
更加強調類型,轉換不僅僅是類型的轉換,代表的意義和內容也變了。
還有更tricky的。
如上pb2與pc2的16進位值雖然不同,但如果進行如下類似的判斷:
if(pb2 == pc2)
{
}
pb2 == pc2卻又是true!!!
c程式猿表示,真傷不起。
難怪圍繞c/c++有過那麼多的爭論。與c的簡潔實在比起來,c++確實多了很多很多東西。
c程式中那種一切盡在掌握中的感覺到了c++裡被一再動搖。
c程式猿表示安全感全沒了!命運已經不受自己控制了!
#c/c++