国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > C++ > 正文

C++各種構(gòu)造函數(shù)的寫法

2019-11-10 22:08:05
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

構(gòu)造函數(shù) ,是一種特殊的方法 。主要用來(lái)在創(chuàng)建對(duì)象時(shí)初始化對(duì)象, 即為對(duì)象成員變量賦初始值,總與new運(yùn)算符一起使用在創(chuàng)建對(duì)象的語(yǔ)句中 。特別的一個(gè)類可以有多個(gè)構(gòu)造函數(shù) ,可根據(jù)其參數(shù)個(gè)數(shù)的不同或參數(shù)類型的不同來(lái)區(qū)分它們 即構(gòu)造函數(shù)的重載。(摘自百度百科 構(gòu)造函數(shù) )。

一、最基本的構(gòu)造函數(shù)

1 class Base2 {3 public:4     Base(int var) : m_Var(var)5     {6     }7 PRivate:8     int m_Var;9 };

以上構(gòu)造函數(shù)的執(zhí)行過(guò)程:

1)傳參   2)給類數(shù)據(jù)成員開辟空間     3)執(zhí)行冒號(hào)語(yǔ)法給數(shù)據(jù)成員初始化    4)執(zhí)行構(gòu)造函數(shù)括號(hào)里面的內(nèi)容

這里需要說(shuō)明的是:冒號(hào)語(yǔ)法后面的內(nèi)容相當(dāng)于int a = 10;(初始化),而構(gòu)造函數(shù)括號(hào)里面則是相當(dāng)于是int a; a = 10;(賦初值)

二、拷貝構(gòu)造函數(shù)

 1 class Base 2 { 3 public: 4     Base(int var) : m_Var(var) 5     { 6     } 7     //拷貝構(gòu)造函數(shù) 8     Base(Base &ref) : m_Var(ref.m_Var) 9     {10     }11 private:12     int m_Var;13 };

為什么拷貝構(gòu)造函數(shù)的參數(shù)只能用引用呢?

這就要從拷貝構(gòu)造函數(shù)式數(shù)碼時(shí)候觸發(fā)開始說(shuō)起了,以下幾種情況都會(huì)自動(dòng)調(diào)用拷貝構(gòu)造函數(shù):

1)用一個(gè)已有的對(duì)象初始化一個(gè)新對(duì)象的時(shí)候

2)將一個(gè)對(duì)象以值傳遞的方式傳給形參的時(shí)候

3)函數(shù)返回一個(gè)對(duì)象的時(shí)候

所以當(dāng)一個(gè)對(duì)象以傳遞值的方式傳一個(gè)函數(shù)的時(shí)候,拷貝構(gòu)造函數(shù)自動(dòng)的被調(diào)用來(lái)生成函數(shù)中的對(duì)象。如果一個(gè)對(duì)象是被傳入自己的拷貝構(gòu)造函數(shù),它的拷貝構(gòu)造函數(shù)將會(huì)被調(diào)用來(lái)拷貝這個(gè)對(duì)象這樣復(fù)制才可以傳入它自己的拷貝構(gòu)造函數(shù),這會(huì)導(dǎo)致無(wú)限循環(huán)直至棧溢出除了當(dāng)對(duì)象傳入函數(shù)的時(shí)候被隱式調(diào)用以外,拷貝構(gòu)造函數(shù)在對(duì)象被函數(shù)返回的時(shí)候也同樣的被調(diào)用。(摘自百度百科 拷貝構(gòu)造函數(shù) )。

拷貝構(gòu)造函數(shù),一般不需要自己編寫,系統(tǒng)默認(rèn)的拷貝構(gòu)造函數(shù)就能抗住了,但是有些情況需要在構(gòu)造的時(shí)候開辟空間,這時(shí)候就需要拷貝構(gòu)造函數(shù)了,如下代碼是摘自 林銳 博士的 高質(zhì)量C++編程指南 一文。

 1 class String 2 { 3 public: 4     String(const char *str = NULL); // 普通構(gòu)造函數(shù) 5     String(const String &other);    // 拷貝構(gòu)造函數(shù) 6     ~ String(void);                 // 析構(gòu)函數(shù) 7 private: 8     char *m_data; // 用于保存字符串 9 };10 // String 的析構(gòu)函數(shù)11 String::~String(void) 12 {13     delete [] m_data;14     // 由于m_data 是內(nèi)部數(shù)據(jù)類型,也可以寫成 delete m_data;15 }16 17 // String 的普通構(gòu)造函數(shù)18 String::String(const char *str) 19 {20     if(str==NULL)21     {22         m_data = new char[1]; // 若能加 NULL 判斷則更好23         *m_data = '/0';24     }25     else26     {27         int length = strlen(str);28         m_data = new char[length+1]; // 若能加 NULL 判斷則更好29         strcpy(m_data, str);30     }31 }32 // 拷貝構(gòu)造函數(shù)33 String::String(const String &other) 34 {35     int length = strlen(other.m_data);36     m_data = new char[length+1]; // 若能加 NULL 判斷則更好37     strcpy(m_data, other.m_data);38 }

 三、普通派生類構(gòu)造函數(shù)的寫法

定義派生類對(duì)象的時(shí)候,會(huì)按如下步驟執(zhí)行構(gòu)造操作:

1)傳參     2)根據(jù)繼承時(shí)的聲明順序構(gòu)造基類    3)給類數(shù)據(jù)成員開辟空間    4)執(zhí)行冒號(hào)語(yǔ)法后面的語(yǔ)句    5)執(zhí)行構(gòu)造函數(shù)函數(shù)體語(yǔ)句

 1 class Base 2 { 3 public: 4     Base(int b) : m_b(b) 5     { 6     } 7 private: 8     int m_b; 9 };10 11 class Derived : public Base12 {13 public:14     //普通派生類構(gòu)造函數(shù)的寫法15     Derived(int b, int d) : Base(b), m_d(d)16     {17     }18 private:19     int m_d;20 };

再寫一個(gè)多繼承的示例:

 1 class Base1 2 { 3 public: 4     Base1(int b1) : m_b1(b1) 5     { 6     } 7 private: 8     int m_b1; 9 };10 11 class Base212 {13 public:14     Base2(int b2) : m_b2(b2)15     {16     }17 private:18     int m_b2;19 };20 21 class Derived : public Base1, public Base222 {23 public:24     Derived(int b1, int b2, int d) : Base1(b1), Base2(b2), m_d(d)25     { //注意冒號(hào)語(yǔ)法后面的順序無(wú)所謂,創(chuàng)造基類是按照上面的繼承聲明順序來(lái)進(jìn)行的...26     }27 private:28     int m_d;29 };

四、含有虛繼承的派生類構(gòu)造函數(shù)的寫法

為何要用到虛繼承?

虛繼承主要是針對(duì)多繼承時(shí),出現(xiàn)二義性問(wèn)題而提出的。比如,如下代碼就需要用到虛繼承,否則的話Derived類繼承時(shí),Base類就會(huì)不明確。

虛繼承構(gòu)造函數(shù)的執(zhí)行按照如下步驟:

1)傳參 2)創(chuàng)建基類,注意這時(shí)候需要顯示創(chuàng)建所有“有參構(gòu)造函數(shù)”的基類,包括直接基類,間接基類。 3)給類數(shù)據(jù)成員開辟空間  4)執(zhí)行冒號(hào)語(yǔ)法  5)執(zhí)行構(gòu)造函數(shù)函數(shù)體

注:你可能會(huì)疑惑,如下代碼不是將Base間接基類創(chuàng)建了3次嗎?其實(shí)不是這樣的,編譯器是這樣處理的,當(dāng)最遠(yuǎn)的派生類Derived創(chuàng)建了基類Base之后,其直接基類創(chuàng)建Base類的語(yǔ)句將會(huì)被忽略掉。

 1 class Base 2 { 3 public: 4     Base(int b) : m_b(b) 5     { 6     } 7 private: 8     int m_b; 9 };10 11 class Base1 : virtual public Base12 {13 public:14     Base1(int b, int b1) : Base(b), m_b1(b1)15     {16     }17 private:18     int m_b1;19 };20 21 class Base2 : virtual public Base22 {23 public:24     Base2(int b, int b2) : Base(b), m_b2(b2)25     {26     }27 private:28     int m_b2;29 };30 //虛繼承,避免二義性31 class Derived : public Base1, public Base232 {33 public:34     Derived(int b, int b1, int b2, int d) : Base(b), Base1(b, b1), Base2(b, b2), m_d(d)35     { //注意冒號(hào)語(yǔ)法后面的順序無(wú)所謂,創(chuàng)造基類是按照上面的繼承聲明順序來(lái)進(jìn)行的...36     }37 private:38     int m_d;39 };

五、關(guān)于虛析構(gòu)

虛析構(gòu)一般伴隨著多態(tài)而產(chǎn)生,多態(tài)主要方式就是用基類的指針或引用指向或引用派生類,而形成多態(tài)。

但是這樣就會(huì)存在一個(gè)問(wèn)題,當(dāng)我們析構(gòu)的時(shí)候,由于是基類的指針,就會(huì)調(diào)用的是基類的構(gòu)造函數(shù),從而造成派生內(nèi)存溢出。為了解決這個(gè)問(wèn)題,引入了虛析構(gòu)的概念。將基類的構(gòu)造函數(shù)聲明為虛,從而使其在調(diào)用析構(gòu)函數(shù)的時(shí)候能夠準(zhǔn)確的調(diào)用派生類的析構(gòu)函數(shù)。

如下代碼必須用到虛析構(gòu)才能準(zhǔn)確的析構(gòu)派生類,并釋放其占有內(nèi)存。

 1 class Base 2 { 3 public: 4     Base(int b) : m_b(b) 5     { 6     } 7     //虛析構(gòu),使基類指針能準(zhǔn)確的釋放所指向的派生類里面的內(nèi)容 8     virtual ~Base() 9     {10     }11 private:12     int m_b;13 };14 15 class Derived : public Base16 {17 public:18     Derived(int b, char *pStr) : Base(b)19     { 20         m_pStr = new char[strlen(pStr)+1];21         strcpy(m_pStr,pStr);22     }23     ~Derived()24     {25         delete m_pStr;26         m_pStr = NULL;27     }28 private:29     char *m_pStr;30 };31 32 int main(void)33 {34     char *pStr = "abcdefg";35     Base *b = new Derived(1,pStr);36     delete b;37 38     return 0;39 }
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 崇州市| 桐乡市| 本溪市| 龙井市| 延长县| 佳木斯市| 呼玛县| 高淳县| 定襄县| 开平市| 婺源县| 凤凰县| 稷山县| 穆棱市| 信阳市| 资中县| 年辖:市辖区| 台南市| 鄂托克旗| 云南省| 凌云县| 闽侯县| 岳普湖县| 鹤山市| 柳州市| 晋城| 蕉岭县| 金昌市| 腾冲县| 巩留县| 克什克腾旗| 贵德县| 清涧县| 留坝县| 安阳市| 滕州市| 清水河县| 土默特右旗| 万宁市| 阳江市| 盐池县|