[C++/CLI] 解構函式等於IDisposable::Dispose()方法

來源:互聯網
上載者:User

在以前的一篇文章裡我曾提到在C++/CLI中,會自動調用Dispose()方法。但那個時候只是從msdn上的文章中知道這樣一個特性,還沒有編譯器的支援,所以一切也只能是紙上談兵,很多細節都很不明朗。VC會以什麼樣的方式來提供這一特性,一直是我常思考的問題。然而甚至到VS.net 2005 beta1發布時,這一特性還沒有得到支援。

好在,在最新的Visual C++ 2005 Tool Refresh中的編譯器,已經支援了這一特性。那麼就讓我們來一探究竟吧。

首先,在最新的編譯器中,如果一個類定義了解構函式,編譯器會自動讓類實現IDisposable介面,並把解構函式映射到Dispose()方法上。假如我們定義以下這個類

它最終產生的IL代碼是這樣的。

我們可以看到它已經實現了IDisposable介面,並且Dispose方法的內容就是解構函式的內容。

其次為了能夠確定自動調用Dispose()方法的時機,C++/CLI現在支援一種新的對象執行個體化文法。

通常為了獲得一個類的執行個體,我們需要這樣寫:

Test^ t = gcnew Test();

但為了獲得自動調用Dispose()方法的好處,我們必須以這樣的文法來執行個體化類:

Test t;

這就彷彿native c++中在棧(Stack)上執行個體化了一個對象一樣。當然這隻是一個文法的模仿,真正的對象還是在堆中執行個體化的。然而以這種方法執行個體化,就告訴了編譯器,但退出對象申明所在的範圍時,希望能自動調用對象的Dispose()方法。

讓我們來看一個函數:

觀察函數的IL代碼,可以發現調用Dispose()方法的代碼已經被加入到方法中了。並且為了在拋出異常時,也能調用Dispose()方法,編譯器還自動加上了一個try塊。

以上的foo()函數,如果用C#來寫,會是這樣:

void foo()
{
      using (Test t = new Test())
      {
      }
}

然而,大家都知道using有一個最大的缺點,就是一次只能執行個體化一個對象。而在ado.net的程式中,經常我們會需要一次申明幾個對象。這時候using語句就無能為力了。而C++/CLI提供的這一機制,完美地解決了這一問題。你可以一次申明多個對象,當這些對象退出範圍時,就會自動Dispose。

並且,範圍的識別方法和native c++中是一致的。也就是說你可以添加一對大括弧來構成一個範圍,而不一定要是一個函數,就像這樣:

值得注意的是,雖然在這個post中,我用了“對象退出範圍”這樣的詞,但是這隻是為了判斷Dispose方法調用的時機,並不表明對象在退出範圍之後就被回收了,對象記憶體的回收仍然是GC操控的,就像C#的using語句中那樣。

總得來說,C++/CLI在吸收了C#中using語句的經驗傳承之後,為顯式釋放資源提供了一個完美的解決方案。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.