C++對象模型和this指針詳解
對象模型
成員變量和成員函數(shù)分開存儲
一、
只有非靜態(tài)成員變量才屬于類的對象上
空對象占用字節(jié)為1
class Person
{
};
void test01()
{
Person p;
cout << "size of = " << sizeof(p) << endl;
}
int main()
{
test01();
system("pause");
return 0;
}

占用內(nèi)存空間為 1 的原因是:如果有其他的空對象,各自分配一個內(nèi)存空間可以讓兩者之間相互區(qū)別,而且 1 字節(jié)也很省內(nèi)存。 所以每個空對象都會有一個自己的內(nèi)存地址。
二、
class Person
{
int m_A;//改為有內(nèi)容
};
void test02()
{
Person p;
cout << "size of = " << sizeof(p) << endl;
}
int main()
{
test02();
system("pause");
return 0;
}

因為 int 類型 ,不把之前的空類型考慮進(jìn)去。
三、
將Person類改為
class Person
{
int m_A;// 非靜態(tài)成員變量 屬于類的對象上
static int m_B;// 添加 靜態(tài)成員變量 不屬于類的對象上
};
int Person::m_B = 0;

非靜態(tài)成員變量 屬于類的對象上
靜態(tài)成員變量,不屬于類對象上
所以不考慮在內(nèi)
四、
class Person
{
int m_A;// 非靜態(tài)成員變量 屬于類的對象上
static int m_B;// 添加 靜態(tài)成員變量 不屬于類的對象上
void func() //非靜態(tài)成員函數(shù)
{
}
};
int Person::m_B = 0;

所以成員變量和成員函數(shù)是分開存儲的,非靜態(tài)成員函數(shù)不屬于類對象上
五、
static voidfunc()
{}
靜態(tài)成員函數(shù)也不會增加 不屬于類對象上
this指針
用于區(qū)分類中多個對象調(diào)用函數(shù)時,分別都是哪個函數(shù)在調(diào)用自己。
this 指針指向被調(diào)用成員函數(shù)所屬的對象
特點:
1. this指針是隱含每一個非靜態(tài)成員函數(shù)內(nèi)的一種指針
2.this 指針不需要定義,直接使用即可。
用途:
1.當(dāng)形參和成員變量同名時,可用this指針來區(qū)分
2.在類的非靜態(tài)成員變量中返回對象本身,可使用return *this
一、
class Person
{
public:
Person(int age)//變量
{
//this指針指向的是被調(diào)用成員函數(shù)的所屬對象
//即 p1, 所以可以解決和變量的名稱沖突
this->age = age;//前一個為成員變量,后一個age為形參
}
int age;
};
void test01()
{
Person p1(18);
cout << "p1的年齡為: " << p1.age << endl;
}
main()
{
test01();
system("pause");
return 0;
}
如果不加 this 都會默認(rèn)為形參 age ,從而報錯。
this 指向被調(diào)用的對象,此時為 p1。
二、
class Person
{
public:
Person(int age)
{
//this指針指向的是被調(diào)用成員函數(shù)的所屬對象
//即 p1, 所以可以解決和變量的名稱沖突
this->age = age;
}
void PersonAddAge(Person &p)
{
this->age += p.age;
}
int age;
};
void test01()
{
Person p1(18);
cout << "p1的年齡為: " << p1.age << endl;
}
//返回對象本身用*this
void test02()
{
Person p1(10);
Person p2(10);
p2.PersonAddAge(p1);
cout << "p2年齡:" << p2.age << endl;
}
int main()
{
test01();
test02();
system("pause");
return 0;
}
此時p2為 20 ,若要多次相加需要改動為
class Person
{
public:
Person(int age)
{
//this指針指向的是被調(diào)用成員函數(shù)的所屬對象
//即 p1, 所以可以解決和變量的名稱沖突
this->age = age;
}
Person& PersonAddAge(Person &p)//此處void 改為Peroson是因為返回值如果是p2的話,就可以將p2.PersonAddAge(p1) 看作p2,然后繼續(xù)調(diào)用之后的PersonAddAge(p1)
//此處的Person &p是以 引用的方式傳入
//此處的Person& 是以引用的方式返回
{
this->age += p.age;
// this是指向p2的指針,而*this就是p2本體
return* this;
}
int age;
};
void test01()
{
Person p1(18);
cout << "p1的年齡為: " << p1.age << endl;
}
//返回對象本身用*this
void test02()
{
Person p1(10);
Person p2(10);
p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);
cout << "p2年齡:" << p2.age << endl;
}
int main()
{
test01();
test02();
system("pause");
return 0;
}

鏈?zhǔn)骄幊趟枷耄嚎梢酝鬅o限的追加。
但如果函數(shù),不使用引用方法,返回的是一個值,就會創(chuàng)建新的對象
Person PersonAddAge(Person &p)//不使用引用方法
{
this->age += p.age;
// this是指向p2的指針,而*this就是p2本體
return* this;
}
int age;
};
在第一次調(diào)用Person PersonAddAge()后 ,p2加了10, 但在這之后返回的并不是本體了,而是根據(jù)本體創(chuàng)建的一個新的數(shù)據(jù)。Person 和 *this 是不一樣的數(shù)據(jù)(見拷貝構(gòu)造函數(shù)的調(diào)用時機-以值方式返回局部對象)。 所以每一次Person PersonAddAge()后,都是一個新的對象,所以最后輸出結(jié)果p2 是不變的20。
疑問:至于為什么不是p2 為 10 。 以值方式返回局部對象會調(diào)用拷貝構(gòu)造函數(shù)。對p2進(jìn)行一次PersonAddAge操作后,將p2的結(jié)果拷貝為p2' 。所以p2還是經(jīng)過了一次加年齡的操作的 。對p2進(jìn)行一次PersonAddAge操作后,將p2的結(jié)果拷貝為p2'
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
C++用winapi?socket實現(xiàn)局域網(wǎng)語音通話功能
這篇文章主要介紹了socket實現(xiàn)局域網(wǎng)語音通話?c++?winapi,功能介紹支持錄音設(shè)備查找以及播放設(shè)備查找,支持局域網(wǎng)語音通話,通話包含語音來電提醒和掛斷電話的提示信息,還能實時的獲取在線用戶的數(shù)量以及對應(yīng)的id,需要的的朋友一起看看2022-06-06
Qt?關(guān)于容器的遍歷迭代器的使用問題小結(jié)
Qt是一個跨平臺的 C++ 開發(fā)庫,主要用來開發(fā)圖形用戶界面程序,當(dāng)然也可以開發(fā)不帶界面的命令行程序,本文重點給大家介紹Qt?關(guān)于容器的遍歷迭代器的使用問題小結(jié),感興趣的朋友一起看看吧2022-03-03
深入了解C++優(yōu)先隊列(priority_queue)的使用方法
在計算機科學(xué)中,優(yōu)先隊列是一種抽象數(shù)據(jù)類型,它與隊列相似,但是每個元素都有一個相關(guān)的優(yōu)先級。C++中的優(yōu)先隊列是一個容器適配器(container adapter),它提供了一種在元素之間維護(hù)優(yōu)先級的方法。本文帶你深入了解C++優(yōu)先隊列的使用方法,需要的可以參考下2023-05-05
C++ EasyX學(xué)習(xí)之鼠標(biāo)操作詳解
EasyX是針對C/C++的圖形庫,可以幫助使用C/C++語言的程序員快速上手圖形和游戲編程。本文將為大家詳細(xì)講講EasyX的鼠標(biāo)操作,需要的可以參考一下2022-07-07

