c++
是一門功能強大的語言。它既相容了
c中的最重要的內容——指標,又有物件導向的功能,如使用繼承組合以及虛函式實現多型等等。如果使用者對這些內容了解不夠深入具體。則常常在使用
c++的指標時會出現不少問題。現舉一些例子如下。(其中全部例子來自書本或者網上)。
問題**如下:
上面的**編譯都能通過,但是執行的結果卻是出人意料的。問題出在**呢?
setpetage
()函式看似沒有問題,第乙個引數雖然是
pet *
,但是對於傳入的派生類引數可以自動向上轉化成
pet *
型別。但是問題恰恰是在這個函式中產生的。因為類
pet的大小是
4byte
(int m_age
的大小)。而
pet的派生類
dog的大小是
8byte
(基類的大小加上
int m_weight
的大小)。按實際的意圖
dogs
指標應該偏移
8個位元組修改
dogs[1].m_age
的值,但是實際情況是
dogs
指標偏移了
4個位元組修改了
dogs[0].m_weight
的值。
m_age
m_weight
表1 物件dog
變數的儲存方式。
這種問題說明,在使用物件陣列與物件的繼承過程中可能存在的隱患。解決的辦法,可以將
setpetage()
作為pet
類的乙個成員函式封裝起來。函式如下:
這樣就不用傳遞物件陣列指標,就不會造成錯誤。
2、 指標與強制型別轉換的問題。
上面的函式雖然編譯沒有問題,但是一執行就彈出「程式遇到問題需要關閉」對話方塊。對比正確的程式發現在求
pfun2
與正確的**相比,錯誤的**在此處
*(int *)(&b) + 1
加了乙個括號。問題也正是在於此。在此處加括號表示先加
1,再轉換成
int
的指標。而
(int *)*(int *)(&b) + 1
表示先轉變為
int的指標,指標所指的位址再加
1。而實際上
int占有
4個位元組。所有正確的是位址值加了
4而不是1。
以上兩例都是指標所指的型別發生了變化而產生的問題。所以,在使用指標的時候一定要注意指標的型別,防止一些故意或者不經意的轉化而帶來的錯誤或隱患。
4、 關於指標的釋放問題。 在《
c++程式設計思想》這本書中
bruce eckel
寫道:「如果正在刪除的物件的指標是
null
,將不發生任何事情。為此人們經常建議在刪除指標後立即把指標賦值為
null
以免對它刪除兩次。對乙個物件刪除兩次可能會產生某些問題。」的確在實際的程式設計過程中,物件刪除兩次在
vc6.0
的debug
模式下執行會彈出「
debug assertion failed
!」對話方塊。
vc編譯器不允許我們將乙個物件刪除兩遍。雖然我們可以強調注意這個問題,但是有時候在設計類以及使用類的物件時可能不經意就會出現上面的乙個實體地址釋放兩次的問題。最常見的問題就是淺拷貝的問題。見如下**:(本例**於網上內容的關於懸浮指標的**)
上面的**編譯沒有問題。但是在執行時會出現問題。因為類
cmystring
沒有重新拷貝建構函式,也沒有過載
=運算子。所以
在cmystring str3 = str1;
這句呼叫的是預設拷貝建構函式,這是淺拷貝,即
str3.m_pdata
與str1.m_pdata
指向了同乙個物理記憶體。所以在
str3
於str1
析構時,同乙個物理記憶體釋放了兩遍。解決的辦法是:在類
cmystring
中增加拷貝建構函式,重灌
=運算子。
即在類中宣告
cmystring(cmystring& pmy);
operator=(const cmystring& pmy);
定義:
指標的應用是非常靈活的,所以也常常出現問題。這就好比一把雙刃劍。掌握得當,靈活使用,指標將會發揮巨大的作用。如果掌握不清楚,在使用過程中就難免會出現很多問題。在此總結一些例子,希望自己以及看博的人都不再犯此類的錯誤。
指標的有關問題
1.指標和陣列 的區別?答 陣列對應著一塊記憶體區域,而指標是指向一塊記憶體區域。其位址和容量在生命期裡不會改變,只有陣列的內容可以改變 而指標卻不同,它指向的記憶體區域的大小可以隨時改變,而且當指標指向常量字串時,它的內容是不可以被修改的,否則在執行時會報錯。2.指標和引用 的區別?答 1 引用必...
有關於指標函式的問題
哎呀,我剛剛寫了一大堆,點了提交之後什麼都沒了,簡單寫寫吧,暈死 typedef int fp int int fun int n void testfp int n,fp fun fp fp fun int main 這段 是看別人的,就是第一句我沒看懂,於是就有了我的實驗 includevoid...
與類有關的指標小結
1.指向物件的指標 定義形式 類名 指標變數名。使用方式 指標變數名 物件名。2.指向成員函式的指標 定義形式 資料型別名 類名 指標名 參數列列 使用方式 指標變數名 類名 成員函式名 3.指向資料成員的指標 定義形式 資料型別名 指標變數名。使用方式 指標變數名 物件名 資料成員名。4.指向物件...