1、成員變數和成員函式分開儲存
在C++中,類內的成員變數和成員函式分開儲存
只有非靜態成員變數才屬於類的物件上
空物件佔用記憶體空間為1。
C++編譯器會為每個空物件也分配1個位元組的空間,是為了區分空物件佔記憶體的位置。
每個空物件也應該有一個獨一無二的記憶體地址。
calss Person
{
int m_A; //非靜態成員變數,屬於類的物件上
static int m_B; //靜態成員變數,不屬於類的物件上
void func(){} //非靜態成員函式,不屬於類物件上
static void func(){} //靜態成員函式,不屬於類的物件上
};
2、this指標概念
C++中,類內的成員變數和成員函式分開儲存。
每一個非靜態成員函式只會誕生一份函式例項,也就是說多個同型別的物件會共用一塊程式碼。
那麼問題是:這一塊程式碼是如何區分哪個物件呼叫自己的呢?
C++透過提供特殊的物件指標:this指標,來解決上述問題。
this指標指向備呼叫的成員函式所屬的物件。
this指標是隱含每一個非靜態成員函式內的一種指標。
this指標不需要定義,可以直接使用。
this指標的本質是指標常量,指標的指向是不可以修改的。
this指標的用途:
當形參和成員變數同名時,可用this指標來區分
1、解決名稱衝突
衝突情況:
class Person
{
public:
Person(int age)
{
age = age;
}
int age;
}; //會報錯,上面有4個age,名稱衝突,這會導致無法進行賦值操作
使用this指標來解決該問題:
class Person
{
public:
Person(int age)
{
this->age = age;
//this指標指向的是備呼叫的成員函式所屬的物件
}
int age;
};
在類的非靜態成員函式中返回物件本身,可使用 return * this
2、返回物件本身用 *this
Person& PersonAddAge(Person &p) //返回值是引用類,傳入也是引用傳遞
{
this->age += p.age;
//this指向p2的指標,而*this指向的就是p2這個物件本體
return *this;
}
void test02()
{
Person p1(10);
Person p2(10);
//鏈式程式設計思想
p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);
cout << "p2的年齡為:" << p2.age << endl; //輸出結果為40,加了3次
}
3、空指標訪問成員函式
C++中空指標也是可以呼叫成員函式的,但是也要注意有沒有用到this指標。
如果用到this指標,需要加以判斷保證程式碼的健壯性。
void showPersonAge()
{
cout << "age = " << this->m_age << endl;
//錯誤,報錯原因是因為傳入的指標是為NULL,空指標沒有東西訪問
}
如何防止出現空指標訪問的情況?
void showPersonAge()
{
if(this == NULL) //如果是空指標就直接return出去
{
return;
}
cout << "age = " << this->m_age << endl;
}
4、const修飾成員函式
常函式:
成員函式後加const後我們稱為這個函式為常數
常函式內不可以修改成員屬性
成員屬性宣告時加關鍵字mutable後,在常函式中依然可以修改
//this指標的本質是指標常量,指標的指向是不可以修改的
void showPerson() const //在成員函式後面加const,修飾的是this指標,讓指標指向的值也不可以修改
{
this->m_B = 100;//特殊變數,可以修改
this->m_A = 100; //會報錯!不可以修改!
}
int m_A;
mutable int m_B; //特殊變數,即使在常函式中,也可以修改這個值
常物件:
宣告物件前加const稱該物件為常物件
常物件只能呼叫常函式
const Person p; //在物件前加const,變為常物件
p.m_A = 100; //報錯,因為p是常物件
p.m_B = 100; //m_B前加了mutable,它是特殊值,在常物件下也可以修改