當前位置:首頁 » 文件傳輸 » 如何理解空指針可以訪問成員函數
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

如何理解空指針可以訪問成員函數

發布時間: 2022-05-12 18:48:11

⑴ 為啥用空指針調用函數程序不崩潰

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變數!

----又是我哈哈哈-----

結論:

  1. 通過對象調用成員函數,對象的指針會被傳入函數中,指針名稱為this

  2. 因此NULL對象指針也可以調用成員函數

  3. NULL對象指針調用成員函數時,只要不訪問此對象的成員變數,則程序正常運行

  4. 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,如果沒有這么做,那麼這個指針里的內容是不可預知的,即不知道它指向內存中的哪個空間(即野指針),它有可能指向的是一個空白的內存區域,可能指向的是已經受保護的區域,甚至可能指向系統的關鍵內存,如果是那樣就糟了,也許我們後面不小心對指針進行操作就有可能讓系統出現紊亂,死機了

⑽ 談談基類指針對類的成員函數的訪問許可權問題

基類指針
對其自己的成員函數:隨便訪問
對子類成員函數:不可訪問(對於虛函數,都是子類的指針對子類重寫的新的虛函數的引用,或者未重寫時候,父類的虛函數的引用,父類即使用指針引了虛函數,也是引自己的)