1. 程式人生 > >this指標的介紹和用法

this指標的介紹和用法

參考書籍,孫鑫視訊教學,百度。
本文章是以綠色字型為修改內容,如有錯誤之處,請大家指正。
this指標的介紹:
1.this指標是一個隱含的指標,它是指向物件本身,代表了物件的地址。
(正如你家有個人名叫“陳皮”的,你隔壁家也有個人叫“陳皮”。this就表示你自家的人,說明白一點就是你家的那個“陳皮”。)
隱含的指標的說法,可以形象化成這樣:
  當你進入一個房子後,你可以看見桌子、椅子、地板等,但是房子你是看不到全貌了。
  對於一個類的例項來說,你可以看到它的成員函式、成員變數,但是例項本身呢?
  this是一個指標,它時時刻刻指向你這個例項本身。
2.一個類所有的物件呼叫的成員函式都是統一程式碼段。
那麼成員函式又是怎麼識別屬於同一物件的資料成員呢?

原來,在物件呼叫pt.output(10,10)時,成員函式除了接受2個實參外,還接受到了一個物件pt的地址。
這個地址被一個隱含的形參this指標所獲取,
它等同於執行this=&pt。所有對資料成員的訪問都隱含地被加上字首this->。
例如:
x=0;等價於this->x=0。
3.一個物件的this指標並不是物件本身的一部分,不會影響sizeof(物件)的結果。
this作用域是在類內部,當在類的非靜態成員函式中訪問類的非靜態成員的時候,編譯器會自動將物件本身的地址作為一個隱含引數傳遞給函式。
也就是說,即使你沒有寫上this指標,編譯器在編譯的時候也是加上this的,它作為非靜態成員函式的隱含形參,
對各成員的訪問均通過this進行。
4.this到底是什麼?(摘自c語言中文網)
this 實際上是成員函式的一個形參,在呼叫成員函式時將物件的地址作為實參傳遞給 this。不過 this 這個形參是隱式的,它並不出現在程式碼中,而是在編譯階段由編譯器默默地將它新增到引數列表中。
---------------------------------------------------
this的作用:
1.使用this區分成員變數和區域性變數。
當類中有兩個同名變數,一個屬於類(類的成員變數),而另一個屬於某個特定的方法(方法中的區域性變數)。
2.使用this簡化建構函式的呼叫。
3.一個類所有的例項(物件)呼叫的成員方法在記憶體中只有一份拷貝
,儘管在記憶體中可能有多個物件,

而資料成員在類的每個物件所在記憶體中都存在著一份拷貝。this變數允許相同的例項方法為不同的物件工作。
每當呼叫一個例項方法時,this變數將被設定成引用該例項方法的特定的類物件。
方法的程式碼接著會與this所代表的物件的特定資料建立關聯。
4.為了分清同變數名,引用指標。
假設:void output(int x,int y)函式裡面的兩個形參和類的公有的兩個變數名一致時,分析如下例項:
class Point
{public:
int x;
int y;
Point(int a,int b){x=a;y=b;}
void output()//output函式{cout<<x<<endl<<y<<endl;}
void output(int x,int y)//output函式過載{x=x;y=y;}
};
void main()
{
Point pt(3,3);
pt.output(5,5);
}

輸出結果為:
3
3
原因:在output(int x,int y)中,x,y都屬於output過載函式裡面的形參,並沒有呼叫類裡面的x,y;

把output(int x,int y)函式改成:
void output(int x,int y)//output函式過載
{
this->x=x;
this->y=y;
}


輸出結果:
5
5
瞭解類的知識,請訪問部落格:
--------------------------------------
this指標程式示例:
  this指標存在於類的成員函式中,指向被呼叫函式所在的類例項的地址。
  根據以下程式來說明this指標
   #include<iostream.h>
   class Point
   {
   int x, y;
   public:
   Point(int a, int b) {x=a; y=b;}
   void MovePoint( int a, int b){ x+=a; y+=b;}
   void print(){ cout<<"x="<<x<<"y="<<y<<endl;}
   };
   void main( )
   {
   Point point1( 10,10);
   point1.MovePoint(2,2);
   point1.print( );
   }


   當物件point1呼叫MovePoint(2,2)函式時,即將point1物件的地址傳遞給了this指標。
   MovePoint函式的原型應該是 void MovePoint( Point *this, int a, int b);第一個引數是指向該類物件的一個指標,我們在定義成員函式時沒看見是因為這個引數在類中是隱含的。這樣point1的地址傳遞給了this,所以在MovePoint函式中便顯式的寫成:
   void MovePoint(int a, int b) { this->x +=a; this-> y+= b;}
   即可以知道,point1呼叫該函式後,也就是point1的資料成員被呼叫並更新了值。
   即該函式過程可寫成 point1.x+= a; point1. y + = b;
 -------------------------------------------------------------------------------------------------------------
   使用this指標要注意的事項
