程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 詳解C++編程中的析構函數

詳解C++編程中的析構函數

編輯:關於C++

詳解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是後挪用結構函數的,但其實不先挪用其析構函數。緣由是兩個對象的存儲種別分歧、性命周期分歧。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved