企業(yè)網(wǎng)站模板演示seo外包如何
一、構(gòu)造函數(shù)
1.什么是構(gòu)造函數(shù)
構(gòu)造函數(shù)是特殊的成員函數(shù),需要注意的是,構(gòu)造函數(shù)雖然名稱(chēng)叫構(gòu)造,但是構(gòu)造函數(shù)的主要任 務(wù)并不是開(kāi)空間創(chuàng)建對(duì)象,而是初始化對(duì)象。
2.特征
- 函數(shù)名與類(lèi)名相同。
- 無(wú)返回值。(void 也不行)
- 對(duì)象實(shí)例化時(shí)編譯器自動(dòng)調(diào)用對(duì)應(yīng)的構(gòu)造函數(shù)。
- 構(gòu)造函數(shù)可以重載。
class Date
{
public://構(gòu)造函數(shù)Date(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;
};int main()
{Date d1(2023, 8, 12);d1.Print();}
除了上面,也可以用多種構(gòu)造函數(shù),來(lái)完成初始化
class Date
{
public://構(gòu)造函數(shù)Date(int year ,int month , int day ){_year = year;_month = month;_day = day;}//無(wú)參構(gòu)造函數(shù)Date(){_year = 2023;_month = 4;_day = 17;}void Print(){cout << _year << "/" << _month << "/" << _day << endl;}private:int _year;int _month;int _day;
};int main()
{Date d1(2023, 8, 12);d1.Print();Date d2;d2.Print();
}
但是當(dāng)這樣寫(xiě)的時(shí)候,就會(huì)出現(xiàn)問(wèn)題
class Date
{
public://全缺省構(gòu)造函數(shù)Date(int year = 1 ,int month = 1, int day = 1 ){_year = year;_month = month;_day = day;}//無(wú)參構(gòu)造函數(shù)Date(){_year = 2023;_month = 4;_day = 17;}void Print(){cout << _year << "/" << _month << "/" << _day << endl;}private:int _year;int _month;int _day;
};int main()
{Date d1(2023, 8, 12);d1.Print();Date d2;d2.Print();}
錯(cuò)誤原因:對(duì)于不帶參數(shù)的對(duì)象,既可以調(diào)用全缺省構(gòu)造,也可以調(diào)用無(wú)參構(gòu)造,但是編譯器會(huì)不知道調(diào)用哪一個(gè)。
3.默認(rèn)構(gòu)造函數(shù)
如果類(lèi)中沒(méi)有顯式定義構(gòu)造函數(shù),則C++編譯器會(huì)自動(dòng)生成一個(gè)無(wú)參的默認(rèn)構(gòu)造函數(shù),一旦用戶(hù)顯式定義編譯器將不再生成。
1、無(wú)參構(gòu)造(沒(méi)有形參的構(gòu)造函數(shù))稱(chēng)之為默認(rèn)構(gòu)造函數(shù)
2、全缺省構(gòu)造(形參都有缺省值)也稱(chēng)之為默認(rèn)構(gòu)造函數(shù)
3、編譯器自動(dòng)生成的默認(rèn)構(gòu)造函數(shù)
對(duì)于編譯器自己生成的,該類(lèi)中的成員變量會(huì)被初始化為隨機(jī)值
class Date
{
public:全缺省構(gòu)造函數(shù)//Date(int year = 1 ,int month = 1, int day = 1 )//{// _year = year;// _month = month;// _day = day;//}無(wú)參構(gòu)造函數(shù)//Date()//{// _year = 2023;// _month = 4;// _day = 17;//}void Print(){cout << _year << "/" << _month << "/" << _day << endl;}private:int _year;int _month;int _day;
};int main()
{/*Date d1(2023, 8, 12);d1.Print();*/Date d2;d2.Print();return 0;
}
關(guān)于編譯器生成的默認(rèn)成員函數(shù),很多人會(huì)有疑惑:不實(shí)現(xiàn)構(gòu)造函數(shù)的情況下,編譯器會(huì)
生成默認(rèn)的構(gòu)造函數(shù)。但是看起來(lái)默認(rèn)構(gòu)造函數(shù)又沒(méi)什么用?
對(duì)象調(diào)用了編譯器生成的默認(rèn)構(gòu)造函數(shù),但是對(duì)象_year/_month/_day,依舊是隨機(jī)值。也就說(shuō)在這里編譯器生成的默認(rèn)構(gòu)造函數(shù)并沒(méi)有什么用??
解答:C++把類(lèi)型分成內(nèi)置類(lèi)型(基本類(lèi)型)和自定義類(lèi)型。內(nèi)置類(lèi)型就是語(yǔ)言提供的數(shù)據(jù)類(lèi)
型,如:int/char…,自定義類(lèi)型就是我們使用class/struct/union等自己定義的類(lèi)型,看看
下面的程序,就會(huì)發(fā)現(xiàn)編譯器生成默認(rèn)的構(gòu)造函數(shù)會(huì)對(duì)自定類(lèi)型成員_t調(diào)用的它的默認(rèn)成員
函數(shù)。
class Time
{
public:Time(){cout << "Time()" << endl;_hour = 0;_minute = 0;_second = 0;}
private:int _hour;int _minute;int _second;
};class Date
{
public:全缺省構(gòu)造函數(shù)//Date(int year = 1 ,int month = 1, int day = 1 )//{// _year = year;// _month = month;// _day = day;//}無(wú)參構(gòu)造函數(shù)//Date()//{// _year = 2023;// _month = 4;// _day = 17;//}void Print(){cout << _year << "/" << _month << "/" << _day << endl;}private://內(nèi)置類(lèi)型int _year;int _month;int _day;//自定義類(lèi)型Time _t;
};int main()
{/*Date d1(2023, 8, 12);d1.Print();*/Date d2;d2.Print();return 0;
}
說(shuō)明:_year,_month,_day都是隨機(jī)值,而Time _t這個(gè)變量是class Time自定義類(lèi)型,編譯器會(huì)走到Time類(lèi)中,調(diào)用該類(lèi)的構(gòu)造函數(shù)。
typedef int STDateType;
class Stack
{
public:Stack(size_t capacity = 4){cout << "Stack()" << endl;_array = (STDateType*)malloc(sizeof(STDateType) * capacity);if (_array == nullptr){perror("malloc fail");return;}_capacity = capacity;_size = 0;}void Push(STDateType x){//CheckCapacity()_array[_size++] = x;}//析構(gòu)函數(shù)~Stack(){cout << "~Stack()" << endl;free(_array);_array = nullptr;_capacity = _size = 0;}
private:STDateType* _array;int _capacity;int _size;
};class MyQueue
{Stack _pushST;Stack _popST;};int main()
{MyQueue q;return 0;
}
對(duì)于MyQueue來(lái)說(shuō),成員變量都為自定義類(lèi)型,編譯時(shí)會(huì)去調(diào)用Stack中的構(gòu)造函數(shù)
二、析構(gòu)函數(shù)
1.定義
析構(gòu)函數(shù)與構(gòu)造函數(shù)功能相反,析構(gòu)函數(shù)不是完成對(duì)對(duì)象本身的銷(xiāo)毀,局部對(duì)象銷(xiāo)毀工作是由編譯器完成的。而對(duì)象在銷(xiāo)毀時(shí)會(huì)自動(dòng)調(diào)用析構(gòu)函數(shù),完成對(duì)象中資源的清理工作。
2.特性
- 析構(gòu)函數(shù)名是在類(lèi)名前加上字符 ~。
- 無(wú)參數(shù)無(wú)返回值類(lèi)型。
- 一個(gè)類(lèi)只能有一個(gè)析構(gòu)函數(shù)。若未顯式定義,系統(tǒng)會(huì)自動(dòng)生成默認(rèn)的析構(gòu)函數(shù)。注意:析構(gòu) 函數(shù)不能重載。
- 對(duì)象生命周期結(jié)束時(shí),C++編譯系統(tǒng)系統(tǒng)自動(dòng)調(diào)用析構(gòu)函數(shù)。
typedef int STDateType;
class Stack
{
public:Stack(size_t capacity = 4){cout << "Stack()" << endl;_array = (STDateType*)malloc(sizeof(STDateType) * capacity);if (_array == nullptr){perror("malloc fail");return;}_capacity = capacity;_size = 0;}void Push(STDateType x){//CheckCapacity()_array[_size++] = x;}//析構(gòu)函數(shù)~Stack(){cout << "~Stack()" << endl;free(_array);_array = nullptr;_capacity = _size = 0;}
private:STDateType* _array;int _capacity;int _size;
};class MyQueue
{Stack _pushST;Stack _popST;};int main()
{Stack s;s.Push(1);return 0;
}
析構(gòu)函數(shù)的調(diào)用是在執(zhí)行return 0后,函數(shù)即將銷(xiāo)毀時(shí)自動(dòng)調(diào)用它,然后堆區(qū)空間就會(huì)被釋放,且其他變量清零。
4.默認(rèn)析構(gòu)類(lèi)型
默認(rèn)析構(gòu)函數(shù)與默認(rèn)構(gòu)造函數(shù)同理,都是我們不生成時(shí),編譯器自動(dòng)生成一個(gè)析構(gòu)函數(shù),但編譯器生成的也只能處理一些簡(jiǎn)單類(lèi)型的成員變量,例如日期類(lèi):
class Date
{
public://全缺省構(gòu)造函數(shù)Date(int year = 1 ,int month = 1, int day = 1 ){_year = year;_month = month;_day = day;}無(wú)參構(gòu)造函數(shù)//Date()//{// _year = 2023;// _month = 4;// _day = 17;//}void Print(){cout << _year << "/" << _month << "/" << _day << endl;}private://內(nèi)置類(lèi)型int _year;int _month;int _day;//自定義類(lèi)型Time _t;
};int main()
{Date d1(2023, 8, 13);return 0;
}
對(duì)于復(fù)雜類(lèi)型的成員變量,編譯器自動(dòng)生成的析構(gòu)函數(shù)并不能完成最后的清理工作,比如:對(duì)于堆區(qū)空間的生成…所以還需要自己去寫(xiě)析構(gòu)函數(shù)