相信大家對指標的用法已經很熟了,這裡也不多說些定義性的東西了,只說一下指標使用中的注意事項吧。
       一.在定義指標的時候注意連續宣告多個指標時容易犯的錯誤,例如int * a,b;這種宣告是聲明瞭一個指向int型別變數的指標a和一個int型的變數b,這時候要清醒的記著,而不要混淆成是聲明瞭兩個int型指標。
       二.要避免使用未初始化的指標。很多執行時錯誤都是由未初始化的指標導致的,而且這種錯誤又不能被編譯器檢查所以很難被發現。這時的解決辦法就是儘量在使用指標的時候定義它,如果早定義的話一定要記得初始化,當然初始化時可以直接使用cstdlib中定義的NULL也可以直接賦值為0,這是很好的程式設計習慣。
        三.指標賦值時一定要保證型別匹配,由於指標型別確定指標所指向物件的型別,因此初始化或賦值時必須保證型別匹配,這樣才能在指標上執行相應的操作。
-------------------------------------------------------------------------------------------------------------
摘自百度百科:
詳細解析編輯

        在前面曾經提到過: 每個物件中的資料成員都分別佔有儲存空間,如果對同一個類定義了n個物件,則有n組同樣大小的空間以存放n個物件中的資料成員。但是,不同物件都呼叫同一個函式程式碼段。
        那麼,當不同物件的成員函式引用資料成員時,怎麼能保證引用的是所指定的物件的資料成員呢?假如,對於例程式中定義的Box類,定義了3個同類物件a,b,c。
            1.如果有a.volume( ) ,應該是引用物件a中的height,width和length,計算出長方體a的體積。
            2.如果有b.volume( ) ,應該是引用物件b中的height,width和length,計算出長方體b的體積。
        而現今都用同一個函式段,系統怎樣使它分別引用a或b中的資料成員呢?在每一個成員函式中都包含一個特殊的指標,這個指標的名字是固定的,稱為this指標。它是指向本類物件的指標,它的值是當前被呼叫的成員函式所在的物件的起始地址。
         例如,當呼叫成員函式a.volume時,編譯系統就把物件a的起始地址賦給this指標,於是在成員函式引用資料成員時,就按照this的指向找到物件a的資料成員。例如volume函式要計算height*width*length的值,實際上是執行:
(this->height)*(this->width)*(this->length)
由於當前this指向a,因此相當於執行:
(a.height)*(a.width)*( a.length)
這就計算出長方體a的體積。
          同樣如果有b.volume( ) ,編譯系統就把物件b的起始地址賦給成員函式volume的this指標,顯然計算出來的是長方體b的體積。this指標是隱式使用的,它是作為引數被傳遞給成員函式的。
本來,成員函式volume的定義如下:
int Box::volume( )
{
return (height*width*length);
}
C++把它處理為
int Box::volume(Box *this)
{
return (this->height * this->width * this->length);
}
即在成員函式的形參表列中增加一個this指標。
在呼叫該成員函式時,實際上是用以下方式呼叫的:
a.volume(&a);
將物件a的地址傳給形參this指標。然後按this的指向去引用其他成員。
需要說明: 這些都是編譯系統自動實現的,程式設計序者不必人為地在形參中增加this指標,也不必將物件a的地址傳給this指標。在需要時也可以顯式地使用this指標。
例如在Box類的volume函式中,下面兩種表示方法都是合法的、相互等價的。
return (height * width * length); //隱含使用this指標
return (this->height * this->width * this->length); //顯式使用this指標
可以用*this表示被呼叫的成員函式所在的物件,*this就是this所指向的物件,即當前的物件。
例如在成員函式a.volume( )的函式體中,如果出現*this,它就是本物件a。上面的return語句也可寫成
return((*this).height * (*this).width * (*this).length);
注意*this兩側的括號不能省略,不能寫成*this.height。
所謂“呼叫物件a的成員函式f”,實際上是在呼叫成員函式f時使this指標指向物件a,從而訪問物件a的成員。在使用“呼叫物件a的成員函式f”時,應當對它的含義有正確的理解。
-----------------------------------------------------------
應用參考編輯
this指標只能在一個類的成員函式中呼叫,它表示當前物件的地址。下面是一個例子:
1
2
3
4
5
6
7
voidDate::setMonth(intmn)
{
  month=mn;
  this->month=mn;
  (*this).month=mn;
  //這三句是等價的
}
1.this只能在成員函式中使用。
全域性函式,靜態函式都不能使用this。
實際上,成員函式預設第一個引數為T*const register this。
如:
class A{public: int func( int p){}};
其中,func的原型在編譯器看來應該是: int func(A*const register this, int p);
2. 由此可見,this在成員函式的開始前構造的,在成員的結束後清除
這個生命週期同任一個函式的引數是一樣的,沒有任何區別。
當呼叫一個類的成員函式時,編譯器將類的指標作為函式的this引數傳遞進去。如:
A a;
a.func(10);
此處,編譯器將會編譯成: A::func(&a, 10);
嗯,看起來和靜態函式沒差別,對嗎?不過,區別還是有的。編譯器通常會對this指標做一些優化的,因此,this指標的傳遞效率比較高--如vc通常是通過ecx暫存器來傳遞this引數。
3. 回答
#1:this指標是什麼時候建立的?
this在非靜態成員中有意義,作為右值可以直接在編譯時確定其存在,執行時無所謂建立。

#2:this指標存放在何處?

堆,棧,全域性變數,還是其他?

由上一問可知,this指標無需顯式儲存記憶體中。只要儲存物件的記憶體位置確定,對應的this指標就被確定了。
#3:this指標如何傳遞給類中函式的?繫結?還是在函式引數的首引數就是this指標.那麼this指標又是如何找到類例項後函式的?
this是通過函式引數的首引數來傳遞的。this指標是在呼叫之前生成的。類例項後的函式,沒有這個說法。類在例項化時,只分配類中的變數空間,並沒有為函式分配空間。自從類的函式定義完成後,它就在那兒,不會跑的。
#4:this指標如何訪問類中變數的?
如果不是類,而是結構的話,那麼,如何通過結構指標來訪問結構中的變數呢?如果你明白這一點的話,那就很好理解這個問題了。
在C++中,struct是一種類型別,struct和class只有一個區別的:class的成員和繼承預設的訪問控制權限是private,而struct是public。
this是class或public的物件的指標。
#5:我們只有獲得一個物件後,才能通過物件使用this指標,如果我們知道一個物件this指標的位置可以直接使用嗎?
this指標只有在非靜態成員中才有意義。獲得一個物件後,不需要在類外部使用this對其操作。應當注意this是一個右值(方法的一個隱式引數) ,不存在所謂的this的“位置”,只是this表示了物件的儲存位置而已。&this違反語義規則,是錯誤的用法,不會編譯通過。
#6:每個類編譯後,是否建立一個類中函式表儲存函式指標,以便用來呼叫函式?
一般來說,對於類成員函式(不論是靜態還是非靜態的成員函式)都不需要建立一個在執行時的函式表來儲存。只有虛擬函式才會被放到函式表中。
但是,即使是虛擬函式,如果編譯器能明確知道呼叫的是哪個函式,編譯器就不會通過函式表中的指標來間接呼叫,而是可以直接呼叫該函式。

相關推薦

this指標介紹用法

