1. 程式人生 > >【C++】c++中的六個預設函式——解構函式

【C++】c++中的六個預設函式——解構函式

  • 解構函式(不能過載,沒有引數,一個類只能有一個解構函式。如果沒定義,編譯器會自動生成一個)

解構函式:建立物件時系統會自動呼叫建構函式進行初始化工作,同樣,銷燬物件時系統也會自動呼叫一個函式來進行清理工作。

解構函式(Destructor)也是一種特殊的成員函式,沒有返回值,不需要顯式呼叫(程式設計師也沒法顯式呼叫),而是在銷燬物件時自動執行。建構函式的名字和類名相同,而解構函式的名字是在類名前面加一個“~”符號。 如下函式:

#include <iostream>
using namespace std;

class Func{
public:
    Func(int len);  //建構函式
    ~Func();  //解構函式
public:
    void input();  //從控制檯輸入陣列元素
    void show();  //顯示陣列元素
private:
    int *ptr(int i);  //獲取第i個元素的指標
private:
    const int m_len;  //陣列長度
    int *m_arr; //陣列指標
    int *m_p;  //指向陣列第i個元素的指標
};

Func::Func(int len): m_len(len){
    if(len > 0)
	{ 
		m_arr = new int[len];  /*分配記憶體*/ 
	}
    else
	{ 
		m_arr = NULL; 
	}
}
Func::~Func()
{
    delete[] m_arr;  //釋放記憶體
}
void Func::input()
{
    for(int i=0; m_p=ptr(i); i++)	
		cin>>*ptr(i); 
}
void Func::show()
{
    for(int i=0; m_p=ptr(i); i++)
	{
        if(i == m_len - 1)
		{ 
			cout<<*ptr(i)<<endl; 
		}
        else
		{ 
			cout<<*ptr(i)<<", "; 
		}
    }
}
int * Func::ptr(int i)
{
    if(!m_arr || i<0 || i>=m_len)
	{ 
		return NULL; 
	}
    else
	{ 
		return m_arr + i; 
	}
}

int main(){
    //建立一個有n個元素的陣列(物件)
    int n;
    cout<<"Input array length: ";
    cin>>n;
    Func *parr = new Func(n);
    //輸入陣列元素
    cout<<"Input "<<n<<" numbers: ";
    parr -> input();
    //輸出陣列元素
    cout<<"Elements: ";
    parr -> show();
    //刪除陣列(物件)
    delete parr;

    return 0;
}

在所有函式之外建立的物件是全域性物件,它和全域性變數類似,位於記憶體分割槽中的全域性資料區,程式在結束執行時會呼叫這些物件的解構函式。

在函式內部建立的物件是區域性物件,它和區域性變數類似,位於棧區,函式執行結束時會呼叫這些物件的解構函式。
new 建立的物件位於堆區,通過 delete 刪除時才會呼叫解構函式;如果沒有 delete,解構函式就不會被執行。(下面的例子)

#include <iostream>
#include <string>
using namespace std;

class Demo{
public:
    Demo(string s);
    ~Demo();
private:
    string m_s;
};
Demo::Demo(string s): m_s(s){ }
Demo::~Demo(){ cout<<m_s<<endl; }

void func(){
    //區域性物件
    Demo obj1("1");
}

//全域性物件
Demo obj2("2");

int main(){
    //區域性物件
    Demo obj3("3");
    //new建立的物件
    Demo *pobj4 = new Demo("4");
    func();
	/*位置1*/
	//delete(pobj4);//有delete 才會呼叫 pobj4
    cout<<"main"<<endl;
	/*位置2*/
	delete(pobj4);//位置不同調用的時機也不同
    
    return 0;
}

執行結果分析: