2.3C++物件模型和this指標

蓝色的海嗷發表於2024-03-17

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,它是特殊值,在常物件下也可以修改

相關文章