1. 程式人生 > >QT中this指標

QT中this指標

一:this指標只能在一個類的成員函式中呼叫,它表示當前物件的地址。下面是一個例子: 

void Date::setMonth( int mn ) 

month = mn; // 這三句是等價的

this->month = mn;

 (*this).month = mn; 

}

1. this只能在成員函式中使用。 全域性函式,靜態函式都不能使用this。 實際上,成員函式預設第一個引數為T* constregister this。 如: class A{publicint func(int p){}}; 其中,func的原型在編譯器看來應該是: int func(A* const

register thisint 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指標會因編譯器不同,而放置的位置不同。可能是棧,也可能是暫存器,甚至全域性變數。

#3:this指標如何傳遞給類中函式的?繫結?還是在函式引數的首引數就是this指標.那麼this指標又是如何找到類例項後函式的?

 this是通過函式引數的首引數來傳遞的。this指標是在呼叫之前生成的。類例項後的函式,沒有這個說法。類在例項化時,只分配類中的變數空間,並沒有為函式分配空間。自從類的函式定義完成後,它就在那兒,不會跑的。

 #4:this指標如何訪問類中變數的/? 如果不是類,而是結構的話,那麼,如何通過結構指標來訪問結構中的變數呢?

 在C++中,類和結構是隻有一個區別的:類的成員預設是private,而結構是public。 this是類的指標,如果換成結構,那this就是結構的指標了。

 #5:我們只有獲得一個物件後,才能通過物件使用this指標,如果我們知道一個物件this指標的位置可以直接使用嗎? this指標只有在成員函式中才有定義。因此,你獲得一個物件後,也不能通過物件使用this指標。所以,我們也無法知道一個物件的this指標的位置(只有在成員函式裡才有this指標的位置)。當然,在成員函式裡,你是可以知道this指標的位置的(可以&this獲得),也可以直接使用的。

 #6:每個類編譯後,是否建立一個類中函式表儲存函式指標,以便用來呼叫函式? 

普通的類函式(不論是成員函式,還是靜態函式),都不會建立一個函式表來儲存函式指標的。只有虛擬函式才會被放到函式表中。 但是,既使是虛擬函式,如果編譯器能明確知道呼叫的是哪個函式,編譯器就不會通過函式表中的指標來間接呼叫,而是會直接呼叫該函式。

7:能否模擬實現? ‘

 其實,模擬實現this的呼叫,在很多場合下,很多人都做過。 例如,系統回撥函式。系統回撥函式有很多,如定時,執行緒啊什麼的。 舉一個執行緒的例子:

 class A{

 int n;

public:

 static void run(void* pThis)

A* this_ = (A*)pThis; 

this_->process();

 }

 void process(){}

 }; 

main(){

 A a; 

_beginthread( A::run, 0, &a ); 

這裡就是定義一個靜態函式來模擬成員函式。 也有許多C語言寫的程式,模擬了類的實現。如freetype庫等等。 如: typedef struct student{ int age; int no; int scores; }Student;

 void initStudent(Student* pstudent); 

void addScore(Student* pstudent, int score); ... 如果你把 pstudent改成this,那就一樣了。 

它相當於:

 class Student{

 public:

 int age; 

int no;

int scores; 

void initStudent();

void addScore(int score);

 } const常量可以有物理存放的空間,因此是可以取地址的///this指標是在建立物件前建立.this指標放在棧上,在編譯時刻已經確定. 並且當一個物件建立後,並且執行整個程式執行期間只有一個this指標. 

當一個成員函式被呼叫時,自動向它傳遞一個隱含的引數,該引數是一個指向接受該函式呼叫的物件的指標。在程式中用this來引用該指標。

void Tdate::Set(int m,int d,int y)

{

month = m;day = d; year = y;

}

C++ 編譯器所認識的指標成員函式Set的定義形式是:

void Tdate::Set(int m,int d,int y)

{

this->month = m;this->day = d;this-> year = y;

}

對於該成員函式中訪問的任何類成員,C++編譯器都認為是訪問this指標所指向物件的成員。

定義一個物件:

Tdate dd;

dd.Set(6,25,2011);

不同的物件呼叫Set()成員函式時,this指標指向不同的物件,就可以實現為不同的物件賦初值。

關於this指標的一個經典回答:  當你進入一個房子後,

  你可以看見桌子、椅子、地板等,   但是房子你是看不到全貌了。   對於一個類的例項來說,   你可以看到它的成員函式、成員變數,   但是例項本身呢?   this是一個指標,它時時刻刻指向你這個例項本身。

Qt中,如果申明瞭兩個陣列:

   QLabel        *label[8];
   QLabel        *sLabel[8];

   這兩個都是QLabel型別的指標陣列,希望在以後的使用中動態的分配其記憶體;
   那麼就應該:
   在class MyLabel中...

  for(int i=0;i<8;i++)
   {
       label[i] = new QLabel("This is a Label",this,0);
       //申請空間.    
       sLabel[i] = new QLabel("",label[i],0);
       //第二個Label指標陣列的父物件為上面申請過空間的Label.
  }

   QLabel的建構函式的原形為:

   QLabel ( const QString & text, QWidget * parent, const char * name = 0, WFlags f = 0 )

   text:       Label上要顯示的字串;
   parent:     Label的父物件的指標;
   name:       Label的名字;
   f:          Label的Flags;

   從上面的程式碼容易得知label陣列每個元素是以當前MyLabel類物件為父物件的;而sLabel裡的元素是以對應的label為父物件的;

  在MyLabel的解構函式中就有相應的釋放空間的程式碼:

  for(int i=0;i<8;i++)
 {
       delete label[i];
       //delete sLabel[i];
  }

  這裡要是不註釋掉上面第3行的語句就會出現段錯誤,原因經過查詢資料得知在Qt中如果在建立元件物件時設定了父物件時,由父物件負責釋放其子物件的空間.所以上面第2行已經釋放了label的空間,而其子物件的sLabel也隨之被釋放,所以如果第三行再進行釋放就會出現之前所說的錯誤.。

二:

Qt中ui指標和this指標
Qt中ui指標和this指標的用法和區別.

ui->xxx = this->ui->xxx 

看ui你定義的是什麼了,一般ui定義的是一個新的介面,繼承了Ui類,例如ui->lable也就是指的介面上的標籤。而this則指是當前物件。你可以用this->ui->lable完成同樣的事情。 

this->xxx 指本類的xxx
ui->xxx 指ui檔案上的xxx  

如果本類包含ui檔案 那麼ui->xxx 和 this->ui->xxx 一樣。