**自:http://hi.baidu.com/sangwf/blog/item/0be10af482d0c46edcc47464.html
我一直認為技術是沒有止境的,不管你怎麼去學,總有你沒有掌握的地方。但是,人,是不能停下腳步的。
今天在檢查乙個mfc程式,看到getsafehwnd函式,於是讓我想明白到底它比m_hwnd成員變數safe在**?到網上查了一下資料,發現了getsafehwnd的實現:
_afxwin_inline hwnd cwnd::getsafehwnd() const
開始一看感覺不會吧?這有意義麼?this為null了,函式還能呼叫嗎?於是寫了乙個簡單的程式來做測試,**如下:
class a
測試發現,程式能夠正常執行。把p賦乙個非空值如p=(a*)123; 同樣如此。於是想搞明白這到底是怎麼一回事。雖然以前明白類成員函式中其實是隱藏了乙個this指標,但不同的例項在呼叫函式時是如何工作的,還不是很清楚。通過這個測試,才能我徹底明白。
對於乙個類,在編譯好的彙編**中,只有乙份**拷貝,但是有不同的例項空間。比如我們定義a a,b;我們呼叫a.f()和b.f()時,會跳轉到類**中f()函式的實現部分。
但如果你要引用成員變數,比如a.i,那麼程式需要找到a在記憶體中的位址,然後通過便宜量找到成員i的位址。如果f()中加上一句cout《在函式的彙編**中,有乙個變數this,你在做函式類的函式呼叫的時候,類似與函式引數一樣壓到棧上去,雖然不同例項執行了同一段**,因為this不同,得到的結果當然不同。如果你要訪問成員變數,而this是乙個非法位址,當然會引起崩潰。
綜上可知,即時乙個函式呼叫正常,還不能確定指標非空,很可能是因為成員函式中沒有使用成員變數的緣故。看來,這還真是乙個搞笑的bug。
這是我自己的一段**:
int_tmain(
intargc, _tchar
*argv)
delete釋放了praxis所指向的堆位址中的資料,並且指標被賦為空了, 當呼叫praxis->praxis2()時,雖然這個時候praxis指標已經空了,但由於praxis2方法中沒有使用成員變數,所以,程式並沒有試圖去訪問堆,也就不會引起error或者將系統搞崩潰。
下面是全部的**: //
dstring.h
//#ifndef dstring_h
#define
dstring_h
#pragma
once
#include
<
string
>
using
namespace
std;
class
dstring
;#endif
//dstring.cpp
//#include
"stdafx.h
"#include
"dstring.h
"#include
<
string
>
#include
<
stdio.h
>
#include
<
iostream
>
#include
<
cctype
>
dstring::dstring(
void
)dstring::
~dstring(
void
)void
dstring::praxis1(
const
string
&leftstr,
const
string
&rightstr)
else
else}}
string
dstring::praxis2(
void
)article
+=sentence;
firstenter
=false;}
return
article;
}string
dstring::praxis3(
void
)for
(string
::size_type index =0
; index
!=article.size(); index ++)
}return
article;
}
空指標的成員函式呼叫
指標為null了,函式還能呼叫嗎?於是寫了乙個簡單的程式來做測試,如下 class a 測試發現,程式能夠正常執行。把p賦乙個非空值如p a 123 同樣如此。於是想搞明白這到底是怎麼一回事。雖然以前明白類成員函式中其實是隱藏了乙個this指標,但不同的例項在呼叫函式時是如何工作的,還不是很清楚。通...
空指標可以呼叫成員函式?
有下面乙個簡單類 class a 用乙個空指標呼叫上面的fun函式 a pa null pa fun 講道理,空指標應當是 不可用 的,自然也不能呼叫其成員函式了,但是結果卻出乎意料地正確執行了 為什麼?其實,關鍵在於每個成員函式的this指標。其實,c 類的成員函式與傳統c的函式並沒有什麼不同,只...
C 空指標呼叫成員函式
如果在c 裡用空指標呼叫成員函式會發生什麼情況呢?以下面類為例 class a void geta void seta int x virtual void test 首先我們用空指標p去呼叫成員方法show 發現是可以成功呼叫的 呼叫geta 發現程式可以編譯成功,但執行失敗,並返回了乙個錯誤碼 ...