最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++基礎(chǔ)之this指針與另一種“多態(tài)”

 更新時間:2013年07月26日 08:56:45   作者:  
this指針識別了同一個類的不同的對象,換句話說,this指針使得成員函數(shù)可以訪問同一個類的不同對象。再深入一點,this指針使得成員函數(shù)會因為this指針的不同而訪問到了不同的成員變量

一、引入
定義一個類的對象,首先系統(tǒng)已經(jīng)給這個對象分配了空間,然后會調(diào)用構(gòu)造函數(shù)。

一個類有多個對象,當程序中調(diào)用對象的某個函數(shù)時,有可能要訪問到這個對象的成員變量。
而對于同一個類的每一個對象,都是共享同一份類函數(shù)。對象有單獨的變量,但是沒有單獨的函數(shù),所以當調(diào)用函數(shù)時,系統(tǒng)必須讓函數(shù)知道這是哪個對象的操作,從而確定成員變量是哪個對象的。
這種用于對成員變量歸屬對像進行區(qū)分的東西,就叫做this指針。事實上它就是對象的地址,這一點從反匯編出來的代碼可以看到。

二、分析
1、測試代碼:

復(fù)制代碼 代碼如下:

/////////////////////////////////////////////////////////////////////////////////////
#include<iostream>
using   namespace   std;
/////////////////////////////////////////////////////
class A
{
public:
    A(char *szname)
    {
        cout<<"construct"<<endl;
        name
 = new char[20];
        strcpy(name,
 szname);
    }
    ~A()
    {
        cout<<"destruct"<<endl;
        delete name;
    }
    void    show();
private:
    char    *name;
};
/////////////////////////////////////////////////////
void    A::show()
{
    cout<<"name
 = "<<name<<endl;
}
/////////////////////////////////////////////////////
int main()
{
    A
 a("zhangsan");
    a.show();
    system("pause");
    return 0;
}

程序在VC++6.0 32位操作系統(tǒng)上編譯、運行。
對編譯后的EXE文件,進行反匯編。反匯編工具為OllyDbg。

2、反匯編分析
關(guān)鍵點截圖如下:
(1)從圖1可以發(fā)現(xiàn)this指針通過ECX寄存器,傳遞給了成員函數(shù)。this指針就是對象的地址。

圖 1 Main函數(shù)

(2)從圖 2可以發(fā)現(xiàn)訪問對象的成員變量用的就是之前通過ECX傳入的this指針。

 

圖 2 show()函數(shù)

三、深入理解

通過截圖及相關(guān)的資料,可以很清晰的知道在調(diào)用構(gòu)造函數(shù)、show()函數(shù)之前的那個ECX就是this指針,也就是說這是一個驗證性的實驗,答案已經(jīng)很清楚了,所要做的就是去動手體驗一下。但是,假如我不懂C++、我不懂什么this指針,我一樣可以發(fā)現(xiàn)這個叫做“this指針”的東西。通過OD的動態(tài)調(diào)試,當顯示出了name時,逐步回溯可以發(fā)現(xiàn)name的源頭是ECX。OD重新載入,查看在進入show()函數(shù)之前ECX是哪里來的,最終可以一步步的發(fā)現(xiàn),ECX就是一個地址,這個地址里邊的第一個值也是一個地址,指向一串字符串。再往上分析,進入show()上邊的構(gòu)造函數(shù),可以發(fā)現(xiàn)里邊有new操作,strcpy操作,這里就發(fā)現(xiàn)了字符串空間、內(nèi)容的來源。至此,基本就分析完了。

通過這個過程可以發(fā)現(xiàn)很多C++的知識。如:對象的空間是在調(diào)用構(gòu)造函數(shù)之前就分配好了的;對象里邊沒有函數(shù);this指針通過寄存器ECX傳遞;通過聲明定義的對象它的空間分配在棧中;等等這些跟系統(tǒng)或者C++有關(guān)聯(lián)的知識。

