C 物件導向 9 物件模型和this指標

2021-10-02 08:10:22 字數 3667 閱讀 9102

本篇來學習物件模型和this指標,物件模型主要是了解物件的儲存模型。在c++中,類內的成員變數和成員函式是分開儲存的,只有非靜態成員變數才是屬於類的物件上,其他都和類存在不同記憶體區域。

1.乙個類的空物件占用記憶體是多大位元組

這裡我們先寫乙個**,通過sizeof()函式來列印乙個空的類物件占用記憶體是多少位元組。

#include using namespace std;

class person

;void test01()

int main()

上面定義了乙個person類,沒有寫成員變數和成員方法。然後直接初始化乙個物件p,那麼我們問題就來了,這麼乙個空的類物件所占用的記憶體大小是多少?我們可以能會猜測1 或者 0 或者 4等。

因為c++編譯器會給每乙個空物件分配乙個空間,是為了區分位置,每乙個物件都有獨一無二記憶體空間,這個空間大小就是1位元組。

2.乙個類只定義乙個int型別的變數的記憶體大小

在上面**基礎之上,新增非靜態成員變數 int m_a, 看看這個類物件所佔的記憶體是多少。

執行結果就是4位元組,因為c++編譯器檢測到這個類裡面定義了乙個int型別的變數,所以這個類物件所佔記憶體就是4位元組。這個結果,側面證明了非靜態成員物件是屬於這個類物件上的。

3.靜態成員變數不屬於類物件上

通過下面**的例子,建立乙個靜態成員變數,並在類外進行初始化,看看這個物件p的記憶體是多少。

#include using namespace std;

class person

;int person::m_b = 100;

void test01()

int main()

執行之後

這個結果還是4位元組,說明靜態成員變數m_b就不在物件p上,證明了靜態成員變數和非靜態成員變數是儲存在不同區域。

4.靜態成員函式和非靜態成員函式也不在類物件上

接下來,我們來證明乙個類的非靜態成員函式也不屬於類上儲存。

#include using namespace std;

class person

};int person::m_b = 100;

void test01()

int main()

執行得到

執行結果依然是4個位元組,說明非靜態成員函式也不屬於類物件上。其實不管非靜態函式還是靜態函式都不屬於類物件上儲存。下面新新增乙個靜態成員函式,再次執行**看看物件p的記憶體大小。

結論:不管靜態成員函式還是非靜態成員函式,都不在類物件上儲存。那邊c++是如何區分不同類物件下呼叫同乙個函式的呢,接下來就要學習this指標來回答這個問題。

5.this指標

c++通過this指標來區分很多物件呼叫同乙個函式。this指標指向被呼叫的成員函式所屬的物件,this指標是隱含每乙個非靜態成員函式的一種指標,this指標不需要定義,直接使用即可。

this指標的作用

當形參和成員變數同名時,可用this指標來區分。

在類的非靜態成員函式中返回物件本身,可使用return *this

先用一段**來描述this指標區分形參和成員變數同名的問題。

#includeusing namespace std;

class person

};void test01()

int main()

執行**後

根據我們前面學習的知識,難道這裡不是呼叫有參構造,年齡輸出18嗎?為什麼輸出這個。

問題就出在這個有參構造,age = age,這個時候類的變數和函式的形式引數名一樣,造成c++認為這兩個age是一樣,並沒有把類變數賦值成功。為了解決這個問題,我們可以在定義類變數的時候加上m_age 或者age,這樣來區分。第二種辦法,就是使用this指標,下面來看看this指標的**。

#includeusing namespace std;

class person

};void test01()

int main()

this是乙個指標,所以這裡是this->來表示。這個時候this表示當前這個被呼叫函式的所屬的物件,也就是**中的p物件,這句話的理解很關鍵,上面用紅色字型標註出來。

使用return *this返回物件本身

有時候我們需要返回物件本身,特別是一些在鏈式程式設計的語法上。來看看下面**。

#includeusing namespace std;

class person

//解引用的方式做乙個返回

person& personaddage(person &p) };

void test01()

int main()

執行結果就是40,這個不斷後面呼叫方法就是鏈式程式設計的特點。注意上面返回的是乙個解引用,並不是乙個值,如果**修改返回值,執行結果是什麼呢?

#includeusing namespace std;

class person

//返回值

person personaddage(person &p) };

void test01()

int main()

執行結果是20,也就是呼叫persopnaddage一次的效果。

第一次呼叫,age=20,這個時候需要返回p2的乙個值,這個值和p2不是同乙個,如果是引用就是同乙個,值就是呼叫拷貝建構函式,新的物件預設age等於0,所以後面執行多次還是等於20.

1 1 物件模型

q1 c 的類有兩種資料成員 static 資料成員與 nonstatic 資料成員,有三種成員函式 static,nonstatic,virtual。q2 在虛繼承的情況下,base class不管在繼承串鏈中被派生多少次,永遠只會存在乙個例項 稱為subobject q3 c 物件模型。每個物件...

7 物件模型

標準 c 物件模型在執行時效率方面卓有成效,但是在某些特定問題域下的靜態特性就顯得捉襟見肘。gui 介面需要同時具有執行時的效率以及更高階別的靈活性。為了解決這一問題,qt 擴充套件 了標準 c 所謂 擴充套件 實際是在使用標準 c 編譯器編譯 qt 源程式之前,qt 先使用乙個叫做 moc met...

9 物件的擴充套件

es6一共有5種方法可以遍歷物件的屬性。1 for.in for.in迴圈遍歷物件自身的和繼承的可列舉屬性 不含symbol屬性 2 object.keys obj object.keys返回乙個陣列,包括物件自身的 不含繼承的 所有可列舉屬性 不含symbol屬性 3 object.getownp...