詳解C++編程中的析構函數。本站提示廣大學習愛好者:(詳解C++編程中的析構函數)文章只能為提供參考,不一定能成為您想要的結果。以下是詳解C++編程中的析構函數正文
C++析構函數
創立對象時體系會主動挪用結構函數停止初始化任務,異樣,燒毀對象時體系也會主動挪用一個函數來停止清算任務(例如收受接管創立對象時消費的各類資本),這個函數被稱為析構函數。
析構函數(Destructor)也是一種特別的成員函數,沒有前往值,不須要用戶挪用,而是在燒毀對象時主動履行。與結構函數分歧的是,析構函數的名字是在類名後面加一個”~“符號。
留意:析構函數沒有參數,不克不及被重載,是以一個類只能有一個析構函數。假如用戶沒有界說,那末編譯器會主動生成。
析構函數舉例:
#include <iostream> using namespace std; class Student{ private: char *name; int age; float score; public: //結構函數 Student(char *, int, float); //析構函數 ~Student(); //通俗成員函數 void say(); }; Student::Student(char *name1, int age1, float score1):name(name1), age(age1), score(score1){} Student::~Student(){ cout<<name<<"再會"<<endl; } void Student::say(){ cout<<name<<"的年紀是 "<<age<<",成就是 "<<score<<endl; } int main(){ Student stu1("小明", 15, 90.5f); stu1.say(); Student stu2("李磊", 16, 95); stu2.say(); Student stu3("王爽", 16, 80.5f); stu3.say(); cout<<"main 函數行將運轉停止"<<endl; return 0; }
運轉成果:
小明的年紀是 15,成就是 90.5 李磊的年紀是 16,成就是 95 王爽的年紀是 16,成就是 80.5 main 函數行將運轉停止 王爽再會 李磊再會 小明再會
可以看出,析構函數在 main 函數運轉停止前被履行,而且挪用次序和結構函數正好相反,為了便利記憶,我們可以將之懂得為一個棧,先入後出。
析構函數的履行次序為何是反的。
析構函數在對象被燒毀前履行;要曉得析構函數甚麼時刻被挪用,就要先曉得對象甚麼時刻被燒毀。
對象可以以為是經由過程類這類數據類型界說的變量,它的許多特征和通俗變量是一樣的,例如感化域、性命周期等。由此可以揣摸,對象這類變量的燒毀機會和通俗變量是一樣的。
總結起來,有上面幾種情形:
1) 假如在一個函數中界說了一個對象(auto 部分變量),當這個函數運轉停止時,對象就會被燒毀,在對象被燒毀前主動履行析構函數。
2) static 部分對象在函數挪用停止時其實不燒毀,是以也不挪用析構函數,只要在法式停止時(如 main 函數停止或挪用 exit 函數)才挪用 static 部分對象的析構函數。
3) 假如界說了一個全局對象,也只要在法式停止時才會挪用該全局對象的析構函數。
4) 假如用 new 運算符靜態地樹立了一個對象,當用 delete 運算符釋放該對象時,先挪用該對象的析構函數。
留意:析構函數的感化其實不是刪除對象,而是在撤消對象占用的內存之前完成一些清算任務,使這部門內存可以分派給新對象應用。
C++挪用結構函數和析構函數的次序
在應用結構函數和析構函數時,須要特殊留意對它們的挪用時光和挪用次序。在普通情形下,挪用析構函數的順序正好與挪用結構函數的順序相反:最早被挪用的結構函數,其對應的(統一對象中的)析構函數最初被挪用,而最初被挪用的結構函數,其對應的析構函數最早被挪用。如例9.5所示,先履行stud2的析構函數,再履行stu1的析構函數。
可以簡記為:先結構的後析構,後結構的先析構,它相當於一個棧,先輩後出。
然則,其實不是在任何情形下都是按這一准繩處置的。對象可以在分歧的感化域中界說,可以有分歧的存儲種別。這些會影響挪用結構函數和析構函數的機會。
上面歸結一下甚麼時刻挪用結構函數和析構函數:
1) 在全局規模中界說的對象(即在一切函數以外界說的對象),它的結構函數在文件中的一切函數(包含main函數)履行之前挪用。但假如一個法式中有多個文件,而分歧的文件中都界說了全局對象,則這些對象的結構函數的履行次序是不肯定的。當main函數履行終了或挪用exit函數時(此時法式終止),挪用析構函數。
2) 假如界說的是部分主動對象(例如在函數中界說對象),則在樹立對象時挪用其結構函數。假如函數被屢次挪用,則在每次樹立對象時都要挪用結構函數。在函數挪用停止、對象釋放時先挪用析構函數。
3) 假如在函數中界說靜態(static )部分對象,則只在法式第一次挪用此函數樹立對象時挪用結構函數一次,在挪用停止時對象其實不釋放,是以也不挪用析構函數,只在main函數停止或挪用exit函數停止法式時,才挪用析構函數。
例如,在一個函數中界說了兩個對象:
void fn(){ Student stud1; //界說主動部分對象 static Student stud2; //界說靜態部分對象 }
在挪用fn函數時,先挪用stud1的結構函數,再挪用stud2的結構函數,在fn挪用停止時,stud1是要釋放的(由於它是主動部分對象),是以挪用stud1的析構函數。而stud2 是靜態部分對象,在fn挪用停止時其實不釋放,是以不挪用stud2的析構函數。直到法式停止釋放stud2時,才挪用stud2的析構函數。可以看到stud2是後挪用結構函數的,但其實不先挪用其析構函數。緣由是兩個對象的存儲種別分歧、性命周期分歧。