但是,對于一個不懂C++的人看來,上面一段的體會都是沒有的。從匯編指令看不出C++的思想,this指針不過是一個地址;對象不過是一些空間;構(gòu)造函數(shù)、析構(gòu)函數(shù)以及其它的函數(shù),也不過是一堆指令的集合。

C++的同一個類定義出來的多個對象,從匯編指令看來是這樣的:有很多塊地址空間,它們有相同的大小。當不同的對象調(diào)用成員函數(shù)時,在匯編指令看來是:它們都call同一個地址,這個call指令其實里邊是一個jmp指令,用于跳向某個位置,在call指令之前一般都會把一個地址放到ECX中,當然有時候會用堆?;蛘咂渌拇嫫鳌?br>
C++的繼承、多態(tài)、封裝,對匯編程序員來說是看不出有什么神奇的,對于C++程序員來說那可就不同了,可以省去很多的工作,把很多事情都交給了編譯器,讓編譯器自動給你搞定。

C++程序員所討論的對象及其眾多的特點、優(yōu)點,最終還是變成了“低級”的指令,而且可能是效率低下的指令,即便如此,它的優(yōu)點仍遠大于缺點,它讓編程變得容易、高效。

四、延伸

忽然想到了C++的多態(tài),一句話“將子類類型的指針賦值給父類類型的指針”,多態(tài)是通過虛函數(shù)實現(xiàn)。對虛函數(shù)及其相關(guān)內(nèi)容的原理、詳細理解就不細說了。

說下我的簡單理解,有一個基類A和子類B、C,有一個函數(shù)以基類A的指針為參數(shù),然后在函數(shù)里頭通過指針調(diào)用基類的成員函數(shù)。假如這個被調(diào)用的基類成員函數(shù)不是虛函數(shù),那么是不可能實現(xiàn)多態(tài)的,因為翻譯成匯編指令的時候,調(diào)用成員函數(shù)的這個地方是一個call指令,然后這個call指令跳到某個地方去執(zhí)行,這是一個固定了的地址。通過定義為虛函數(shù),調(diào)用成員函數(shù)的這個地方是通過虛函數(shù)表指針來確定調(diào)用哪個函數(shù)的,而虛函數(shù)表指針就放在對象的地址空間中,如果對象變了,那么虛函數(shù)表指針也變了,調(diào)用的函數(shù)也就不同了。對于那個以基類A的指針為參數(shù)的函數(shù),指針即是對象的地址,如果傳遞的地址是子類B或者C的對象的地址,那么虛函數(shù)表指針也就不同了,調(diào)用的成員函數(shù)也就不同了。

這就是多態(tài),這種多態(tài)使得調(diào)用同一個函數(shù),因為傳遞參數(shù)的不同而顯示出差異,參數(shù)可以是基類對象或者眾多不同的子類對象。它們的差異是類與類之間的。

有虛函數(shù)的對象的內(nèi)存布局,比沒有虛函數(shù)的對象多了一個指向虛函數(shù)表的指針。因為虛函數(shù)的調(diào)用是通過虛函數(shù)表指針來實現(xiàn)的,所以有了多態(tài)。

再考慮一下C++的this指針,一個類中的成員函數(shù),依據(jù)this指針來區(qū)分不同的對象,也就是說根據(jù)this指針實現(xiàn)了訪問不同的對象的成員變量。

這是否也是多態(tài)的一種表現(xiàn)?這里所說的多態(tài)已經(jīng)不是那個“父類指針指向子類對象”的教條了,而是體現(xiàn)在同一個類的不同對象之間,調(diào)用同一個成員函數(shù),依據(jù)參數(shù)“this指針”來實現(xiàn)訪問不同的對象的成員變量。成員函數(shù)訪問成員變量,在編譯期無法確定它訪問的成員變量在哪一個地址的,只有到了運行期依據(jù)this指針才能確定訪問的地址。這一點很類似于類的多態(tài):以基類指針為參數(shù)的函數(shù)里調(diào)用了某個基類的虛成員函數(shù),在編譯期無法確定程序運行時調(diào)用的會是哪個類的對象,只有到了運行期才確定會調(diào)用哪個類的對象。

this指針識別了同一個類的不同的對象,換句話說,this指針使得成員函數(shù)可以訪問同一個類的不同對象。再深入一點,this指針使得成員函數(shù)會因為this指針的不同而訪問到了不同的成員變量。這也是多態(tài)吧,只是它是必然存在的多態(tài),這種多態(tài)跟基類與派生類之間的多態(tài)是不同級別的多態(tài),它不像一般的多態(tài)可以通過對使用虛函數(shù)的選擇來取舍,它是一個類對應(yīng)多個對象、多個對象共享一份成員函數(shù)代碼帶來的必然結(jié)果。

相關(guān)文章

  • C語言詳細講解qsort函數(shù)的使用

    C語言詳細講解qsort函數(shù)的使用

    排序方法有很多種:選擇排序,冒泡排序,歸并排序,快速排序等??疵侄贾揽焖倥判蚴悄壳肮J的一種比較好的排序算法。因為他速度很快,所以系統(tǒng)也在庫里實現(xiàn)這個算法,便于我們的使用。這就是qsort函數(shù)
    2022-04-04
  • 詳解C++中的對象指針與對象數(shù)組

    詳解C++中的對象指針與對象數(shù)組

    這篇文章主要介紹了詳解C++中的對象指針與對象數(shù)組,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-09-09
  • C++容器map和pair對組實例詳解

    C++容器map和pair對組實例詳解

    pair?是一種模板類,允許將兩個不同類型的值組合在一起,它由兩個數(shù)據(jù)成員first和second組成,分別用來保存這兩個值,這篇文章主要介紹了C++容器——map和pair對組,需要的朋友可以參考下
    2024-05-05
  • c++實現(xiàn)LinkBlockedQueue的問題

    c++實現(xiàn)LinkBlockedQueue的問題

    這篇文章主要介紹了c++實現(xiàn)LinkBlockedQueue的問題,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • C語言利用結(jié)構(gòu)體數(shù)組實現(xiàn)學(xué)生成績管理系統(tǒng)

    C語言利用結(jié)構(gòu)體數(shù)組實現(xiàn)學(xué)生成績管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C語言利用結(jié)構(gòu)體數(shù)組實現(xiàn)學(xué)生成績管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • C語言switch語句和if用法介紹

    C語言switch語句和if用法介紹

    本文詳細講解了C語言switch語句和if用法介紹,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-12-12
  • C語言項目全正整數(shù)后再計算的三種參考解答方法

    C語言項目全正整數(shù)后再計算的三種參考解答方法

    今天小編就為大家分享一篇關(guān)于C語言項目全正整數(shù)后再計算的三種參考解答方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • C語言鏈表案例學(xué)習(xí)之通訊錄的實現(xiàn)

    C語言鏈表案例學(xué)習(xí)之通訊錄的實現(xiàn)

    為了將所學(xué)到的鏈表的知識進行鞏固學(xué)習(xí),做到學(xué)以致用,本文將利用鏈表制作一個簡單的通訊錄。文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下
    2022-10-10
  • 千萬不要被階乘嚇倒

    千萬不要被階乘嚇倒

    本篇文章是對階乘進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C++11中union的使用方法示例

    C++11中union的使用方法示例

    這篇文章主要給大家介紹了關(guān)于C++11中union的使用方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-09-09

最新評論

通江县| 塔河县| 呈贡县| 绥宁县| 宝坻区| 梁河县| 景宁| 大田县| 濮阳市| 南昌县| 天水市| 故城县| 师宗县| 拜城县| 奎屯市| 申扎县| 吴旗县| 黎平县| 盘锦市| 通城县| 永川市| 鄂伦春自治旗| 大田县| 肃南| 泾源县| 巴彦淖尔市| 朝阳县| 兰溪市| 石河子市| 怀集县| 武城县| 太康县| 临沧市| 鹤峰县| 昂仁县| 陇南市| 临安市| 河东区| 南投县| 遵化市| 广汉市|