首頁>技術>

在c++程式中,去定義一個類物件時,系統會為每一個物件分配儲存空間。

因此,按理說,在一個既有資料又有成員函式時,用同一個類定義多個物件時分配記憶體應該是下面這種情況:

然而很明顯這種方法,有一個重大缺陷:當物件定義比較多時,將在儲存每一個物件中均出現數據和成員函式,而這些成員函式除了僅僅執行的物件不同,其餘程式碼內容完全相同,一個相同的程式碼在每個物件中都儲存,計算機中的資源寸土寸金,這樣造成的記憶體資源大量浪費是很不必要的。

因此在c++中,採取的方法是:物件在儲存時僅僅儲存的為它的資料部分,而他的函式部分儲存的是另一塊儲存空間;一個物件所佔的空間大小隻取決於該物件中資料成員所佔的空間,而與成員函式無關。在呼叫各物件的函式時,都會去呼叫這個公共的函式,從而大大節約儲存空間。即下圖方式:

但是,這樣儲存固然有很大優勢,但是,又有了一個新的問題:即物件使用時,當相同的成員函式引用不同的資料成員時,怎樣能保證引用的是所指向的物件的資料成員呢?

c++中解決這個問題,在每個成員函式中都包含一個特殊的指標,這個指標的名字是固定的,即this指標,每個類都會有一個,它是指向本類物件的指標,它的值是當前被呼叫的成員函式所在物件的起始地址

舉一個例子進行說明:

程式:

#define _CRT_SECURE_NO_WARNINGS 1#include <iostream>#include <string>  using namespace std;class Student{private:	char _name[20];	char _sex[5];	int _age;public:	void InitStudent(char* name, char* sex, int age)//初始化函式	{	strcpy(_name, name);	strcpy(_sex, sex);	_age = age;	}	void PrintStudent()                  //列印函式	{		cout << _name << "  " << _sex << "  " << _age << endl;	}};int main(){	Student s1,s2,s3;	s1.InitStudent("小明","男",18);	s1.PrintStudent();	s2.InitStudent("張三", "女", 17);	s2.PrintStudent();	s3.InitStudent("李四", "男", 20);	s3.PrintStudent();	system("pause");	return 0;}

除錯程式:

1.當程式執行建立物件s1時,開啟監視我們取s1地址,然後除錯程式進入對物件s1進行操作的成員函式,在監視中同樣取this指標的地址

利用同樣的方法對物件s2的地址和對s2資料成員進行操作的成員函式中取this的地址

同樣s3也相同。

​透過對比可以很清晰地看到此時this指標所存的地址就是第一個物件的地址,我們都知道在程式編譯的時候編譯器會重新對程式碼進行重寫,在重寫的時候,編譯器將會在類的成員函式引數中新增this指標引數。

比如:上邊函式

void InitStudent(char* name, char* sex, int age)//初始化函式{	strcpy(_name, name);	strcpy(_sex, sex);	_age = age;}	strcpy(_name, name);	strcpy(_sex, sex);	_age = age;}

在編譯器看來,函式將如下形式:

void InitStudent(Student* const this ,char* name, char* sex, int age)//初始化函式{	strcpy(this->_name, name);	strcpy(this->_sex, sex);	this->_age = age;}

用this指標將物件的起始地址傳給成員函式,進而進行操作。

在vs編譯器下開啟反彙編也可看到函式進行對物件進行操作時,this指標的變化。。

​即this指標先將物件的起始位置傳給成員函式,這樣成員函式引用資料成員時,就會按照this指標的指向找到物件的資料進行操作。

需要注意的是:this指標的型別是*const形;

this指標是類的成員函式獨有的,一般函式無this指標;

this指標的生命週期和成員函式的引數的生命週期相同;

this指標是隱式使用的,它作為引數被編譯器自動傳遞給成員函式;

10
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Visual Studio對CMake工程ARM64的支援