a做爰網(wǎng)站網(wǎng)店運營基礎(chǔ)知識
類的引入
C語言中,結(jié)構(gòu)體中只能定義變量,在C++中,結(jié)構(gòu)體內(nèi)不僅可以定義變量,也可以定義函數(shù)。
而為了區(qū)分C和C++我們將結(jié)構(gòu)體重新命名成class去定義
類的定義
標(biāo)準(zhǔn)格式:
class className
{// 類體:由成員函數(shù)和成員變量組成}; // 一定要注意后面的分號
注意:結(jié)構(gòu)體不是函數(shù),不管是C的struct還是C++的class 最后大括號完了都得加上“;”
class為定義類的關(guān)鍵字,ClassName為類的名字,{}中為類的主體,注意類定義結(jié)束時后面分號。 類中的元素稱為類的成員:類中的數(shù)據(jù)稱為類的屬性或者成員變量; 類中的函數(shù)稱為類的方法或者成員函數(shù)。
類的兩種定義方式:
聲明和定義都在結(jié)構(gòu)體中:
同一個.cpp文件下#include <iostream>
using namespace std;
//. 聲明和定義全部放在類體中
class Date
{
public://結(jié)構(gòu)體中的函數(shù)void Init(int year,int month ,int day){_year = year;_month = month;_day = day;}void ShowDate(){cout << _year << "-" << _month << "-" << _day << endl;}
public://結(jié)構(gòu)體中的變量int _year;//年int _month;int _day;};
int main()
{Date dt;dt.Init(2024, 4, 1);dt.ShowDate();return 0;
}
聲明在.h,定義在.cpp(常用):
.h聲明 person#include <iostream>
using namespace std;
//. 聲明和定義全部放在類體中
class Date
{
public://結(jié)構(gòu)體中的函數(shù)void Init(int year, int month, int day);void ShowDate();
public://結(jié)構(gòu)體中的變量int _year;//年int _month;int _day;
};.C++ person#include "person.h"//結(jié)構(gòu)體中的函數(shù)
void Date::Init(int year, int month, int day)
{_year = year;_month = month;_day = day;
}
void Date::ShowDate()
{cout << _year << "-" << _month << "-" << _day << endl;
}.C++ main
#include "person.h"int main()
{Date dt;dt.Init(2024, 4, 1);dt.ShowDate();return 0;
}
為什么使用域作用限定符?
回答:當(dāng)在不同文件中聲明定義,可能會出現(xiàn)相同函數(shù),但是又因為結(jié)構(gòu)體和命名空間等的包裝,就需要專門::去打開。
成員變量前加“_”
成員變量(結(jié)構(gòu)體里的變量)和函數(shù)參數(shù)變量都為相同的時,無法區(qū)分,為了更明顯表現(xiàn)在代碼上各變量關(guān)系,常用“_”來表示成員變量
類的訪問限定符及封裝:
上圖一個會報錯一個不會報錯,其中最關(guān)鍵的在于public。由此我們能看出這個結(jié)構(gòu)體默認(rèn)是不讓你胡亂在結(jié)構(gòu)體外修改他的結(jié)構(gòu)體內(nèi)的變量的。
我們并不希望結(jié)構(gòu)體內(nèi)的有些東西會被修改,例如成員變量。
訪問限定符:
說明:
1. public修飾的成員在類外可以直接被訪問
2. protected和private修飾的成員在類外不能直接被訪問(此處protected和private是類似的)
3. 訪問權(quán)限作用域從該訪問限定符出現(xiàn)的位置開始直到下一個訪問限定符出現(xiàn)時為止
4. class的默認(rèn)訪問權(quán)限為private,struct為public(因為struct要兼容C)
封裝:
C++實現(xiàn)封裝的方式:用類將對象的屬性與方法結(jié)合在一塊,讓對象更加完善,通過訪問權(quán)限選擇性的將其 接口提供給外部的用戶使用。
面向?qū)ο蟮娜筇匦?#xff1a;封裝、繼承、多態(tài)
定義:封裝:將數(shù)據(jù)和操作數(shù)據(jù)的方法進(jìn)行有機結(jié)合,隱藏對象的屬性和實現(xiàn)細(xì)節(jié),僅對外公開接口來和對象進(jìn)行 交互。
本質(zhì):通過將我們想要保護(hù)的隱私東西用保險箱保護(hù)(封裝)起來。
通過不同的保護(hù)容器來實現(xiàn)不同的效果,例如,可以公開的信息就用透明箱子等;
類的作用域
類定義了一個新的作用域,類的所有成員都在類的作用域中。在類體外定義成員,需要使用 :: 作用域解析符 指明成員屬于哪個類域。
類的實例化
定義:用類類型創(chuàng)建對象的過程,稱為類的實例化(由圖紙->實物)
1.類只是一個模型一樣的東西,限定了類有哪些成員,定義出一個類并沒有分配實際的內(nèi)存空間來存儲它
2.. 一個類可以實例化出多個對象,實例化出的對象 占用實際的物理空間,存儲類成員變量
簡單理解:類只是給你設(shè)計了一個住宅區(qū)的建筑圖紙,你可以用這份圖紙在任何地方去建造住宅區(qū),這個過程(給類申請空間)就叫做實例化過程;
//類--設(shè)計圖紙
class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void ShowDate(){cout << _year << "-" << _month << "-" << _day << endl;}
public:int _year;int _month;int _day;
};int main()
{Date dt;//類的實例化--開實際空間dt.Init(2024, 4, 1);dt.ShowDate();return 0;
}
類的對象大小的計算
結(jié)論:一個類的大小,實際就是該類中”成員變量”之和,當(dāng)然也要進(jìn)行內(nèi)存對齊,注意空類的大小,空類比較特殊,編譯器給了空類一個字節(jié)來唯一標(biāo)識這個類。
類的存儲位置
注意:類里面函數(shù)運行的指令是存在代碼段里,但是運行過程中的參數(shù)是存在棧里
結(jié)構(gòu)體內(nèi)存對齊規(guī)則:
1. 第一個成員在與結(jié)構(gòu)體偏移量為0的地址處。
2. 其他成員變量要對齊到某個數(shù)字(對齊數(shù))的整數(shù)倍的地址處。
注意:對齊數(shù) = 編譯器默認(rèn)的一個對齊數(shù) 與 該成員大小的較小值。 VS中默認(rèn)的對齊數(shù)為8
3. 結(jié)構(gòu)體總大小為:最大對齊數(shù)(所有變量類型最大者與默認(rèn)對齊參數(shù)取最小)的整數(shù)倍。
4. 如果嵌套了結(jié)構(gòu)體的情況,嵌套的結(jié)構(gòu)體對齊到自己的最大對齊數(shù)的整數(shù)倍處,結(jié)構(gòu)體的整體大小就是 所有最大對齊數(shù)(含嵌套結(jié)構(gòu)體的對齊數(shù))的整數(shù)倍。
類成員函數(shù)this指針
由來:C++編譯器給每個“非靜態(tài)的成員函數(shù)“增加了一個隱藏的指針參數(shù),讓該指針指向當(dāng)前對象(函數(shù)運行時調(diào)用該函數(shù)的對象),在函數(shù)體中所有成員變量的操作,都是通過該指針去訪問。只不過所有的操作對用戶是透明的,即用戶不需要來傳遞,編譯器自動完成。
this指針的特性:
1.this指針的類型:類類型* const
2. 只能在“成員函數(shù)”的內(nèi)部使用
3.this指針是成員函數(shù)第一個隱含的指針形參,一般情況由編譯器通過ecx寄存器自動傳遞,不需要用戶傳遞
4.this指針本質(zhì)上其實是一個成員函數(shù)的形參,是對象調(diào)用成員函數(shù)時,將對象地址作為實參傳遞給this 形參。所以對象中不存儲this指針。
this存在哪里?
1.棧,因為他是隱含形參
2.VS下,是通過ecx寄存器
空指針問題:
//測試空指針問題
class Date
{
public:void Init(int year, int month, int day){cout << this << endl;this->_year = year;this->_month = month;this->_day = day;}void Show(){cout << this << endl;cout << "func()" << endl;}
public:int _year;int _month;int _day;
};int main()
{Date d1;d1.Init(1111, 11, 1);Date* ptr = nullptr;ptr->Show(); //正常運行(*ptr).Show(); //正常運行ptr->Init(3333, 33, 3);//運行崩潰return 0;
}
重點:解引用使用時主要看我們所申請的這個對象里包不包括我們要調(diào)用的函數(shù)或者變量。
解讀代碼:
結(jié)構(gòu)體的解引用不一定都是有效的,例如ptr->Init()這里進(jìn)去后要修改_year的數(shù)據(jù),此時ptr解引用后并無實際存儲數(shù)據(jù)空間,只是單純的申請了了一個地址空間。所以此時解引用后是無法進(jìn)行操作的。
show函數(shù)他只進(jìn)行顯示地址等并沒有數(shù)據(jù)的操作過程