⑴ 為啥用空指針調用函數程序不崩潰
class MyClass{public:int i;void hello(){printf("hello/n");}void print(){printf("%d/n", i);}};void main(){MyClass* pmy = NULL;pmy-hello();}看上面的這段代碼,似乎很詭異。 用一個空指針調用成員函數,簡直是天大的錯誤,可以遺憾的是,...
⑵ 為什麼C++調用空指針對象的成員函數可以運行通過
很多時候代碼中需要的是指針的類型,而不是指針中的值;所以指向NULL也是無所謂的;比如多重繼承的時候,
⑶ c++中空指針對象訪問成員問題
我這么說吧。因為fun3函數里沒有直接或間接用到this指針。
什麼叫直接?你寫了 this 在裡面,並且這個this被訪問了。
什麼叫間接?你沒直接寫 this 但是用了成員變數等。
因為C++編譯的時候,fun3是靜態綁定的,所以運行的時候沒有「查找對象上的fun3函數」的過程,對象有沒有存在也不影響。
你可以嘗試一下把fun3改成虛擬函數(virtual),這樣調用過程就變成動態綁定,它就會出錯了
⑷ 對象指針為NULL,為什麼還是可以調用成員函數
要理解這個的話。。。成員函數其實可以認為是一個普通的函數,比如
classA{
public:
voidfunc(intx){cout<<"hello,A.x="<<x<<endl;}
};
在編譯器看來,大概就長這個樣子吧:
voidA_func(A*this,intx){cout<<"hello,A.x="<<x<<endl;}
你平時使用成員函數的時候,大概就是這樣的:
Aa;
a.func(2);
其實在編譯器看來,是這個樣子的:
A_func(&a,2);
如果這么說的話,也許你就理解了,為什麼對象是NULL的時候還可以調成員函數:
A*pa=NULL;
pa->func(2);
//在編譯器看來就好像是A_func(pa,2);且pa==NULL
((A*)NULL)->func(2);
//在編譯器看來就好像是A_func(((A*)NULL),2);
-----我是分割線-----
上面的例子中func函數里並沒有使用成員變數。考慮有成員變數並且在成員函數里使用的情況,就會不一樣了:
classA{
private:
inty;
public:
voidfunc(intx){y=x;}
};
注意此時y是成員變數,編譯器會自動給它加上this->,也就是
voidA_func(A*this,intx){this->y=x;}
此時正常的情況就不用說了,說說用NULL對象指針調用成員函數的情況:
A*pa=NULL;
pa->func(2);
//在編譯器看來就好像是A_func(pa,2);且pa==NULL
((A*)NULL)->func(2);
//在編譯器看來就好像是A_func(((A*)NULL),2);
//好吧我承認這段代碼跟上面的一毛一樣啦!
此時程序會崩潰!為什麼?因為this指針是NULL,而你訪問了它的y變數!
----又是我哈哈哈-----
結論:
通過對象調用成員函數,對象的指針會被傳入函數中,指針名稱為this
因此NULL對象指針也可以調用成員函數
NULL對象指針調用成員函數時,只要不訪問此對象的成員變數,則程序正常運行
NULL對象指針調用成員函數時,一旦訪問此對象的成員變數,則程序崩潰
⑸ 為什麼一個類的空指針可以訪問類的成員函數
class MyClass{public:int i;void hello(){printf("hello/n");}void print(){printf("%d/n", i);}};void main(){MyClass* pmy = NULL;
pmy-hello();}看上面的這段代碼,似乎很詭異。 用一個空指針調用成員函數,簡直是天大的錯誤,可以遺憾的是,卻是可行的,至少對於上面的這段程序來說,不會照成錯誤。
之前運行的原因。
大家知道,每個對象,都有一個指向自己的this指針,這個指針的值,將會因為對象的不同而不同,它的作用主要就是用來區分不同的對象,這樣你就可以根據它
來訪問不同的對象的成員變數。然而,我們main函數中的hello函數並沒有使用類中的任何成員變數,所以,它也就不會用到this指針,此時的this指針是NULL。從而
我們就可以沒有障礙的使用hello函數,然而相對的是,如果你在pmy-hello()之後接著調用pmy-print(),那麼將會報空指針錯誤,因為這個函數試圖用this指針訪問成員變數i。
⑹ 對象指針訪問其對象的成員函數的機制是如何 c++
對於const對象,是只能訪問const成員函數的,所以,你定義的base是沒有const成員函數的,所以無法進行轉換,你去掉const,或者在虛函數那個show函數後邊加上const限制,都是可以解決問題的。
a. const對象只能訪問const成員函數,而非const對象可以訪問任意的成員函數,包括const成員函數.
b. const對象的成員是不可修改的,然而const對象通過指針維護的對象卻是可以修改的.
c. const成員函數不可以修改對象的數據,不管對象是否具有const性質.它在編譯時,以是否修改成員數據為依據,進行檢查.
e. 然而加上mutable修飾符的數據成員,對於任何情況下通過任何手段都可修改,自然此時的const成員函數是可以修改它的
⑺ C++類的空指針為什麼可以輸出數據
樓主。。進入一個誤區了
你說的那個空指針。那個是給指針初始賦值,讓他等於NULL
可是在viod OutPut(){cout << "Output Called!"};
。根本不需要傳遞任何東西進來。這個功能就是列印出這樣的一句話。
你的指針有初始就是對的。只要是對的話,那麼他就會執行這一句列印的。
⑻ C++函數指針和空指針的問題
函數int plus(int b)的指針類型原型為:int (*)(int)
其中左側int指定函數返回類型,右側(int)表示函數的參數類型。指針類型定義中,凡是右側有括弧的都表示是個函數指針,而括弧內可以定義0個或多個參數,以逗號分隔。中間的(*)把星號獨立起來表示是個指針定義。
當要直接定義一個函數指針時將變數名放星號後面,比如這樣:
int (*p)(int) =NULL;
雙參數定義:int (*p)(int,int) =NULL;
圖例中由於pV是個虛指針(萬能指針),可以賦值任意類型的地址,因此pV=Plus不會報錯,但訪問時必須強轉,否則編譯器不知道如何訪問指針(強轉就是將指定類型放在變數左側,比如(int)a就是將a的值強轉為int類型),強轉格式:(類型) 變數 ,那麼外面要套一層括弧:(int (*)(int))pV,我們需要用強轉後的函數指針傳遞參數進行函數調用,為避免歧義,因此需要連同變數名再打包一次:((int (*)(int))pV),隨後再傳遞參數10:
((int (*)(int))pV)(10)
括弧打包的內容可以看作一個整體/對象,你迷惑的主要因素應該有兩點:
1、不知道如何定義函數指針類型。
實際上就是將函數定義中的函數名用(*)替換,再將參數名去掉就可以了,比如下面這個函數
int * Fun(int a,char c){。。。。。。}
其函數指針類型為: int * (*)(int,char)
指針定義:int* (*p)(int, char);
2、括弧嵌套多了看起來比較亂。這個很簡單,一層一層拆解一層層理解。
⑼ C語言中,空指針的使用意義是什麼在編程中使用空指針會帶來什麼影響
語言定義中說明,每一種指針類型都有一個特殊值——「空指針」——它與同類型的其它所有指針值都不相同,它「與任何對象或函數的指針值都不相等」;
不要返回指向棧內存的指針或引用,因為棧內存在函數結束時會被釋放。
指針是個很強大的工具,可是正因為它太強大,所以要操作它不是件易事。操作不當造成的野指針,甚至會引起系統死機等比較嚴重的後果。
如果程序定義了一個指針,就必須要立即讓它指向一個我們設定的空間或者把它設為NULL,如果沒有這么做,那麼這個指針里的內容是不可預知的,即不知道它指向內存中的哪個空間(即野指針),它有可能指向的是一個空白的內存區域,可能指向的是已經受保護的區域,甚至可能指向系統的關鍵內存,如果是那樣就糟了,也許我們後面不小心對指針進行操作就有可能讓系統出現紊亂,死機了
⑽ 談談基類指針對類的成員函數的訪問許可權問題
基類指針
對其自己的成員函數:隨便訪問
對子類成員函數:不可訪問(對於虛函數,都是子類的指針對子類重寫的新的虛函數的引用,或者未重寫時候,父類的虛函數的引用,父類即使用指針引了虛函數,也是引自己的)