C++物件模型和this指標
阿新 • • 發佈:2021-08-11
成員變數和成員函式分開儲存
在C++中,類內的成員變數和成員函式分開儲存
只有非靜態成員變數才屬於類的物件上
#include <iostream> using namespace std; class Person { public: int m_A; static int m_B; void func() { } }; int Person::m_B = 0; int main() { Person p; cout << sizeof(p) << endl; //4 //空物件佔用的記憶體空間為 1 //不是空物件,比如有一個int成員變數 記憶體空間變為4 //靜態成員不屬於類的物件上 不佔記憶體空間 //成員函式 屬於類的物件上 不佔記憶體空間 }
this 指標概念
我們知道了C++成員變數和成員函式是分開儲存的
每一個非靜態成員函式只會誕生一份函式例項,也就是說多個同類型物件會共用一塊程式碼
那麼問題是:這一塊程式碼是如何區分哪個物件呼叫自己的?
C++通過提供特殊的物件指標,this 指標,解決上述問題,this指標指向被呼叫的成員函式所屬的物件
this指標是隱含每一個非靜態成員函式內的一種指標
this指標不需要定義,直接用即可
this指標的用途:
- 當形參和成員變數同名時,可用this指標來區分
- 在類的非靜態成員函式中返回物件本身,可使用 return *this
#include <iostream> using namespace std; class Person { public: Person(int age) { this->age = age; //解決名稱衝突,this指標指向被呼叫的成員函式所屬的物件 } Person& PersinAddAge(Person &p) {this->age += p.age; return *this; //this指向p2的指標,而*this指向的就是p2這個物件本體 } int age; }; int main() { Person p1(10);//這裡呼叫有參構造,this指向p1 cout << "p1的年齡為:" << p1.age << endl; //10 Person p2(10); //鏈式程式設計思想 p2.PersinAddAge(p1).PersinAddAge(p1).PersinAddAge(p1); cout << "p2的年齡為:" << p2.age << endl; //40 如果不是引用的返回則是20 }
空指標訪問成員函式
C++中空指標也是可以呼叫成員函式的,但是也要注意有沒有用到this指標
如果用到this指標,需要加以判斷保證程式碼的健壯性
#include <iostream> using namespace std; class Person { public: void showClassName() { cout << "this is Person class" << endl; } void showPersonAge() { //提高健壯性 if (this == NULL) { return; } //報錯的原因是傳入的指標為空 cout << "age = " << m_Age << endl; //相當於this->m_Age } int m_Age; }; int main() { Person * p = NULL; p->showClassName(); //不報錯 p->showPersonAge(); //錯誤 }
const修飾成員函式
常函式:
- 成員函式後加const後我們稱這個函式為常函式
- 常函式內不可以修改成員屬性
- 成員屬性宣告加關鍵字mutable後,在常函式中依然可以修改
常物件:
- 宣告物件前加const稱該物件為常物件
- 常物件只能呼叫常函式
#include <iostream> using namespace std; class Person { public: //this指標的本質 是指標常量 指標的指向不可以修改 void showPerson() const{ //const修飾的是this指標 讓指標指向的值也不可以修改 //相當於const Person * const this //this = NULL; this指標不可以修改指標的指向 //m_A = 100; this->m_A報錯 不可以修改指標指向的值 m_B = 100; // 不報錯 } void test(){ m_A = 100; } int m_A; mutable int m_B; //即使在常函式中,也可以修改 }; int main() { Person p; p.showPerson(); const Person p2{}; //常物件,不能修改指標指向的值 //p2.m_A = 100; 不可修改屬性 p2.m_B = 100; p2.showPerson(); //只能呼叫常函式 //p2.test(); 不能呼叫普通成員函式 因為普通成員函式可以修改屬性 }