C++對象模型和this指針詳解
對象模型
成員變量和成員函數分開存儲
一、
隻有非靜態成員變量才屬於類的對象上
空對象占用字節為1
class Person { }; void test01() { Person p; cout << "size of = " << sizeof(p) << endl; } int main() { test01(); system("pause"); return 0; }
占用內存空間為 1 的原因是:如果有其他的空對象,各自分配一個內存空間可以讓兩者之間相互區別,而且 1 字節也很省內存。 所以每個空對象都會有一個自己的內存地址。
二、
class Person { int m_A;//改為有內容 }; void test02() { Person p; cout << "size of = " << sizeof(p) << endl; } int main() { test02(); system("pause"); return 0; }
因為 int 類型 ,不把之前的空類型考慮進去。
三、
將Person類改為
class Person { int m_A;// 非靜態成員變量 屬於類的對象上 static int m_B;// 添加 靜態成員變量 不屬於類的對象上 }; int Person::m_B = 0;
非靜態成員變量 屬於類的對象上
靜態成員變量,不屬於類對象上
所以不考慮在內
四、
class Person { int m_A;// 非靜態成員變量 屬於類的對象上 static int m_B;// 添加 靜態成員變量 不屬於類的對象上 void func() //非靜態成員函數 { } }; int Person::m_B = 0;
所以成員變量和成員函數是分開存儲的,非靜態成員函數不屬於類對象上
五、
static voidfunc()
{}
靜態成員函數也不會增加 不屬於類對象上
this指針
用於區分類中多個對象調用函數時,分別都是哪個函數在調用自己。
this 指針指向被調用成員函數所屬的對象
特點:
1. this指針是隱含每一個非靜態成員函數內的一種指針
2.this 指針不需要定義,直接使用即可。
用途:
1.當形參和成員變量同名時,可用this指針來區分
2.在類的非靜態成員變量中返回對象本身,可使用return *this
一、
class Person { public: Person(int age)//變量 { //this指針指向的是被調用成員函數的所屬對象 //即 p1, 所以可以解決和變量的名稱沖突 this->age = age;//前一個為成員變量,後一個age為形參 } int age; }; void test01() { Person p1(18); cout << "p1的年齡為: " << p1.age << endl; } main() { test01(); system("pause"); return 0; }
如果不加 this 都會默認為形參 age ,從而報錯。
this 指向被調用的對象,此時為 p1。
二、
class Person { public: Person(int age) { //this指針指向的是被調用成員函數的所屬對象 //即 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指針指向的是被調用成員函數的所屬對象 //即 p1, 所以可以解決和變量的名稱沖突 this->age = age; } Person& PersonAddAge(Person &p)//此處void 改為Peroson是因為返回值如果是p2的話,就可以將p2.PersonAddAge(p1) 看作p2,然後繼續調用之後的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; }
鏈式編程思想:可以往後無限的追加。
但如果函數,不使用引用方法,返回的是一個值,就會創建新的對象
Person PersonAddAge(Person &p)//不使用引用方法 { this->age += p.age; // this是指向p2的指針,而*this就是p2本體 return* this; } int age; };
在第一次調用Person PersonAddAge()後 ,p2加瞭10, 但在這之後返回的並不是本體瞭,而是根據本體創建的一個新的數據。Person 和 *this 是不一樣的數據(見拷貝構造函數的調用時機-以值方式返回局部對象)。 所以每一次Person PersonAddAge()後,都是一個新的對象,所以最後輸出結果p2 是不變的20。
疑問:至於為什麼不是p2 為 10 。 以值方式返回局部對象會調用拷貝構造函數。對p2進行一次PersonAddAge操作後,將p2的結果拷貝為p2′ 。所以p2還是經過瞭一次加年齡的操作的 。對p2進行一次PersonAddAge操作後,將p2的結果拷貝為p2′
總結
本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!
推薦閱讀:
- 帶你瞭解C++this指針的用法及其深究
- C++靜態成員函數和this指針詳解
- C++ this指針和空指針的具體使用
- 聊聊c++數組名稱和sizeof的問題
- C++類中三大函數詳解(構造、析構和拷貝)