c++ 内存 继承
http://blog.csdn.net/randyjiawenjie/article/details/6829823
1.C++的虛函數是怎樣實現的?
??????C++的虛函數使用了一個虛函數表來存放了每一個虛函數的入口地址,這個虛函數表又使用一個虛函數指針來進行訪問。通常,虛函數指針都放在對象模型的第一個位置存放,這樣訪問徐函數指針的速度最快,沒有偏移量。通過虛函數指針,找到虛函數表,進而再做一個次偏移量計算,來得到真實虛函數的入口地址,從而訪問了虛函數。這樣看來,訪問一個虛函數將使用兩次間接計算,故要失去一些時間效率。另外,使用了虛函數,那么就要消耗一些空間,存放虛函數指針。但是,這都是值得的,為了實現多態。
2.?虛函數表是每個對象一個還是每個類一個呢?
???? 這個事搜狗的面試題目。其實討論過,我之前看到這個問題,立馬就想到了this指針。http://topic.csdn.net/u/20081031/16/6784c211-a475-4af5-a331-c3df887a2d0c.html比較詳細的討論。
??? 每個類只有若干個虛擬函數表,每個對象可以有若干個虛函數表指針。(這都是在多重繼承的情況下出現的。單重繼承的情況下,就是一個對象有一個虛函數表指針,每一個類有一個虛函數表)函數調用的時候會將this指針作為參數發過去,所以沒有必要為每一個對象做一個虛擬函數表。
???? “每個類有一個或多個虛函數表,單純的繼承下來的類有一個虛函數表,虛繼承下來的類就有可能有多個虛函數表(只是有可能),對象沒有虛函數表,但是有指向虛函數表的指針。對象之所一能調用“自己的函數”,是因為類的成員函數不知不覺的在編譯時多了一個this指針參數來識別成員數據屬于哪個對象。”
????關于這個問題,在《more effective c++》中的條款24有詳細敘述,的確是每一個類的一個虛函數表。至于放的的位置,書中也有講述。
3.函數指針和指針函數的區別?
???? 就想通過這個問題來判斷我的C水平?C語言我看的數都有三本。
??? 函數指針,一個指針,指向了函數的調用地址。? void (*fun)(void)
? 指針函數,就是一個函數的返回值是指針。 int *? fun(void)
? 這道題目我真的很冤,指針函數,我真的沒有聽說過。
?? 數組指針和指針數組我知道什么區別
4. C++ 深拷貝和淺拷貝的區別?如果要delete一個淺拷貝,需要注意什么條件?
?? 現在有一個指針p1指向了一個內存空間m1;
?? 淺拷貝就是再用一個新的指針p2指向這片內存空間m1;
?? 深拷貝就是用一個新的指針p3指向m1的副本m2
?? delete一個淺拷貝,首先要測試是不是有其它的指針還在指向這片空間。不然,直接就是野指針了。為什么野指針那么是絕對要禁止的?野指針現在指向了一片內存區間,這片內存區間以前是有意義的,現在被釋放了,操作系統可能會講這邊區間放上其它程序數據。那么,野指針仍然指向了這片區間。如果此時使用野指針,改變了這片內存的數據,那么程序應該直接崩潰。而且,這樣子的崩潰可能出現,可能等一會兒出現,不定。帶來的bug很難查找。
5.? dynamic_cast的用法?
http://blog.csdn.net/wingfiring/article/details/633033
作為四個內部類型轉換操作符之一的dynamic_cast和傳統的C風格的強制類型轉換有著巨大的差別。除了dynamic_cast以外的轉換,其行為的都是在編譯期就得以確定的,轉換是否成功,并不依賴被轉換的對象。而dynamic_cast則不然。在這里,不再討論其他三種轉換和C風格的轉換。
首先,dynamic_cast依賴于RTTI信息,其次,在轉換時,dynamic_cast會檢查轉換的source對象是否真的可以轉換成target類型,這種檢查不是語法上的,而是真實情況的檢查。
先看RTTI相關部分,通常,許多編譯器都是通過vtable找到對象的RTTI信息的,這也就意味著,如果基類沒有虛方法,也就無法判斷一個基類指針變量所指對象的真實類型, 這時候,dynamic_cast只能用來做安全的轉換,例如從派生類指針轉換成基類指針.而這種轉換其實并不需要dynamic_cast參與.
也就是說,dynamic_cast是根據RTTI記載的信息來判斷類型轉換是否合法的。
[cpp]?view plaincopy
pb2將會為NULL指針,pb22將會編譯出錯。
[cpp]?view plaincopy
dynamic_cast < type-id > (?expression?)
該運算符把expression轉換成type-id類型的對象。Type-id必須是類的指針、類的引用或者void*;
如果type-id是類指針類型,那么expression也必須是一個指針,如果type-id是一個引用,那么expression也必須是一個引用。 dynamic_cast主要用于類層次間的上行轉換和下行轉換,還可以用于類之間的交叉轉換。
在類層次間進行上行轉換時,dynamic_cast和static_cast的效果是一樣的;
在進行下行轉換時,dynamic_cast具有類型檢查的功能,比static_cast更安全。
http://blog.csdn.net/wingfiring/article/details/633033dynamic_cast 確實很好地解決了我們的問題,但也需要我們付出代價,那就是與 typeid 相比,dynamic_cast 不是一個常量時間的操作。為了確定是否能完成強制類型轉換,dynamic_cast`必須在運行時進行一些轉換細節操作。因此在使用 dynamic_cast 操作時,應該權衡對性能的影響
5. 請閱讀以下的代碼,試試看,你能發現錯誤或者不恰當地方嗎?(提示: ? 不止一處)
http://topic.csdn.net/t/20061129/14/5194019.html
修改如下:
[cpp]?view plaincopy
6.C++程序進入main函數之前,退出main函數之后會做些什么?
main函數執行之前,主要就是初始化系統相關資源:
1.設置棧指針
2.初始化static靜態和global全局變量,即data段的內容
3.將未初始化部分的賦初值:數值型short,int,long等為0,bool為FALSE,指針為NULL,等等,即.bss段的內容
4.運行全局構造器,C++中構造函數
5.將main函數的參數,argc,argv等傳遞給main函數,然后才真正運行main函數
main 函數之后會執行相反的工作。
總結
- 上一篇: c++实现多态的方法 虚表
- 下一篇: C++ 对象的内存布局