您好,登錄后才能下訂單哦!
深入理解struct
在C語言中,我們通常使用struct來表示不同數(shù)據(jù)類型的結(jié)合。當(dāng)然我們也可以在struct中定義函數(shù),在C++中,這是允許的但是不提倡使用,因為有一個比它更好使用的復(fù)雜數(shù)據(jù)類型,叫做類(這在稍后做出介紹)。
使用struct的時候有一個問題:在進行一個比較大的項目工程的時候,我們的數(shù)據(jù)結(jié)構(gòu)的定義和使用可能在不同的文件中,當(dāng)我們修改了數(shù)據(jù)結(jié)構(gòu)中的某個成員,那么,使用該數(shù)據(jù)結(jié)構(gòu)的函數(shù)必須修改,而我們并不知道拿下函數(shù)使用該種數(shù)據(jù)結(jié)構(gòu),這時候我們怎么做?答案很簡單,在函數(shù)定義的時候,讓該函數(shù)屬于該數(shù)據(jù)結(jié)構(gòu),在再次查找修改函數(shù)的時候,只要屬于該結(jié)構(gòu)的函數(shù)就進行修改就好了,代碼如下:
聲明數(shù)據(jù)結(jié)構(gòu): struct Time{ int hour; int minute; int second; void set_time(int h, int m, int s); void tick(); void show(); void run(); }; 定義函數(shù): void Time::set_time(int h, int m, int s){} void Time::tick(){} void Time::show(){} void Time::run(){}
補充:成員運算符:表示某個變量的成員,‘.’;表示某個類型的成員,“::”;
類的引出
這樣定義就萬事大吉了嗎?我們?nèi)绻谄渌瘮?shù)中試圖訪問該結(jié)構(gòu)中的成員變量(如:hour、minute、second)是成功的,這樣我們就有可能無意中修改了數(shù)據(jù)結(jié)構(gòu)中的某個成員變量的值,當(dāng)其他函數(shù)在使用成員變量的時候,就會使用該可能非法的數(shù)據(jù),這樣我們就會想到只要讓這些成員變量變成私有的就好了,這樣除了結(jié)構(gòu)中定義的函數(shù)外,其他方式都不可以訪問到該成員,這就出現(xiàn)了我們C++常使用的一種數(shù)據(jù)結(jié)構(gòu)——類。我們進行如下修改。
聲明數(shù)據(jù)結(jié)構(gòu): class Time{ int hour; int minute; int second; void set_time(int h, int m, int s); void tick(); void show(); void run(); }; 定義函數(shù): void Time::set_time(int h, int m, int s){} void Time::tick(){} void Time::show(){} void Time::run(){}
如果我們就止步于上面的數(shù)據(jù)結(jié)構(gòu),我們定義一個上述類的對象,當(dāng)我們通過對象調(diào)用函數(shù)的時候,會發(fā)現(xiàn)編譯不會通過,提示我們“你訪問的對象是私有的”。這里就要說明class和struct最大的區(qū)別:struct中的所有成員默認是公開的(public),即任意一個函數(shù)都可以進行訪問;class中的所有成員默認是私有的(private),即除了class中的成員函數(shù)之外,其他方式不可以訪問。
我們使用class而不是用struct的原因是因為,我們想讓成員變量變成私有的,實現(xiàn)基本數(shù)據(jù)封裝。但是對于成員函數(shù)的調(diào)用接口我們不必要私有,因為我們創(chuàng)建的對象,要通過成員函數(shù)完成項目任務(wù),所以我們應(yīng)讓成員函數(shù)的接口公開(public),這就是我們常說的封裝。接著進行如下更改,讓成員函數(shù)變量公有的(public)。
聲明數(shù)據(jù)結(jié)構(gòu): class Time{ private: int hour; int minute; int second; public: void set_time(int h, int m, int s); void tick(); void show(); void run(); }; 定義函數(shù): void Time::set_time(int h, int m, int s){} void Time::tick(){} void Time::show(){} void Time::run(){}
在這里我們要說說class中成員變量的訪問權(quán)限:
(1)private:私有的。這是class中成員變量默認的訪問權(quán)限,這種權(quán)限的成員變量,只有該類中成員函數(shù)可以訪問,子類中的成員函數(shù)不可以訪問,其他方式也不可以訪問。(子類是繼承中的概念,在講繼承的時候再談這個話題,先了解就好)。
(2)protected:保護的。該class中的成員函數(shù)可以訪問,子類中的成員函數(shù)也可以訪問,但是其他方式不可以訪問。
(3)public:公開的。該class中的成員函數(shù)可以訪問,子類中的成員函數(shù)也可以訪問,其他方式亦可以訪問。
構(gòu)造函數(shù)和析構(gòu)函數(shù)
對于class中的成員函數(shù),我們可以自己寫一個函數(shù)進行初始化,比如set函數(shù),將每個成員變量進行初始化賦值。但是每次創(chuàng)建一個新類都要調(diào)用該種函數(shù)進行成員的初始化,這大大加大了我們創(chuàng)建使用類的代價,為了讓我們每次創(chuàng)建一個對象的時候,都可以自動調(diào)用某個函數(shù)進行成員變量的初始化,我們可以使用類中重要的成員函數(shù)——構(gòu)造函數(shù)(構(gòu)造函數(shù)無返回值,并且函數(shù)名與類名一致),它可以在創(chuàng)建對象的時候自動調(diào)用,根據(jù)創(chuàng)建對象時傳入的初始化參數(shù)進行成員變量的初始化。
構(gòu)造函數(shù)的格式:Class_name(parameters){}
構(gòu)造函數(shù)的初始化有兩種方式:
(1)通過在構(gòu)造函數(shù)內(nèi)部進行賦值進行初始化,常量不能被賦值,只能使用初始化列表。
(2)通過初始化列表進行初始化,如果成員變量是數(shù)組或結(jié)構(gòu)不能使用初始化列表進行初始化。
構(gòu)造函數(shù)的重載:有時候我們需要定義多個構(gòu)造函數(shù),因為我們可能基于不同的需求對成員變量的初始化操作不同,這就是構(gòu)造函數(shù)的重載(函數(shù)重載:函數(shù)名相同,但是函數(shù)參數(shù)不同。系統(tǒng)可以根據(jù)傳入?yún)?shù)的不同來調(diào)用不同的函數(shù))。
析構(gòu)函數(shù):存在構(gòu)造函數(shù)也就會存在析構(gòu)函數(shù),析構(gòu)函數(shù)就是在該對象即將被釋放的時候做收尾動作,析構(gòu)函數(shù)一定沒有參數(shù)列表,所以析構(gòu)函數(shù)不可以重載。
析構(gòu)函數(shù)規(guī)則:~Class_name(){};
class A{ int n; double d; public : A():n(0),d(0.0){ // constructor_init1 } A(int n){ // constructor_init2 this->n = n; d = 0.0; } void show(){ cout << "n = " << n << ", d = " << d << endl; } ~A(){ cout << “~A()” << endl; } }; int main(int ac, char *av[]) { A a1; // use constructor_init1 a1.show(); A a2(100); // use constructor_init2 (*this).show(); return 0; }
this指針:this指針是系統(tǒng)自動定義的,用來保存結(jié)構(gòu)變量的地址。當(dāng)我們創(chuàng)建一個對象的時候,系統(tǒng)就會自動將該對象對應(yīng)的類的成員保存在this中,我們可以通過this->mem_val或this->mem_func,來訪問該成員。在一個成員函數(shù)中,可以不用寫this,表示默認使用該成員函數(shù)所在類的成員變量。
構(gòu)造函數(shù)總結(jié):
(1)構(gòu)造函數(shù)不同寫返回值,其函數(shù)名與類名一致。
(2)構(gòu)造函數(shù)在每個對象創(chuàng)建的時候都不被自動調(diào)用一次。
構(gòu)造函數(shù)的調(diào)用順序
·全局對象的構(gòu)造函數(shù)在main之前調(diào)用。
·靜態(tài)局部對象的構(gòu)造函數(shù)在整個程序的執(zhí)行過程中只調(diào)用一次。
class A{ int n; public: A(int n) : n(n){ cout << "A(" << n << ')' << endl; } ~A(){ cout << "~A(" << n << ')' << endl; } }; void func(){ A a2(2); static A a3(3); } int main(int ac, char *av[]) { A a4(4); cout << "first call func : \n"; func(); cout << "second call func : \n"; func(); return 0; } A a1(1); //========================== // 1:全局對象 // 2:函數(shù)func中的自動對象 // 3:函數(shù)func中的靜態(tài)全局對象 //4:函數(shù)main中的自動對象 //=============================== 結(jié)果顯示: [root@anna-laptop construtor]# ./call_queue A(1) A(4) first call func : A(2) A(3) ~A(2) second call func : A(2) ~A(2) ~A(4) ~A(3) ~A(1)
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。