
[C++]類與物件的講解分析(上)
- 前言
- 一、面向程序和面向物件初步認識
- 二、類的引入
- 三、類的定義
- 四、類的訪問限定符以及類的封裝
- 4.1.訪問限定符
- 4.2封裝
- 五、類的作用域
- 六、類的實體化
- 七、類的存盤形式
- 八、類成員函式的this指標
- 總結
前言
關于C++中類的內容講解,因為內容較多,一篇博客的書寫可能會讓人失去對完的信心,所以這一次我將通過多篇小幅度博客對類和物件進行多次講解;如果有讀者學習過java等語言,在閱讀時會輕松許多
一、面向程序和面向物件初步認識
我們在學習C++時,我們知道C++最初的目的是彌補C語言的不足,同時其特性和當時新撰寫的語言相同,開始面向物件進行考慮,考慮各個物件之間的關系;
C語言是面向程序的,關注的程序,分析出解決問題的每個步驟,通過函式呼叫,逐步實作解決問題,
C++是面向物件的,關注的是物件,將一件事情拆分成不同的物件,依靠物件之間的互動完成
二、類的引入

我們在C原因中如果我們想要實作鏈表以及鏈表的增刪查改等操作,我們定義的結構體中只能包含定義的變數,但我們的一些列操作函式卻和我們的結構體分開后;
而我們的C++中,我們的結構體中既可以包含我們定義的變數,同時還可以包含我們的一系列操作函式,
//代碼舉例:
struct ListNode//C語言
{
int val;
struct ListNode* next;
}
struct ListNode//C++
{
int val;
ListNode* next;//C++的特殊之一
}
//代碼舉例:
struct Student
{
void SetStudentInfo(const char* name, const char* gender, int age)//我們在結構體中定義函式
{
strcpy(_name, name);
strcpy(_gender, gender);
_age = age;
}
void PrintStudentInfo()//我們在結構體中定義函式
{
cout<<_name<<" "<<_gender<<" "<<_age<<endl;
}
char _name[20];//C和C++中定義的變數
char _gender[3];
int _age;
};
注意:我們在C++中更喜歡用clss來定義
//代碼舉例:
class Student
{
void SetStudentInfo(const char* name, const char* gender, int age)//我們在結構體中定義函式
{
strcpy(_name, name);
strcpy(_gender, gender);
_age = age;
}
void PrintStudentInfo()//我們在結構體中定義函式
{
cout<<_name<<" "<<_gender<<" "<<_age<<endl;
}
char _name[20];//C和C++中定義的變數
char _gender[3];
int _age;
};
三、類的定義
類的定義如下:
//代碼舉例:
class classname
{
//類成員:函式的宣告和變數的宣告
};//一定要加上';'
注意:
class為定義類的關鍵字,ClassName為類的名字,{}中為類的主體,注意類定義結束時后面分號,
類中的元素稱為類的成員:
類中的資料稱為類的屬性或者成員變數;
類中的函式稱為類的方法或者成員函式,
我們有兩種類的定義方式:
①

②

這里我們更推薦第二種方式,因為當我們在類中定義函式時,如果我們的函式定義過長,函式定義無效,不會將其視為行內函式
四、類的訪問限定符以及類的封裝

4.1.訪問限定符
C++實作封裝的方式:用類將物件的屬性與方法結合在一塊,讓物件更加完善,通過訪問權限選擇性的將其介面提供給外部的用戶使用,
我們上面講述的將變數和方法都定義在類中,其實就是類的封裝;
現在我們先講述一下類中的訪問限定符:

說明:
1. public修飾的成員在類外可以直接被訪問
2. protected和private修飾的成員在類外不能直接被訪問(此處protected和private是類似的)
3. 訪問權限作用域從該訪問限定符出現的位置開始直到下一個訪問限定符出現時為止
4. class的默認訪問權限為private,struct為public(因為struct要兼容C)
4.2封裝
面向物件的三大特性:封裝、繼承、多型,
封裝:將資料和操作資料的方法進行有機結合,隱藏物件的屬性和實作細節,僅對外公開介面來和物件進行,這里我們在上面的講述中其實就是封裝性的體現
我們對封裝性進行一個現實生活中的一個例子:
故宮早期的開發讓游客們可以隨意觀光,但此時帶來的問題就是部分游客隨意修改破壞,導致故宮部分收到損壞,而封裝的出現就像是對故宮進行多方面的保護,比如設定管理員,劃分觀光區域等,使我們的故宮得以保護,不被破壞;對應到類中,我們一些變數不希望被人隨意修改,這個時候我們通過封裝,使得要想使用變數或者修改變數只能通過函式進行,使得我們的變數不會被任意修改使用,得以保護
五、類的作用域
類定義了一個新的作用域,類的所有成員都在類的作用域中,在類體外定義成員,需要使用 :: 作用域決議符指明成員屬于哪個類域,
我們舉例說明:我們程式中有兩個類,而這兩個類中有兩個同名的函式,當我們在對函式進行定義時,我們就需要明確函式的類域
//代碼舉例:
class PersonC
{
public:
void PrintPersonInfo();
private:
char _name[20];
char _gender[3];
int _age;
}
class PersonCPP
{
public:
void PrintPersonInfo();
private:
char _name[20];
char _gender[3];
int _age;
};
// 這里需要指定PrintPersonInfo是屬于PersonCPP這個類域
void PersonCPP::PrintPersonInfo()
{
cout<<_name<<" "_gender<<" "<<_age<<endl;
}
六、類的實體化

