1. 程式人生 > 其它 >建構函式和解構函式

建構函式和解構函式

本文原創,轉載需註明原作者。

什麼是建構函式和解構函式?

建構函式就是在一個類被建立的時候自動執行的函式。
解構函式就是在一個類被銷燬的時候自動執行的函式。
例如下面這段程式碼:

#include<bits/stdc++.h>
using namespace std;
class A{
public:
  A(){
    cout<<"created."<<endl;
  }
  ~A(){
    cout<<"destroyed."<<endl;
  }
};
class A test;
int main(){
  cout<<"main."<<endl;
}

輸出結果:
created.
main.
destroyed.

可以看到,created在main之前輸出,說明在定義一句“class A test”這一句中就已經執行了這個建構函式。
在main結束後,test變數被自動銷燬,輸出destroyed。

建構函式的寫法

考慮如下的程式碼:

#include<bits/stdc++.h>
using namespace std;
class A{
public:
  int a;
  A(int i){
    a=i;
  }
};
int main(){
  A test(5);
  cout<<test.a;
}

可以看到,建構函式和普通的成員函式寫法類似,但是沒有返回值。建構函式名稱必須和類名一致。
在定義變數的時候,只需要在變數名之後寫上括號和引數即可。

建構函式注意事項

如果我們定義了一個建構函式,但是沒有呼叫,會發生什麼?

#include<bits/stdc++.h>
using namespace std;
class A{
public:
  int a;
  A(int i){
    a=i;
  }
};
int main(){
  A test;
  cout<<test.a;
}

輸出:error: no matching function for call to 'A::A()'

其實普通時候,我們定義A test,就是在呼叫一個空建構函式,等同於A test()。
如果我們沒有定義建構函式,編譯器會自動寫一個空建構函式A::A(),這樣就可以呼叫A test()了。
然而我們已經有一個構造函數了,編譯器沒有提供空建構函式,因此報錯。

再看一個例子,我們看這段程式碼,會輸出什麼?是created,main嗎?

#include<bits/stdc++.h>
using namespace std;
class A{
public:
  int a;
  A(){
    cout<<"created"<<endl;
  }
};
A *test;
int main(){
  cout<<"main"<<endl;
  test=new A;
}
點我看答案 正確輸出是main,created。 只有在new之後,test才被分配記憶體,呼叫建構函式。如果沒有new,test沒有對應的記憶體,就沒有被初始化。

我們再看這段程式碼,又會輸出什麼?

#include<bits/stdc++.h>
using namespace std;
class A{
public:
  int a;
  A(){
    cout<<"created"<<endl;
  }
};
A *test;
int main(){
  cout<<"main"<<endl;
  test=(A*)malloc(sizeof(A));
}
點我看答案 只輸出main。大家可能會很奇怪,不就是把new換成malloc嗎?其實,只有new可以自動呼叫建構函式,malloc不會呼叫建構函式,因此,我鼓勵大家在C++中多使用new而不是malloc。(當然,其實new也有它的缺點,例如不能realloc)

解構函式

解構函式的寫法和建構函式類似,函式名是類名,只是在前面加上一個~符號,表示解構函式。
在delete一個指標的時候,會自動呼叫解構函式,與new類似。

#include<bits/stdc++.h>
using namespace std;
class A{
public:
  int a;
  ~A(){
    cout<<"destroy,";
  }
  
};
A *test;
int main(){
  cout<<"main,";
  test=new A;
  delete test;
}

通過解構函式,我們可以看出區域性變數的作用域。例如,會輸出幾次destroy?

#include<bits/stdc++.h>
using namespace std;
class A{
public:
  int a;
  ~A(){
    cout<<"destroy,";
  }
  
};
int main(){
  cout<<"main,";
  int n=10;
  while(n--){
    A test;
  }
}
點我看答案 答案:10次,因為while一共實行10次迴圈,test是區域性變數。

完。