做電影小視頻在線觀看網(wǎng)站整合營銷傳播工具有哪些
1. 類的定義
類是C++中的一種自定義類型,是某個具體事物或概念的抽象化代碼表示,通過類的成員(變量+函數(shù)/方法),可以表征出事物或概念的特征。
1.1 類定義的格式
class Stack
{
public:// 成員函數(shù)void Init(int n = 4){array = (int*)malloc(sizeof(int) * n);if (nullptr == array){perror("malloc申請空間失敗");return;}capacity = n;top = 0;}void Push(int x){// ...擴容array[top++] = x;}int Top(){assert(top > 0);return array[top - 1];}void Destroy(){free(array);array = nullptr;top = capacity = 0;}
private:// 成員變量int* array;size_t capacity;size_t top;
}; // 分號不能省略
class為定義類的關鍵字,Stack為類的名字,{}中為類的主體,注意類定義結束時后面分號不能省 略。類和C語言中的結構體類似,類體中內(nèi)容稱為類的成員:類中的變量稱為類的屬性或成員變量; 類中的函數(shù)稱為類的方法或者成員函數(shù)/類函數(shù)。一般來說,這些類函數(shù)是專門設計來服務于這個類類型的變量(對象)。
為了區(qū)分成員變量,一般習慣上成員變量會加一個特殊標識,如成員變量前面或者后面加_ 或者 m 開頭,注意C++中這個并不是強制的,只是一些慣例,具體看公司的要求。
// _成員變量名
int* _array;
size_t _capacity;
size_t _top;// 成員變量名_
int* array_;
size_t capacity_;
size_t top_;// m成員變量名
int* mArray;
size_t mCapacity;
size_t mTop;
C++中struct也可以定義類,C++兼容C中struct的用法,同時struct升級成了類,明顯的變化是 struct中可以定義函數(shù),一般情況下我們還是推薦用class定義類。
定義在類中的成員函數(shù)默認為inline。
1.2?訪問限定符
上面Stack類中的“public”和“private”就是訪問限定符,除此之外,還有“protected”。
他們的作用是限定類成員被訪問的權限。
? C++一種實現(xiàn)封裝的方式,用類將對象的屬性與方法結合在一塊,讓對象更加完善,通過訪問權限選擇性的將其接口提供給外部的用戶使用。
? public修飾的成員在類外可以直接被訪問;protected和private修飾的成員在類外不能直接被訪問,protected和private是一樣的,以后繼承章節(jié)才能體現(xiàn)出他們的區(qū)別。
? 訪問權限作用域從該訪問限定符出現(xiàn)的位置開始直到下?個訪問限定符出現(xiàn)時為止,如果后面沒有訪問限定符,作用域就到 “}”即類結束。
? class定義成員沒有被訪問限定符修飾時默認為private,struct默認為public。
? 一般成員變量都會被限制為private/protected,需要給別人使用的成員函數(shù)會放為public。
習慣上,被public修飾的成員統(tǒng)一放到前面,被private修飾的成員統(tǒng)一放到后面。
被public修飾的一般是類函數(shù),被private修飾的一般是成員變量。
1.3?類域
類定義了一個新的作用域,類的所有成員都在類的作用域中,在類體外定義成員時,需要使用?:: 作 用域操作符指明成員屬于哪個類域。
前面提到,在類中定義的函數(shù)默認為inline函數(shù),如果不希望某個函數(shù)被當作inline函數(shù),則可將類函數(shù)的聲明與定義分開,只在類中聲明,而在類外進行定義。
class Stack
{
public:// 成員函數(shù)void Init(int n = 4);void Push(int x);int Top();void Destroy();
private:// 成員變量int* array;size_t capacity;size_t top;
}; // 分號不能省略void Stack::Init(int n = 4)
{array = (int*)malloc(sizeof(int) * n);if (nullptr == array){perror("malloc申請空間失敗");return;}capacity = n;top = 0;
}
void Stack::Push(int x)
{// ...擴容array[top++] = x;
}
int Stack::Top()
{assert(top > 0);return array[top - 1];
}
void Stack::Destroy()
{free(array);array = nullptr;top = capacity = 0;
}
類域影響的是編譯的查找規(guī)則,上面程序中的函數(shù)如果不指定類域Stack,那么編譯器就把這些函數(shù)當成全局函數(shù),那么編譯時,找不到array等成員的聲明/定義在哪里,就會報錯。指定類域Stack,就是知道這些函數(shù)是成員函數(shù),當前域找不到的array等成員,就會到類域中去查找。
2. 對象的定義(實例化)
簡單來說,類只是一種類似于結構體的類型,用類類型定義出的變量,就是該類的對象。
2.1 實例化的概念
用類類型在物理內(nèi)存中創(chuàng)建對象的過程,稱為類實例化出對象。
類是對象進行的一種抽象描述,是一個模型一樣的東西,限定了類有哪些成員變量,這些成員變量只是聲明,沒有分配空間,用類實例化出對象時,才會分配空間。
一個類可以實例化出多個對象,實例化出的對象占用實際的物理空間,存儲類成員變量。打個比方:類實例化出對象就像現(xiàn)實中使用建筑設計圖建造出房子,類就像是設計圖,設計圖規(guī)劃了有多 少個房間,房間大小功能等,但是并沒有實體的建筑存在,也不能住人,用設計圖修建出房子,房 子才能住人。同樣類就像設計圖一樣,不能存儲數(shù)據(jù),實例化出的對象分配物理內(nèi)存存儲數(shù)據(jù)。
以“Date類”為例:
class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout << _year << "/" << _month << "/" << _day << endl;}
private:// 這?只是聲明,沒有開空間int _year;int _month;int _day;
};
這里給出了定義“Date類”類型變量的藍圖,利用該類進行實例化,就可以得到“Date類”類型的變量。
int main()
{// Date類實例化出對象day1和day2Date day1;Date day2;return 0;
}
2.2 this指針
相信讀者已經(jīng)注意到,類函數(shù)看上去似乎有些奇怪:這些函數(shù)直接使用了類中的成員變量,而沒有對應形參的傳入,那么這些函數(shù)怎么知道成員變量是誰的呢?。
我們從類函數(shù)的調(diào)用方式入手:
int main()
{Date day1;day1.print(2024, 7, 29);Date day2;day2.print(2004, 12, 18);return 0;
}
因為類函數(shù)也是類的成員,所以使用成員訪問操作符“.”訪問對象的成員即可調(diào)用類函數(shù)。
可以看到,類函數(shù)的調(diào)用是與某個對象綁定在一起的,所以類函數(shù)能知道成員變量是哪個對象的。
但是,在底層上是如何做到的呢?
編譯器編譯后,類的成員函數(shù)默認都會在形參第一個位置,增加一個當前類類型的指針,叫做“this指針”。比如Date類的Init的真實原型為:?
void Init(Date* const this, int year, int month, int day);
所以,在調(diào)用類函數(shù)時,當前對象的地址就會通過“this指針”傳入函數(shù)中,函數(shù)就能對該對象的成員變量進行操作。
類的成員函數(shù)中訪問成員變量,本質都是通過this指針訪問的,如Init函數(shù)中給_year賦值的語句相當于是:
?this->_year = year;
2.3 對象的大小
我們已經(jīng)了解過C語言中結構體的大小C語言結構體的大小,結構體內(nèi)存對齊_c語言 struct大小-CSDN博客
相比于結構體,類增加了成員函數(shù),那么這些成員函數(shù)會使實例化出的對象的空間如何變化呢?
對于同一個類,不同的對象之間成員變量一般不同,但是成員函數(shù)完全相同。所以,沒有單獨為每一個對象存儲成員函數(shù)的必要。其次,函數(shù)被編譯后是一段指令,對象中沒辦法存儲,這些指令 存儲在一個單獨的區(qū)域(代碼段),那么對象中非要存儲的話,也只能是成員函數(shù)的指針。同一個函數(shù)只有一個地址,也沒有必要分別存儲。最后,其實函數(shù)指針本身就是不需要存儲的,函數(shù)指針是一個地址,調(diào)用函數(shù)被編譯成匯編指令[call 地址], 其實編譯器在編譯鏈接時,就要找到函數(shù)的地址,不是在運行時找,只有動態(tài)多態(tài)是在運行時找,就需要存儲函數(shù)地址,這個我們以后會講解。
總結來說,每個類的對象的大小只與成員變量有關,成員函數(shù)不存儲在對象中。在此基礎上,符合內(nèi)存對齊的原則。