C++中默認(rèn)無參構(gòu)造函數(shù)的工作機制淺析
在不實現(xiàn)構(gòu)造函數(shù)的情況下,編譯器會自動生成一個默認(rèn)無參構(gòu)造函數(shù)。但是看起來編譯器自動生成的無參默認(rèn)構(gòu)造函數(shù)似乎沒有什么用,比如創(chuàng)建p對象時調(diào)用了編譯器生成的無參默認(rèn)構(gòu)造函數(shù),但是p對象的成員變量依舊是隨機值。
class Person { private: int age; public: int getAge() { return age; } }; int main() { Person p; cout << p.getAge() << endl; return 0; }
默認(rèn)無參構(gòu)造函數(shù)真的沒有用嗎?
我們可以通過下面的代碼來探究默認(rèn)無參構(gòu)造函數(shù)的作用。
#include<iostream> #include<string> using namespace std; class Person { int age; public: Person() { cout << "自定義類型成員的默認(rèn)無參構(gòu)造函數(shù)被調(diào)用" << endl; } //Person(int _age = 0) :age(_age) { cout << "自定義類型成員的全缺省默認(rèn)構(gòu)造函數(shù)被調(diào)用" << endl; } int getAge() { return age; } }; class Student { Person p; int id; public: Student(){} int getId() { return id; } int getAge() { return p.getAge(); } }; int main() { Student s; cout << "id:" << s.getId() << endl; cout << "age:" << s.getAge() << endl; return 0; }
上面代碼利用默認(rèn)無參構(gòu)造函數(shù)創(chuàng)建對象s,根據(jù)第一句輸出,我們可以得知默認(rèn)無參構(gòu)造函數(shù)會先對自定義類型的數(shù)據(jù)成員會調(diào)用自定義數(shù)據(jù)類型的默認(rèn)構(gòu)造函數(shù)來處理自定義類型數(shù)據(jù)成員。根據(jù)第二句輸出,我們可以知道默認(rèn)無參構(gòu)造函數(shù)對基本類型數(shù)據(jù)成員沒有作處理,只是在初始化列表中用隨機值對其進(jìn)行了初始化,第三句輸出,是默認(rèn)無參構(gòu)造函數(shù)調(diào)用了自定義類型的默認(rèn)構(gòu)造函數(shù)對自定義數(shù)據(jù)成員處理的結(jié)果,由于自定義類型的默認(rèn)構(gòu)造函數(shù)也是默認(rèn)無參構(gòu)造函數(shù),所以它不會對基本數(shù)據(jù)類型成員age作處理,只是在初始化列表中用隨機值對其進(jìn)行初始化。
我們把第八行代碼屏蔽,放出第九行全缺省默認(rèn)構(gòu)造函數(shù)試試看,輸出如下:
上面代碼利用默認(rèn)無參構(gòu)造函數(shù)創(chuàng)建對象s,根據(jù)第一句輸出,我們可以得知默認(rèn)無參構(gòu)造函數(shù)會先對自定義類型的數(shù)據(jù)成員會調(diào)用自定義數(shù)據(jù)類型的默認(rèn)構(gòu)造函數(shù)來處理自定義類型數(shù)據(jù)成員,與之前不同的是,之前自定義數(shù)據(jù)類型的默認(rèn)構(gòu)造函數(shù)是默認(rèn)無參構(gòu)造函數(shù),這里自定義類型的默認(rèn)構(gòu)造函數(shù),是自己定義的全缺省的默認(rèn)構(gòu)造函數(shù)。根據(jù)第二句輸出,我們可以知道默認(rèn)無參構(gòu)造函數(shù)對基本類型數(shù)據(jù)成員沒有作處理,只是在初始化列表中用隨機值對其進(jìn)行了初始化,第三句輸出,是默認(rèn)無參構(gòu)造函數(shù)調(diào)用了自定義類型的全缺省默認(rèn)構(gòu)造函數(shù)對自定義數(shù)據(jù)成員處理的結(jié)果。
由此我們可以得出結(jié)論:
C++把類型分成基本類型和自定義類型。
默認(rèn)無參默認(rèn)構(gòu)造函數(shù)對基本類型成員變量不做處理(在初始化列表中用隨機值對其進(jìn)行初始化),C++11 中針對基本類型成員不初始化的缺陷,又打了補丁,即:基本類型成員變量在類中聲明時可以給默認(rèn)值。
默認(rèn)無參構(gòu)造函數(shù)對于自定義類型成員變量才會處理,它會去調(diào)用自定義類型的默認(rèn)構(gòu)造函數(shù)去初始化創(chuàng)建自定義類型的成員變量(對象)。
何時使用編譯器自動生成的無參默認(rèn)構(gòu)造函數(shù)就夠了,何時需要自己實現(xiàn)構(gòu)造函數(shù)呢?
如果一個類中的成員全是自定義類型,或者基本類型成員在聲明時已經(jīng)給了缺省值,即無需對基本類型成員變量做處理,且自定義成員都提供了默認(rèn)構(gòu)造函數(shù),此時使用編譯器自動生成的無參默認(rèn)構(gòu)造函數(shù)就可以了。
如果有基本類型的成員變量且需要顯示傳參初始化,即我們需要自己對基本類型成員變量進(jìn)行處理,或者自定義類型成員沒有默認(rèn)構(gòu)造函數(shù),那么就要自己實現(xiàn)構(gòu)造函數(shù)。
到此這篇關(guān)于C++中默認(rèn)無參構(gòu)造函數(shù)的工作機制淺析的文章就介紹到這了,更多相關(guān)C++默認(rèn)無參構(gòu)造函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言對組文件處理的相關(guān)函數(shù)小結(jié)
這篇文章主要介紹了C語言對組文件處理的相關(guān)函數(shù)小結(jié),包括setgrent()函數(shù)和getgrent()函數(shù)以及endgrent()函數(shù),需要的朋友可以參考下2015-08-08C語言 深入解讀數(shù)據(jù)結(jié)構(gòu)之堆的實現(xiàn)
堆就是用數(shù)組實現(xiàn)的二叉樹,所以它沒有使用父指針或者子指針。堆根據(jù)“堆屬性”來排序,“堆屬性”決定了樹中節(jié)點的位置2021-11-11c++調(diào)用實現(xiàn)yolov5轉(zhuǎn)onnx介紹
大家好,本篇文章主要講的是c++調(diào)用實現(xiàn)yolov5轉(zhuǎn)onnx介紹,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12詳解C++虛函數(shù)中多態(tài)性的實現(xiàn)原理
C++是一種面向?qū)ο蟮木幊陶Z言,在C++中,虛函數(shù)是實現(xiàn)多態(tài)性的關(guān)鍵。本文就來探討一下C++虛函數(shù)中多態(tài)性的實現(xiàn)原理及其在面向?qū)ο缶幊讨械膽?yīng)用吧2023-05-05MFC中動態(tài)創(chuàng)建控件以及事件響應(yīng)實現(xiàn)方法
這篇文章主要介紹了MFC中動態(tài)創(chuàng)建控件以及事件響應(yīng)實現(xiàn)方法,詳細(xì)講解了MFC中動態(tài)創(chuàng)建控件以及事件響應(yīng)的概念與實現(xiàn)方法,具有一定的實用價值,需要的朋友可以參考下2014-10-10