[C++之旅] 16 對(duì)象指針/對(duì)象成員指針/this指針
一视事、對(duì)象指針
- 對(duì)象指針指向堆中地址
類(lèi)名 *對(duì)象指針 = new 類(lèi)名();//或者類(lèi)名 *對(duì)象指針 = NULL; 對(duì)象指針 = new 類(lèi)名监憎;
delete 對(duì)象指針绞呈;
對(duì)象指針 = NULL贸人;
- 對(duì)象指針指向棧中地址
類(lèi)名 對(duì)象;
類(lèi)名 *對(duì)象指針 = &對(duì)象佃声;
delete 對(duì)象指針艺智;
對(duì)象指針 = NULL;
訪(fǎng)問(wèn)對(duì)象指針的成員有兩種方式如下:
對(duì)象指針->成員/函數(shù)...
(*對(duì)象指針).成員/函數(shù)...
二圾亏、對(duì)象成員指針
即對(duì)象成員采用new運(yùn)算符實(shí)例化十拣,實(shí)例化一個(gè)包含對(duì)象成員指針的對(duì)象時(shí),其對(duì)象所占用的內(nèi)存為對(duì)象中成員+對(duì)象指針本身的大小志鹃,并不包含對(duì)象指針申請(qǐng)的堆中內(nèi)存夭问,因此在執(zhí)行該對(duì)象的析構(gòu)函數(shù)時(shí)不會(huì)自動(dòng)釋放堆中內(nèi)存,需用戶(hù)在析構(gòu)函數(shù)中自行釋放曹铃,其釋放內(nèi)存的順序?yàn)橄柔尫艑?duì)象指針堆中的內(nèi)存再將對(duì)象本身的內(nèi)存釋放缰趋。
class Coordinate
{
public:
Coordinate(int x, int y):
m_x(x), m_y(y){}
private:
int m_x;
int m_y;
};
Coordinate表示點(diǎn)的類(lèi),其中包含點(diǎn)的xy坐標(biāo)
class Line
{
public:
Line(int x1, int y1, int x2, int y2);
private:
Coordinate *m_coorA;
Coordinate *m_coorB;
};
Line::Line(int x1, int y1, int x2, int y2)
{
m_coorA = new Coordinate(x1, y1);
m_coorB = new Coordinate(x2, y2);
}
Line::~Line()
{
delete m_coorA;
m_coorA = NULL;
delete m_coorA;
m_coorA = NULL;
}
Line表示線(xiàn)的類(lèi),包含AB兩個(gè)坐標(biāo)點(diǎn)的指針秘血,使用對(duì)象成員指針時(shí)一定要在析構(gòu)函數(shù)中釋放掉味抖。
int main(void)
{
Line *p = new Line(1, 2, 4, 5);
delete p;
p = NUll;
return 0;
}
三、this指針
class Coordinate
{
public:
Coordinate(int x, int y):
m_x(x), m_y(y){}
void setpoint(x, y);
private:
int m_x;
int m_y;
};
以坐標(biāo)這個(gè)類(lèi)為例灰粮,在實(shí)例化三個(gè)點(diǎn)時(shí)仔涩,會(huì)在內(nèi)存中新建三個(gè)數(shù)據(jù)成員,而成員函數(shù)卻只有一份存在代碼區(qū)粘舟。三個(gè)對(duì)象只有一個(gè)成員函數(shù)熔脂,那在調(diào)用成員函數(shù)時(shí),編譯器是怎么知道操作的是哪個(gè)對(duì)象的數(shù)據(jù)成員呢柑肴?其實(shí)每個(gè)成員函數(shù)中都包含this指針锤悄,作為入口參數(shù),編譯器根據(jù)入口的指針?lè)直媸褂媚膫€(gè)數(shù)據(jù)成員嘉抒,其函數(shù)原型如下零聚,為例方便 C++編譯器將this“省略”了,其實(shí)在編譯時(shí)編譯器自動(dòng)為每一個(gè)成員函數(shù)的參數(shù)列表加了一個(gè)this 指針些侍。
class Coordinate
{
public:
Coordinate(T *this, int x, int y):
m_x(x), m_y(y){}
void setpoint(T *this, x, y);
private:
int m_x;
int m_y;
};
int main()
{
Coordinate coorA(this, 1, 3);
coorA.setpoint(this, 3, 4);
Coordinate coorB(this, 1, 3);
coorB.setpoint(this, 3, 4);
return 0;
}
-
this解決參數(shù)名與成員數(shù)據(jù)名同名問(wèn)題
上面理解了this指針隶症,那this指針在c++中怎么使用呢?如下實(shí)例setpoint函數(shù)的輸入?yún)?shù)與成員變量名相同岗宣,在執(zhí)行賦值語(yǔ)句時(shí)編譯器無(wú)法分清哪個(gè)時(shí)參數(shù)哪個(gè)時(shí)成員變量蚂会,此時(shí)在前面加入this指針可以讓編譯器知道為成員變量。
class Coordinate { public: Coordinate(int x, int y): m_x(x), m_y(y){} void setpoint(m_x, m_y); private: int m_x; int m_y; }; void Coordinate::setpoint(m_x, m_y) { this->m_x = m_x; this->m_y = m_y; } int main() { Coordinate coorA(1, 3); coorA.setpoint(3, 4); Coordinate coorB(1, 3); coorB.setpoint(3, 4); return 0; }
-
this作為返回值
將setpoint函數(shù)進(jìn)行修改耗式,返回this對(duì)象(this為指針胁住,*this為對(duì)象),也就是返回當(dāng)前對(duì)象刊咳。
Coordinate& Coordinate::setpoint(m_x, m_y) { this->m_x = m_x; this->m_y = m_y; return *this; } int main() { Coordinate coorA(1, 3); coorA.setpoint(3, 4).setpoint(5, 6); Coordinate coorB(1, 3); coorB.setpoint(3, 4); return 0; }
其最終coorA的坐標(biāo)為(5彪见,6)。因?yàn)榉祷氐臑閠his對(duì)象的引用娱挨,其實(shí)返回的就是coorA這個(gè)對(duì)象余指。若將setpoint改為:
Coordinate Coordinate::setpoint(m_x, m_y) { this->m_x = m_x; this->m_y = m_y; return *this; }
則不會(huì)修改coorA的成員數(shù)據(jù),此時(shí)返回的是一個(gè)新的Coordinate的對(duì)象跷坝,操作的并不少coorA了酵镜。
除了采用引用的方式,還可以采用指針的方式柴钻,如下:
Coordinate* Coordinate::setpoint(m_x, m_y) { this->m_x = m_x; this->m_y = m_y; return this; } int main() { Coordinate coorA(1, 3); coorA.setpoint(3, 4)->setpoint(5, 6); Coordinate coorB(1, 3); coorB.setpoint(3, 4); return 0; }
這種方式也是可以的淮韭,只是在利用指針的形式訪(fǎng)問(wèn)成員變量時(shí),需使用
->
符號(hào)贴届。