//=====================================================================
//TITLE:
// C++ VS C#(10):構造函數與析構函數
//AUTHOR:
// norains
//DATE:
// Friday 18-January-2011
//Environment:
// Visual Studio 2010
// Visual Studio 2005
//=====================================================================
1. 構造函數與析構函數
類最不可或缺的是什麼?沒錯,就是構造函數和析構函數。對於C++和C#而言,兩者的基礎語法是一致的,構造函數都是和類名稱同名,而析構函數就是在類名稱之前增加~標志,如:
view plaincopy to clipboardprint?
//C++
class CMyBase
{
public:
//構造函數
CMyBase(){};
//析構函數
virtual ~CMyBase(){};
};
//C++
class CMyBase
{
public:
//構造函數
CMyBase(){};
//析構函數
virtual ~CMyBase(){};
};
view plaincopy to clipboardprint?
//C#
class CMyBase
{
//構造函數
public CMyBase(){}
//析構函數
public ~CMyBase(){}
};
//C#
class CMyBase
{
//構造函數
public CMyBase(){}
//析構函數
public ~CMyBase(){}
};
不過在C#中,雖然我們聲明的析構函數是~CMyBase(),但在.NET實際調用的卻是Finalize()。說白了,Finalize()其實就是我們聲明的析構函數~CMyBase()的別名。那麼我們可不可以不定義~CMyBase(),而直接實現Finalize()呢?建議是最好不要。因為~CMyBase()會默認調用基類的析構函數,而Finalize()必須手工調用,存在一定的風險性。
接下來的區別,就更加擴大了兩者的區別。默認情況下,派生類調用的是基類的默認構造函數,如果需要調用非默認的構造函數,兩種語言都有相應的語法。
首先我們來看看C++,如果需要調用基類的非默認構造函數,那麼我們必須要在派生類的構造函數中明確指出,也就是明確調用基類的非默認構造函數,如:
view plaincopy to clipboardprint?
//C++
//基類
class CMyBase
{
public:
//默認構造函數
CMyBase(){};
//非默認構造函數
CMyBase(int i){};
//析構函數
virtual ~CMyBase(){};
};
//派生類
class CDerive:
public CMyBase
{
public:
//默認構造函數
CDerive(){};
//明確指出調用的是基類的非默認構造函數
CDerive(int i):CMyBase(i){};
//析構函數
virtual ~CDerive(){};
};
//C++
//基類
class CMyBase
{
public:
//默認構造函數
CMyBase(){};
//非默認構造函數
CMyBase(int i){};
//析構函數
virtual ~CMyBase(){};
};
//派生類
class CDerive:
public CMyBase
{
public:
//默認構造函數
CDerive(){};
//明確指出調用的是基類的非默認構造函數
CDerive(int i):CMyBase(i){};
//析構函數
virtual ~CDerive(){};
};
C#的手法和C++其實也差不多,不過這裡並不需要明確指出基類的構造函數,而是用base關鍵字替代,如:
view plaincopy to clipboardprint?
//C#
//基類
class CMyBase
{
//默認構造函數
public CMyBase(){}
//非默認構造函數
public CMyBase(int i){}
//析構函數
public ~CmyBase(){}
};
class CMyDerive:
CMyBase
{
//默認構造函數
public CMyDerive(){}
//以base關鍵字來明確指出調用的是基類的非默認構造函數
public CMyDerive(int i): base(i){}
//析構函數
public ~ CMyDerive (){}
};
//C#
//基類
class CMyBase
{
//默認構造函數
public CMyBase(){}
//非默認構造函數
public CMyBase(int i){}
//析構函數
public ~CmyBase(){}
};
class CMyDerive:
CMyBase
{
//默認構造函數
public CMyDerive(){}
//以base關鍵字來明確指出調用的是基類的非默認構造函數
public CMyDerive(int i): base(i){}
//析構函數
public ~ CMyDerive (){}
};
C++需要明確指出基類的名稱,而C#可以不用理會而直接用base替代,相對來說,似乎C#更為簡便一些。因為如果基類的名稱有所改變的話,那麼C#只需要修改繼承時的名字,而C++需要修改的似乎更多。那麼為什麼C++為什麼不能也增加一個類似於base的關鍵字呢?這個和繼承的機制有關。因為C#只支持單繼承,也就是只能允許有一個基類,所以base關鍵字指向非常明確;而C++因為是能夠多重繼承的,也就是說有多個基類,單單的一個base關鍵字根本無法明確指出是哪個基類。
除了base關鍵字以外,C#還支持一個this關鍵字。和base指向基類的不同,this指向的是當前類。簡單點來說,.NET在執行當前的類構造函數之前,會先執行this指向的當前類的構造函數。當然咯,this的執行次序還是在基類的構造函數完畢之後。我們來看看下面這段代碼:
view plaincopy to clipboardprint?
class CMyBase
{
//默認構造函數
public CMyBase()
{
Console.WriteLine("CMyBase()");
}
//非默認構造函數
public CMyBase(int i)
{
Console.WriteLine("CMyBase(i)");
}
};
class CMyDerive: