1. 程式人生 > >詳解this指標--為什麼空的物件指標可以呼叫成員函式

詳解this指標--為什麼空的物件指標可以呼叫成員函式

引題

class A{
public:
    void function()
    {
        cout << "I can run" << endl;
    }
};

int main()
{
    A* pa = NULL;
    pa->function();
    system("pause");
    return 0;
}

這裡寫圖片描述

C++中,空指標是不能夠使用的,然而空物件指標有時候卻能夠呼叫成員函式。
這就涉及到this指標。

為什麼空的物件指標可以呼叫成員函式卻不能呼叫成員變數?

類的成員函式其實可以認為是一個普通的函式,比如

class A{  
public:  
    void func(int x) { cout<<"hello, A. x="<<x<<endl; }  
};  

//在編譯器看來,大概是這個樣子:

void A_func(A* this, int x) { cout<<"hello, A. x="<<x<<endl; }  
//類的成員函式
A a;  
a.func(2);  
//被解釋成下面這樣子
A_func(&a, 2);  

那麼當物件指標為空的時候

A *pa = NULL;  
pa->
func(2); //在編譯器看來就好像是 A_func(pa, 2);且pa==NULL ((A*)NULL)->func(2); //在編譯器看來就好像是 A_func( ((A*)NULL), 2);

那麼對於類的成員變數時

class A{  
private:  
    int y;  
public:  
    void func(int x) { y = x; }  
};  
//注意此時y是成員變數,編譯器會自動給它加上this->,也就是:

void A_func(A* this, int x) { this->y = x; }  

但是!此時程式會崩潰!因為this指標是NULL,而你訪問了它的y變數!

總結

什麼是this指標

this是一個指標,它時時刻刻指向你這個例項本身。

this指標的特點

1)this只能在成員函式中使用。指向被呼叫函式所在的類例項的地址全域性函式、靜態函式都不能使用this,
2)this在成員函式的開始前構造,在成員函式的結束後清除。
3)一個物件的this指標並不是物件本身的一部分,不會影響sizeof(物件)的結果。
4)我們只有獲得一個物件後,才能通過物件使用this指標
5)this指標是類成員函式的第一個預設隱含引數,編譯器自動維護傳遞,類編寫者不能顯式傳遞。

從這道題得到的結論

1)NULL物件指標可以呼叫成員函式
2)通過物件呼叫成員函式,物件的指標會被傳入函式中,指標名稱為this
3)NULL物件指標呼叫成員函式時,只要不訪問此物件的成員變數,則程式正常執行
4)NULL物件指標呼叫成員函式時,一旦訪問此物件的成員變數,則程式崩潰

相關推薦

C# 反射:定義、建立物件呼叫例項方法及靜態方法

    1、反射的定義及功能介紹:審查元資料並收集關於它的型別資訊的能力。元資料(編譯以後的最基本資料單元)就是一大堆的表,當編譯程式集或者模組時,編譯器會建立一個類定義表,一個欄位定義表,和一個方法定義表等。可能這些說的比較抽象。我再從另一個角度來說:反射是.Net中

this指標--為什麼物件指標可以呼叫成員函式

引題 class A{ public: void function() { cout << "I can run" << endl; } }; int main() { A* pa =

[C++]物件指標可以呼叫成員函式

include using namespace std; class A{ public: void func() { cout << "hahaha" << endl; } int m_num = 1; }; int main() { A* ptr = NULL; A obj;

this 指標的地址--呼叫成員函式的所在物件的起始地址

#include<iostream> using namespace std; class Test { int x; public: Test(int a){ x=a; } void get_this(); }; void Test:: get_this() { co

C++基礎:類與物件(物件呼叫成員函式 this指標)

1.一個物件的this指標並不是物件本身的一部分,不會影響sizeof(物件)的結果。this作用域是在類內部,當在類的非靜態成員函式中訪問類的非靜態成員的時候,編譯器會自動將物件本身的地址作為一個隱含引數傳遞給函式。也就是說,即使你沒有寫上this指標,編譯器在編譯的時候

多維陣列與指標之間的關係

先介紹一下簡單的一維陣列:列如:int a[3] = {0,1,2};[3]和型別int則明確表示編譯器應該為這個棧分配多大的記憶體,也就是三個int大小!在記憶體中示意圖是:在CPU看來記憶體是一組連續的地址空間,所以當我們對一維陣列進行操作時只需要知道陣列首地址,就可以通

二維陣列與指標指標陣列、陣列指標

int* p=a[0];//此時P是指向一維陣列的指標。P++後,p指向 a[0][1]。 int (*p1)[n];p1=a;p1++後,p1指向a[1][0];   int *p=a[0]; 則陣列a的元素a[1][2]對應的指標為:p+1*4+2 元素a[1][2]

靜態成員函式this指標物件指標和動態物件使用小結

·靜態成員函式就是使用static 關鍵字宣告的成員函式  在類外實現時不加static關鍵字,只有在類內宣告時才加static·靜態成員函式是類的一部分,作用是為了處理靜態資料成員  沒有this指標·靜態成員函式可以直接訪問該類的靜態成員,但不能直接訪問類中的非靜態成員·若想在靜態成員fun中使用非靜態成

c++中使用指標呼叫成員函式的理解

使用空指標呼叫成員函式會如何? 舉個例子:base是基類,裡面有兩個函式:non-virtual func2 以及 virtual func1; derived是派生類,使用public繼承自base,裡面有四個函式:virtual func1,non-vi

指標也能呼叫成員函式

    最近各大公司都在招聘實習生,昨晚,微信公眾號推送了網易的筆試題讓小夥伴們參考,看了第一道題,博主就覺得“嗯,我果然還是見識短哈!”為什麼呢,我們先看看這個程式碼~class cal { publ

C++常量(一)常量指標與常量引用的初始化

1、常量 1.1、常量的初始化: const物件一旦建立後其值就不能再改變,所以const物件必須初始化。這裡我們要注意一點,像const int *p和const int &r都並不是const物件。因為const int *p只是表示

指標可以呼叫成員函式

有下面一個簡單類: class A { public: void fun(){ cout << "I'm class A"<<endl; } }; 用一個空指標呼叫上面的fun函式: A* p

c++ 如何把this指標傳入成員函式 像全域性函式一樣呼叫成員函式

測試這個功能的初衷是測試boost裡面的bind boost::bind((&A::sum), &a, _1, _2) 上面的程式碼是我boost bind及多執行緒這篇部落格裡面的一行程式碼。我就想boost是怎麼做到這樣呼叫一個類的成員函式的。其實成員

指標呼叫成員函式問題

問題由來:new一個自己的類,用完後delete指標,置空NULL 後,打斷點指標為空,但是依舊可以調用出類裡的函式,且編譯通                    過了; 總結:在java,Python語言中是做不到這樣的,但是C++中可以,原因是其繫結方式不一樣;

[C++]類的指標呼叫成員函式後,會發生什麼事?

類的例項呼叫成員函式的原理 其實不管是通過物件例項或指標例項呼叫,其實底層呼叫的過程都是一樣的,都是把當前物件的指標作為一個引數傳遞給被呼叫的成員函式。通過下面的相關例項程式碼進行檢驗: 實驗的C++程式碼 class Student { private: int age; public: Studen

SSH 框架中物件呼叫流程

摘要:SSH=Struts+Spring+Hibernate SSH不是一個框架,而是多個框架(struts+spring+hibernate)的整合,是目前較流行的一種Web應用程式開源整合框架,用於構建靈活、易於擴充套件的多層Web應用程式。 整合SSH框架的系統從職責上分為四層:表示層、業務邏輯層、資料

web前端技術基礎課程之JavaScript面向物件

JavaScript中的面向物件是個老生常談的話題,但是依然有很多小夥伴處於懵逼狀態。面試時候最擔心的就是被問到面向物件相關的內容,自己看過無數的資料,依然對面向物件百思不得其解。到底什麼是原型?什麼是建構函式?什麼是繼承。。。一提到這些概念那真是欲哭無淚、悲憤交加,甚至恨的直咬牙!所以有必要談一次面向物件。

JavaWeb學習----JSP內建物件---九大內建物件沒cook JavaWeb學習----JSP內建物件

JavaWeb學習----JSP內建物件詳解 JSP共有以下9大內建物件: out request response session pageContext application config page exception 文章連結 -

this

原文:https://www.cnblogs.com/Wayou/p/all-this.html this 虐我千百遍,看完此文效立見!不得不說,這篇文章的總結很地道很全面,適合收藏之用。 原文:all this 習慣了高階語言的你或許覺得JavaScript中的th

Django中Request物件的相關用法

從Request物件中獲取資料 我們在第三章講述View的函式時已經介紹過HttpRequest物件了,但當時並沒有講太多。 讓我們回憶下:每個view函式的第一個引數是一個HttpRequest物件,就像下面這個hello()函式: ? 1 2 3 4 from djang