說明:
1. 類只是一個模型一樣的東西,限定了類有哪些成員,定義出一個類并沒有分配實際的記憶體空間來存盤它
2. 一個類可以實體化出多個物件,實體化出的物件 占用實際的物理空間,存盤類成員變數
3. 做個比方,類實體化出物件就像現實中使用建筑設計圖建造出房子,類就像是設計圖,只設計出需要什么東西,但是并沒有物體的建筑存在,同樣類也只是一個設計,實體化出的物件才能實際存盤資料,占用物理空間

在這里的類的實體化today、yesterday、tomorrow中都有變數_data、_month、_year但每一個實體化個體中的變數存盤的資訊都不同,就好像我們用同一張圖紙建立了許多了棟樓房,樓房的結構都是一樣大,但每一個樓房中住幾個人,用的什么家具等都是不同的
七、類的存盤形式
我們在創建一個類中,我們知道類中有變數和函式,那么我們一個類的實體化的大小就是我們的變數和函式在計算機中所占的大小嗎?


答案并非如此,在類中,我們類的實體化的大小僅記錄為類中變數所占的空間大小,那為什么我們不將類中的函式所占的空間記錄到我們的實體化中呢?
這個時候我們去想,我們通過類的定義可以實體化許多物件,那么如果我們將類的定義中的函式也都放在每一個物件中時,使得我們的物件所占空間更大,如果我們的類中定義了許多函式,那么我們所需的堆疊幀空間太大,使得我們的堆疊幀開銷可能不足后續使用,
所以我們類的實體化的大小僅即為變數所占的空間大小,我們將類中方法置于公共代碼區,當我們的實體化需要使用時呼叫即可,減省堆疊幀空間的消耗,
八、類成員函式的this指標
我們在講述this指標前先定義一個日期類Data
//代碼舉例:
class Date
{
public :
void Display ()
{
cout <<_year<< "-" <<_month << "-"<< _day <<endl;
}
//void SedDate(Date* this,int year,int month,int day)
//{
// this->_year = year;
// this->_month = month;
// this->_day = day;
//}
void SetDate(int year , int month , int day)
{
_year = year;
_month = month;
_day = day;
}
private :
int _year ; // 年
int _month ; // 月
int _day ; // 日
};
int main()
{
Date d1, d2;
d1.SetDate(2018,5,1);//d1.SetDate(&d1,2018,5,1);
d2.SetDate(2018,7,1);//d2.SetDate(&d2,2018,7,1);
d1.Display();
d2.Display();
return 0;
}
我們在main函式中實作對物件d1和d2的變數初始化和變數的列印,但這個時候我們注意到我們在對物件d1和d2進行初始化時,沒有像C語言中使用指標資料型別去作為引數接受實參,而只是傳遞了要改變的變數的資料,那這樣是如何實作對物件的變數進行改變的呢?
另一個問題:Date類中有SetDate與Display兩個成員函式,函式體中沒有關于不同物件的區分,那當s1呼叫SetDate函式時,該函式是如何知道應該設定s1物件,而不是設定s2物件呢?
這里的解決辦法實際上是:
C++中通過引入this指標解決該問題,即:C++編譯器給每個“非靜態的成員函式“增加了一個隱藏的指標引數,讓該指標指向當前物件(函式運行時呼叫該函式的物件),在函式體中所有成員變數的操作,都是通過該指標去訪問,只不過所有的操作對用戶是透明的,即用戶不需要來傳遞,編譯器自動完成,
我們在讀上述的內容時仍可能不理解是什么意思,下面我們通過對代碼進行圖解進行講述:

總結
這里我們對主要類的封裝性和this進行了講述,而這兩個特點是我們C語言中不曾有過的特性,這里需要我們對其進行仔細理解;封裝性是將我們的變數和函式進行統一定義,同時對不同的變數和函式進行訪問限定符修飾;而this指標是我們函式中默認的實作,避免了我們再創建改變資料型別的指標,更方便我們函式功能的實作
以上是我對類和物件的個人認識,后續我們會繼續講解類和物件的內容
上述內容如果有錯誤的地方,還麻煩各位大佬指教【膜拜各位了】【膜拜各位了】

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/321332.html
標籤:其他
上一篇:14 軟硬鏈接