參考書籍,孫鑫視訊教學,百度。本文章是以綠色字型為修改內容,如有錯誤之處,請大家指正。this指標的介紹:1.this指標是一個隱含的指標,它是指向物件本身,代表了物件的地址。(正如你家有個人名叫“陳皮”的,你隔壁家也有個人叫“陳皮”。this就表示你自家的人,說明白一點就

【轉】C# list介紹用法

php 檢索 排序 c# reac ont 面向對象 類型 大型 一、LIST概述 所屬命名空間:System.Collections.Generic public class List<T> : IList<T>, ICollection

git remote 遠端倉庫介紹用法

1 遠端倉庫的作用 使用Git的遠端倉庫可以實現團隊協作開發。 2 遠端倉庫的使用介紹 假設我們已經有了一個遠端倉庫,地址是:https://github.com/CnPeng/test.git 1) 克隆遠端版本倉庫到本地: git clone https://github.c

Java基礎(18):集合(容器)—CollectionMap兩大體系介紹用法

boolean add(E e)_______________________________新增指定元素 boolean addAll(Collection c)___________________將指定集合中所有元素都新增到此 collection boolean contains(Object

Python signal模組包介紹用法

在瞭解了Linux的訊號基礎之後,Python標準庫中的signal包就很容易學習和理解。signal包負責在Python程式內部處理訊號,典型的操作包括預設訊號處理函式,暫停並等待訊號,以及定時發出SIGALRM等。要注意,signal包主要是針對UNIX平臺(比如Linux, MAC OS),而Win

js中常用日期控制元件WdatePicker介紹用法詳解

4. 日期範圍限制  靜態限制  注意:日期格式必須與 realDateFmt 和 realTimeFmt 一致  你可以給通過配置minDate(最小日期),maxDate(最大日期)為靜態日期值,來限定日期的範圍 示例4-1-1 限制日期的範圍是 2006-09-1

C++中this指標的理解用法

關於this指標的一個精典回答: 當你進入一個房子後,你可以看見桌子、椅子、地板等,但是房子你是看不到全貌了。對於一個類的例項來說,你可以看到它的成員函式、成員變數,但是例項本身呢?this是一個指標,它時時刻刻指向你這個例項本身。 個人理解: (ps:class類就好比這

SQLite 數據庫介紹基本用法

png 觸發 align rim 嵌入 pan upd 參考 add ? 簡介 SQLite 是一款輕量級的關系型數據庫,同時也是一種嵌入式數據庫,與 Oracle、MySQL、SQL Server 等數據庫不同,它可以內嵌在程序中,是程序中的一個組成部分。所以,經常被應

C++快速入門---this指標類的繼承(10)

C++快速入門---this指標和類的繼承(10)   this是一個特殊的指標 class Human {    char fishc;    Human(char fishc); } Human::Human(char

C++類物件(一)&&實現OFFSETOF巨集&&THIS指標

一.目錄   1.物件的相關知識   2.類的定義   3.類的例項化   4.類物件模型   5.模擬實現offsetof巨集   6.this指標 二.正文 1.物件的相關知識   C語言是面向過程的,關注的是過程,分析求解問題的步驟,通過函式呼叫逐步解決問題

物件指標this指標智慧指標

物件指標 指向的是一個物件,定義形式為: *類名 物件指標名; 那如何通過指標訪問物件成員呢? 物件指標名->成員名 例:使用指標來訪問Point類的成員 #include using namespace std; class Point { public: Point(in

C++: this指標用法,相關知識點

1. this指標只能在類的成員函式中呼叫,表示當前物件的地址; void data::set_month(int mn) { month = mm; this->month = mn; (*this).month = mn;//三者等價 } 2. this

C++ this指標的詳解 C++中this指標用法詳解

C++中this指標的用法詳解   轉自:http://blog.chinaunix.net/uid-21411227-id-1826942.html 1. this指標的用處:   一個物件的this指標並不是物件本身的一部分,不會影響sizeof(物件)的結果

c++中this指標用法詳解

為什麼引入this指標?     最簡單的應用場景就是:當我們在類中定義了一個變數,同時在類成員函式中定義了同一變數時,也就是說變數名重複時,但是我們想使用類中定義的變數,這個時候我們該怎麼辦呢?這個時候就是this指標大顯身手的時候了。為此我們引入this指標

C/C++陣列指標指標陣列、函式指標變數的宣告用法

#include <iostream> using namespace std; void fun1(int(*pArr)[3], int row) { int i,j; for (i = 0; i < row; i++) { for (j = 0; j <

python中的map()函式reduce()函式的區別用法介紹

咱們先從定義上來解釋一下這兩個函式的區別: ①從引數方面來講: map(func, *iterables)包含兩個引數,第一個是引數是一個函式,第二個是序列(列表或元組)。其中,函式(即map的第一個引

SpringSpringBoot中的@Component @ComponentScan註解用法介紹注意事項

通過本文你將學到: Component Scan是什麼? 為什麼ComponentScan很重要? 專案中Spring Boot會對哪些包自動執行掃描(Component Scan)? 如何利用Spring Boot定義掃描範圍? 專案啟動時關於Compone

C++類物件(一)&&實現OFFSETOF巨集&&THIS指標

一.目錄   1.物件的相關知識   2.類的定義   3.類的例項化   4.類物件模型   5.模擬實現offsetof巨集   6.this指標 二.正文 1.物件的相關知識   C語言是面向過程的,關注的是過程,分析求解問題的步驟,通過函式呼叫逐步解

c++物件陣列this指標

當程式需要建立同一個類的多個物件時,可以建立物件陣列,宣告物件陣列的方法和宣告標準型別陣列相同,且陣列用法也相同。 宣告:Stock mystuff[4]; 初試化:Stock stocks[4]= { Stock("WANG",1,2), Stock("zhang",2,

JSON Web Token(JWT)原理用法介紹

JSON Web Token(JWT)是目前最流行的跨域身份驗證解決方案。今天給大家介紹一下JWT的原理和用法。 一、跨域身份驗證 Internet服務無法與使用者身份驗證分開。一般過程如下。 1. 使用者向伺服器傳送使用者名稱和密碼。 2. 驗證伺服器後,相關資料(如使用者角色,登入時間等)將儲存在