構造函數和析構函數

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

什麼是構造函數和析構函數?

構造函數就是在一個類被建立的時候自動執行的函數。
析構函數就是在一個類被銷毀的時候自動執行的函數。
例如下面這段代碼:

#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是局部變量。

完。

Tags: