C++?構(gòu)造函數(shù)和析構(gòu)函數(shù)(Constructors?&?Destructors)詳解
一、定義:
當(dāng)object產(chǎn)生,有一個(gè)特殊的稱為constructor的函數(shù)會(huì)自動(dòng)執(zhí)行。當(dāng)object死亡,有一個(gè)特殊的稱為destructor的函數(shù)會(huì)自動(dòng)執(zhí)行。Constructor 可以不只一個(gè),但 destructor 只能有一個(gè)。
Constructor(構(gòu)造函數(shù))就是與class同名的那些member functions,例如CPoint::CPoint()或CDemo::CDemo()。Constructors不能夠指定返回值類型,也就是它不必(但可以)return。constructions可以有一個(gè)或多個(gè),各有不同類型的參數(shù)。
Destructor(析構(gòu)函數(shù))就是與class同名,且前面有加“~”符號的那個(gè)member function,例如例如 CPoint::~CPoint() 或 CDemo::~CDemo()。Destructor 不能指定返回值類型,也就是它不必(但可以)return。每個(gè)class只有一個(gè)destructor,并且不能有任何參數(shù)。
由于global object的誕生比程序進(jìn)入更早點(diǎn),所以global object的constructor執(zhí)行的時(shí)間更早于程序的進(jìn)入點(diǎn)。
二、Default Constructors
所謂的default constructor就是沒有指定任何的參數(shù)的constructor。如果我們的class CA聲明如下:
#include <iostream> using namespace std; class CA { public: int getdata(){return _data;}; CA(){_data =5;}; CA(int val){_data =val;}; protected: int _data; };
CA有兩個(gè)constructors,分別是CA(int) 和 CA()。后都沒有參數(shù),正是所謂的default constructor。當(dāng)我產(chǎn)生一個(gè) CA object 而沒有指定任何參數(shù):
CA aCA; CA* pCA = new CA;
編譯器就為我們呼叫default constructor。
普遍存在于C++程序員之間的一個(gè)誤解是:如果我們沒有為某個(gè)class設(shè)計(jì)constructor,編譯器會(huì)自動(dòng)為該class制造出一個(gè)default constructor來。這個(gè)說法也對也不對,這里我先提示一個(gè)結(jié)論,銷稍后有更多細(xì)節(jié)探討。什么是編譯器所需要的動(dòng)作?就是隱藏在C++程序代碼下面,讓C++諸多特征得到實(shí)現(xiàn)的動(dòng)作,包含以下三種情況:
1. class CA 內(nèi) 含 class CZ objects,如圖1:當(dāng)產(chǎn)生一個(gè)CA object 時(shí),隱藏在底層的必要?jiǎng)幼魇窍瘸跏蓟疌Z object(因?yàn)镃A object中有一個(gè)CZ object)
2.class CA繼承于class CZ,如圖2:當(dāng)產(chǎn)生一個(gè)CA object 時(shí),隱藏在底層的必要?jiǎng)幼魇窍日{(diào)用CZ的default constructor (因?yàn)镃A object中有一個(gè)CZ subobject)
3.CA是一個(gè) polymorphic class,也就是說它有virtual functions,或繼承于有virtual functions的class。當(dāng)產(chǎn)生一個(gè)CA object,隱藏在底層的必要?jiǎng)幼魇牵簩⑻摂M機(jī)制所需要的vptr和vtb1初始化。
由于這三種情況皆有所謂的“底層的必要?jiǎng)幼?rdquo;,所以編譯器必須自動(dòng)為class CA生成一個(gè)default constructor((如果沒有任何 user-defined constructor 的話),或暗中對已有的user-defined constructor 動(dòng)作腳(添加一些代碼)。生成出來的東西稱為“implicit nontrivial default constructor”。
如果沒有上述需求,編譯器就不會(huì)為class產(chǎn)生一個(gè)default constructor,例如:
class CB { public: int getdata() { return _data; }; protected: int _data; };
virtual functions的base classes),也沒有內(nèi)含embedded objects,也沒有繼承于其它c(diǎn)lass,所以編譯器不會(huì)為它生成一個(gè)default constructor出來,于是當(dāng)我們這么做:
CB aCB; // 應(yīng)該調(diào)用default constructor cout << "aCB.getdata()=" << aCB.getdata() << endl;
但得到的結(jié)果如下:
aCB.getdata()=4211382 // 莫名其妙的初值
這個(gè)恐怕不是我所期望的,我們期望的_data有個(gè)初始值,但這個(gè)不是編譯器的需求,所以我們只能自求多福,自已設(shè)計(jì)一個(gè)default constructor:
class CB { public: int getdata() { return _data; }; CB() { _data = 5; }; // default constructor protected: int _data; };
現(xiàn)在輸出的結(jié)果就是我們所期望的了:
CB aCB; // 應(yīng)該調(diào)用 default constructor cout << "aCB.getdata()=" << aCB.getdata() << endl; // 輸出結(jié)果:aCB.getdata()=5
注意,如果class已經(jīng)有了任何constructor,但不是default constructor,編譯器絕不會(huì)為它生成一個(gè)default constructor。如果class CZ正是如此一個(gè)class,那么當(dāng)你想產(chǎn)生一個(gè)CZ object,并且沒有指定參數(shù)時(shí):
CZ *aCZ; // error
編譯器會(huì)輸出異常提示:
error C2512: 'CZ' : no appropriate default constructor available
三、Copy Constructors
所謂的Copy Constructors是指有一個(gè)參數(shù)的類型是其 class type的 constructor,例如:
class CA { public: int getdata() {return _data; }; //default constructor CA(){_data =5;}; CA(int val){_data=val; }; //constructor CA(const CA& ca){ //copy constructor cout<<"copy constructor"<<endl; _data=10; }; protected: int _data; };
以下兩種情況,會(huì)喚起copy constructor:
情況1:將一個(gè)object當(dāng)做參數(shù)傳給某一個(gè)函數(shù);
情況2:將一個(gè)object當(dāng)做函數(shù)的返回值;
例如(沿用上面的class CA):
#include <iostream> using namespace std; class CA { public: int getdata() {return _data; }; //default constructor CA(){_data =5;}; CA(int val){_data=val; }; //constructor CA(const CA& ca){ //copy constructor cout<<"copy constructor"<<endl; _data=10; }; protected: int _data; }; void foo2(CA aCA)//情況1(函數(shù)參數(shù)是個(gè)object) { cout<<"in foo2(),aCA.getdata()="<<aCA.getdata()<<endl; } CA foo3()//情況2(函數(shù)的返回值是個(gè)object) { CA aCA(3); cout<<"in foo3(),aCA.getdata()="<<aCA.getdata()<<endl; return aCA; } int main() { CA aCA1,aCA2(7); cout << "aCA1.getdata()="<<aCA1.getdata()<< endl; cout << "aCA2.getdata()="<<aCA2.getdata()<< endl; aCA2 =aCA1;//object assignment cout << "aCA2.getdata()="<<aCA2.getdata()<< endl; foo2(aCA1);//情況1(調(diào)用之前aCA1._data 為5) aCA2=foo3(); cout << "aCA2.getdata()="<<aCA2.getdata()<< endl; return 0; }
讓我們看看執(zhí)行結(jié)果:
aCA1.getdata()=5
aCA2.getdata()=7
aCA2.getdata()=5 // 經(jīng)過 object assignment 之后
copy constructor
in foo2(), aCA.getdata()=10 // 經(jīng)過情況 1 之后
in foo3(), aCA.getdata()=3
copy constructor
aCA2.getdata()=10 // 經(jīng)過情況 2 之后
這里有幾點(diǎn)需要注意的:
1. 38行的將一個(gè)object指派(assign)給另一個(gè)object,這也是一種復(fù)制,但它喚起的所謂的copy assignment operator。本例并沒有特別設(shè)計(jì)copy assignment operator;
2.調(diào)用foo2()之前,_data為5,進(jìn)入foo2()之后再輸出,已變成10,可見copy constructor的確在foo2()的參數(shù)復(fù)制時(shí)發(fā)生;
3.foo3()內(nèi)有一個(gè)local object,其_data為3,把穹當(dāng)做返回值輸出,卻變成了10,可見copy constructor的確在foo3()的返回值復(fù)制時(shí)發(fā)生;
到此這篇關(guān)于C++ 構(gòu)造函數(shù)和析構(gòu)函數(shù)(Constructors & Destructors)詳解的文章就介紹到這了,更多相關(guān)C++ 構(gòu)造函數(shù)和析構(gòu)函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言實(shí)現(xiàn)為無聲avi視頻添加wave音樂
這篇文章主要為大家詳細(xì)介紹了C語言如何實(shí)現(xiàn)為無聲avi視頻添加wave音樂,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴可以了解一下2023-11-11C語言詳盡圖解函數(shù)棧幀的創(chuàng)建和銷毀實(shí)現(xiàn)
我們知道c語言中函數(shù)都是被調(diào)用的,main函數(shù)里面能調(diào)用其他函數(shù),其實(shí)main函數(shù)也是被別的函數(shù)調(diào)用的,下面通過本文給大家分享c語言函數(shù)棧幀的創(chuàng)建和銷毀過程,一起看看吧2022-05-05探討C++中不能聲明為虛函數(shù)的有哪些函數(shù)
下面小編就為大家?guī)硪黄接慍++中不能聲明為虛函數(shù)的有哪些函數(shù)。希望對大家有所幫助。一起跟隨小編過來看看吧,祝大家游戲愉快哦2017-01-01C++編程中break語句和continue語句的學(xué)習(xí)教程
這篇文章主要介紹了C++編程中break語句和continue語句的學(xué)習(xí)教程,break和continue是C++循環(huán)控制中的基礎(chǔ)語句,需要的朋友可以參考下2016-01-01C語言數(shù)組實(shí)現(xiàn)公交車管理系統(tǒng)
這篇文章主要介紹了C語言數(shù)組實(shí)現(xiàn)公交車管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12C++ Vector 動(dòng)態(tài)數(shù)組的實(shí)現(xiàn)
這篇文章主要介紹了C++ Vector 動(dòng)態(tài)數(shù)組的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01C++中vector容器的注意事項(xiàng)總結(jié)
在c++中,vector是一個(gè)十分有用的容器,下面這篇文章主要給大家介紹了關(guān)于C++中vector容器的注意事項(xiàng),文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-12-12