C++類與對象的詳細說明

類的引入

在引入類之前,先來回憶一下C語言中的結構體。結構體是一種自定義類型,可以在其中定義變量,如我們所熟悉的日期結構體:

struct Date
{
	int year;
	int month;
	int day;
};

而在C++中,結構體被升級成瞭類,結構體中不僅可以定義成員變量,也可以定義成員函數(成員方法):

struct Date
{
	//成員變量
	int year;
	int month;
	int day;
	//成員方法
	void print()
	{
		cout << year << "-" << month << "-" << "day" << endl;
	}
};

在C++中,更喜歡使用class來替代struct,當然它們也有所差別,在之後會說明。

類的定義

類的定義可以分為兩種,即聲明和定義全部放在類體中與聲明與定義分離。

1、聲明和定義全部放在類體中

該方式即為上一舉例代碼的定義方式。但要註意,如果采用這種方法定義成員函數,編譯器可能會將該函數作為內聯函數處理。

2、聲明放在頭文件,定義放在源文件中

頭文件中成員函數隻需要聲明:

struct Date
{
	//成員變量
	int year;
	int month;
	int day;
	//成員方法
	void print();
};

在源文件中對函數進行定義:

void Date::print()
{
	cout << year << "-" << month << "-" << "day" << endl;
}

需要註意,print為類域中的函數,如果不加Date::用以指定類域,會導致定義出錯。因此,使用該方式定義成員函數時,一定要註意指定類域。

類的訪問限定符號及封裝

訪問限定符

訪問限定符分為三種:

(1)public修飾的成員在類外可以直接被訪問:

class Date
{
public:
	int year;
	int month;
	int day;
	void print()
	{
		cout << year << "-" << month << "-" << "day" << endl;
	}
};
int main()
{
	Date date;
	date.day = 0;
}

如上代碼,在main函數中可以直接對對象中的成員變量day進行訪問。

(2)protected和private修飾的成員變量在類外不能被直接訪問

class Date
{
private:
	int year;
	int month;
	int day;
	void print()
	{
		cout << year << "-" << month << "-" << "day" << endl;
	}
};
int main()
{
	Date date;
	date.day = 0;
}

此時如果在main函數中對直接對象中的成員變量day進行訪問,會導致錯誤

 (3)訪問權限作用域是從該訪問限定符的位置開始直到下一個訪問限定符出現時為止

class Date
{
private:
	int year;
	int month;
	int day;
public:
	void print()
	{
		cout << year << "-" << month << "-" << "day" << endl;
	}
};

如上代碼,成員變量均為私有的,而成員函數print為公有的。

(4)class的默認訪問權限(即不寫訪問限定符時)為private,struct為public

封裝

封裝實際上是一種更好的嚴格管理

將數據和方法封裝到類裡,可以訪問的定義為共有,不想給他人訪問的定義為私有或保護。如此一來就做到瞭隱藏對象的屬性和細節,僅僅對外公開接口來和對象進行交互,更加安全高效。

類的實例化

所謂類的實例化,簡而言之就是用類類型創建對象的過程。

打個比方,類就好似建築的圖紙,而對象就是根據圖紙造出的建築。對象是真實存在摸得著的,隻有實例化出的對象才能夠實際存儲數據。

類對象模型

學過C語言我們知道如何計算結構體的大小,那麼在C++中,類的大小如何確定呢?

我們所不清楚的,就是類中成員函數的大小如何計算。實事上對於同一類的不同對象,處理問題的方法是相同的,如果每個對象都要保存一遍成員方法,未免有些過於浪費空間瞭。

因此在C++中,成員函數存放在公共代碼段。計算類的大小隻需要按照C語言中結構體大小的計算規則即可,不需要考慮成員函數。

註意:空類的大小為1byte,不存儲有效數據,但需要占位用以表示對象存在。

this指針

class Date
{
private:
	int _year;
	int _month;
	int _day;
public:
	void init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
};
int main()
{
	Date date1, date2;
	date1.init(2022, 2, 14);
	date2.init(2022, 2, 15);
}

對於上述代碼,有一個問題,date1與date2這兩個對象分別都調用瞭init進行初始化,那麼init函數是如何區分該為哪個對象進行初始化的呢?

C++通過引入this指針解決瞭這個問題。

this指針的特性

1、this指針的類型:類類型* const,存放對象的地址

2、隻能在成員函數內部使用

3、this指針本質上是成員函數的形參,傳參時存放在棧幀中,對象中不存儲this指針

4、this指針為隱藏的形參,不需要用戶傳遞

在上述代碼實際被處理成瞭這樣:

void init(int year, int month, int day)
{
	this->_year = year;
	this->_month = month;
	this->_day = day;
}

總結

本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!    

推薦閱讀: