cthis指針存儲
㈠ C++中的this指針,this本身是在程序的棧中嗎還是在全局區求指教
可以的,stack是容器,也是類型,當然可以定義指針。
給個例子:
#include<iostream>
#include<stack>
#include<vector>
using namespace std;
int main()
{
stack<int,vector<int> > *sp=new stack<int,vector<int> >;
for(size_t ix=1;ix!=20;++ix)
{
sp->push(ix);
}
for(ix=1;ix!=20;++ix)
{
cout<<sp->top()<<' ';
sp->pop();
}
cout<<endl;
return 0;
}
可以運行看看。
如果在vs2008上,在第二次for循環處ix前加上
size_t或int。
可以的,stack是容器,也是類型,當然可以定義指針。
給個例子:
#include<iostream>
#include<stack>
#include<vector>
using namespace std;
int main()
{
stack<int,vector<int> > *sp=new stack<int,vector<int> >;
for(size_t ix=1;ix!=20;++ix)
{
sp->push(ix);
}
for(ix=1;ix!=20;++ix)
{
cout<<sp->top()<<' ';
sp->pop();
}
cout<<endl;
return 0;
}
可以運行看看。
如果在vs2008上,在第二次for循環處ix前加上
size_t或int。
可以的,stack是容器,也是類型,當然可以定義指針。
給個例子:
#include<iostream>
#include<stack>
#include<vector>
using namespace std;
int main()
{
stack<int,vector<int> > *sp=new stack<int,vector<int> >;
for(size_t ix=1;ix!=20;++ix)
{
sp->push(ix);
}
for(ix=1;ix!=20;++ix)
{
cout<<sp->top()<<' ';
sp->pop();
}
cout<<endl;
return 0;
}
可以運行看看。
如果在vs2008上,在第二次for循環處ix前加上
size_t或int。
指針本身存在調用棧中,指針指的數據在堆中。
㈡ this指針存在的目的是( )
B,this與基類子類的問題沒有關系。只是一個指向自己的指針,訪問自己的數據成員。
㈢ C++this指針的應用參考
this指針只能在一個類的成員函數中調用,它表示當前對象的地址。下面是一個例子: 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指針是類的私有成員。不能做函數參數傳遞。
要得到某個類對象的指針有多種方式。
比如GetParent();
㈤ 一個c++虛函數與this指針的問題
1.
不可以。
2.
是。
3.
是。
你這個疑問就實際上涉及到了編譯技術。this指針你會發現他是C++的關鍵字,而不是在那個頭文件里聲明的變數。也就是說,this指針並不是一個真實存在的C++語言變數,「父類指針不能自動(隱式)轉換為子類指針」實際上是C++語言的變數類型規則,但this指針並非一個變數,所以不需要遵循此規則。從執行中的程序來說,this指針是幫助函數確定對象的位置。
如果非要問,this指針到底是儲存在哪裡?你去看網路,它是這樣說的「不存在所謂的this的「位置」,只是this表示了對象的存儲位置而已。&this違反語義規則,是錯誤的用法,不會編譯通過。」當然,這是從C++語言的層面上來談。在程序運行中,其實確實是有一個地方儲存this指針的值的,不過這只有在非靜態函數被調用才存在的。在X86處理器中,儲存這個值的地方是寄存器ecx,X86-64儲存這個值的地方是rcx。下面給出例子。
void G(IA* a)
{
a->F();
}這段對應的匯編語言重點如下:
mov
rcx,
[rsp+28h+arg_0]
<——這里就是把對象的首地址(就是變數a的值)放在rcx中。
call
qword
ptr
[rax]
<——調用F()函數。
virtual void F()
{
this->member++;
}mov
[rsp+arg_0],
rcx
<——將rcx(其實就是所謂this指針)壓進棧以防rcx寄存器有他用。
mov
rax,
[rsp+arg_0]
mov
eax,
[rax+0Ch]
<——通過this指針找到成員變數member的位置。
inc
eax
<——執行自增操作。
看到了吧,this指針不過就是類成員函數被調用時,被臨時儲存到rcx寄存器的對象首地址。
之所以啰嗦這么多,意思就是讓你明白(如果你被上面所述搞得一頭霧水),從程序實際運行的角度上看,this指針與其說是C++的指針,還不如說是編譯技術里的東西,匯編/機器語言里根本沒有類型一說(當然,機器最多分整數運行儲存單元和浮點數運算儲存單元),自然不存在什麼類型轉換了。
㈥ C++ 基類與派生類中this指針與*this問題
給你說詳細點吧!
sizeof是編譯器在編譯時根據表達式的靜態類型來確定所佔用的存儲空間。
cout << "Base" << endl;
cout << "size of *this is:" << sizeof(*this) << endl;
這里的this的靜態類型是Base指針,所以sizeof( *this )的值就是1了。
㈦ C++this指針的詳細解析
在前面曾經提到過: 每個對象中的數據成員都分別佔有存儲空間,如果對同一個類定義了n個對象,則有n組同樣大小的空間以存放n個對象中的數據成員。但是,不同對象都調用同一個函數代碼段。
那麼,當不同對象的成員函數引用數據成員時,怎麼能保證引用的是所指定的對象的數據成員呢?假如,對於例9.6程序中定義的Box類,定義了3個同類對象a,b,c。
如果有a.volume( ) ,應該是引用對象a中的height,width和length,計算出長方體a的體積。
如果有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」時,應當對它的含義有正確的理解。
㈧ c++的指針用法總結
C++程序設計重要基礎就是類和對象,對象指針是很重要的一部分,包括指向對象的指針、指向對象成員的指針、this指針、指向對象的常指針、指向常對象的指針等。
1、指向對象的指針
定義:對象空間的起始地址就是對象的指針。
說明:在建立對象時,編譯系統就為每個對象分配一定的存儲空間以存放其成員,不過注意,在一般情況下不同對象的數據存儲單元中存放的數據成員是不相同,而不同對象的函數代碼卻是相同的,也就是說,它們的函數代碼是共享的。這時我們可以定義一個指針變數用來存放對象的指針。
定義指向類對象的指針變數的一般形式是:
類名 *對象指針名;
我們就可以通過對象指針訪問對象和對象的成員,假如所定義的類中有數據成員hour、minute、sec,成員函數有gettime(),則
(*p).hour 即為p指向對象中的hour成員,相當於t.hour
(*p).gettime() 即為p指向對象中的成員函數gettime(),相當於t.gettime()
也可以用如下形式:
p->hour 和 p->gettime()和上面是等價的。
2、指向對象成員的指針
(1)指向對象數據成員的指針
在C中我們學過指向普通變數的指針變數,在C++中定義指向對象數據成員的指針變數的方法和定義指向普通變數的指針變數方法相同,其一般形式為:
數據類型名 *指針變數名;
(2)指向對象成員函數的指針
定義指向對象成員函數的指針變數和定義指向普通函數的指針變數不同。
然而編譯系統要求在將函數地址賦給指針變數時必須滿足三個條件:
函數參數類型及個數要匹配
函數返回值的類型要匹配
所屬的類要匹配
顯然在上面的p與類是無關的。為了滿足第三條,我們可以為指針指定類,故定義指向對象成員函數的指針變數一般形式為:
數據類型(類名::*指針變數名)(參數表列);
注意:因為成員函數不存放在對象空間中,多個同類對象共享此成員函數代碼,所以在將成員函數的入口地址賦給指針變數是應寫成:
指向對象成員函數的指針變數=&類名::成員函數名;
在成員函數名後面沒有"()",如果寫成p=&Time::gettime()是錯誤的。[nextp
3、this指針
在每個成員函數中都包含了一個特殊的指針,稱為this,它是指向本類對象的指針,它的值是當前被調用成員函數所在對象的起始地址。之所以有這個指針,是因為為了保證同類的不同對象的成員函數引用的是指定對象中的數據成員,它是系統自動實現的。
假如已經定義了對象t,當調用成員函數t.vol()時,編譯系統就把對象t的起始地址賦給this指針,於是在成員函數引用數據成員時,根據指針this就可以引用到對象t的數據成員。
所以在調用成員函數t.vlo()時,實際的調用方式為t.vol(&t),不過對象t的地址傳給this指針是由系統自動完成的,不需人為加上。
4、指向對象的常指針
將指向對象的指針變數聲明為const型且進行處始化,這樣指針值始終保持為其初值,不能改變其指向。
由上面我們可以看出定義指向對象的常指針的一般形式為:
類名 *const 指針變數名=對象的起始地址;
注意:指向對象的常指針變數的值不能改變,但可以改變它所指向對象中的數據成員的值。
常指針一般用作函數的參數,這樣就不允許在函數執行過程中改變指針變數的值,使其始終保持指向原來的對象。
5、指向常對象的指針變數
首先回顧一下指向常變數的指針變數,其一般形式為:
const 類型名 *指針變數名;
如果一個變數已經被聲明為常變數,那麼只能用指向常變數的指針變數去指向它,而不能用一般的指針變數。另外,指向常變數的指針變數除了可以指向常變數外,還可以指向未被聲明為const的變數,但也不能通過該指針改變其值。
說明:上例中,指針變數p指向字元變數c,並不說把c也聲明成常變數,而只是說在通過指針變數引用c時,c具有常變數的特徵,其值是不能改變的,但c仍然是一個普通變數。
在指向常變數的指針中,關於函數形參的指針類型有幾點值得注意:
如果函數形參是非const型指針變數,實參只能用指向非const型指針;如果函數形參是指向const型變數的指針,實參則可以是const型的或非const型的指針變數。換句話說就是指向常變數的指針可以指向const和非const型的變數,而指向非const型變數的指針只能指向非const的變數。
如果一個對象已經被聲明為長對象,只能用指向常對象的指針變數指向它,而不能用一般的指針變數指向它。
如果定義了一個指向常對象的指針變數且使它指向一個非const的對象,其指向的對象不能通過指針來改變。
如果定義了一個指向常對象的指針變數,是不能通過它改變所指向的對象的值的,但是指針變數本身的值是可以改變的。
所以當我們希望在調用函數時對象的值不被修改,我們就可以把形參定義為const型的指針變數,同時用對象的地址作實參(對象可以是const或非const型);當要求對象不僅在調用函數中不被改變,而且在程序執行過程中也不發生改變,我們就把它定義為const型。所以指向常對象的指針最常用於函數的參數,以保護形參指針所指向的對象在函數執行過程中不被修改。