[C++/CLI]在棧上聲明Reference Type

來源:互聯網
上載者:User

在上次介紹顯示釋放資源的文章,我提到了C++/CLI中提供了一種新的對象執行個體化文法,就彷彿在native c++中在靜態棧上定義一個對象一樣。今天就讓我們來考察一下這個特性。另外,因為在上個文章裡回答Ninputer的一個問題時,犯了一個錯誤,我在這裡糾正一下...

定義以下以一個類。

ref class Test
{
Test(String^ s)
 {
  this->_s = s;

 }
 void Hello()
 {
  Console::WriteLine(_s);
 }

 property String^ Message
 {
  String^ get() { return  _s;}
 }
 
 
private:
 String^ _s;
};

然後我們定義一個函數來使用這個類:

void foo()
{
 Test t("Hello"); //沒有無參建構函式時的定義方法
 t.Hello();             //使用“點”來訪問成員,而不是"->"符號
 Console::WriteLine(t.Message); //訪問屬性
}

我們來看一下產生的IL代碼
.method assembly static void  foo() cil managed
{
  // Code size       29 (0x1d)
  .maxstack  1
  .locals init ([0] class Test V_0)
  IL_0000:  ldstr      "Hello"
  IL_0005:  newobj     instance void Test::.ctor(string)
  IL_000a:  stloc.0
  IL_000b:  ldloc.0
  IL_000c:  call       instance void Test::Hello()
  IL_0011:  ldloc.0
  IL_0012:  call       instance string Test::get_Message()
  IL_0017:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_001c:  ret
} // end of method 'Global Functions'::foo

如果我們把上面的foo()函數改成gcnew的形式:

void foo()
{
    Test^ t = gcnew Test("Hello");
    t->Hello();
    Console::WriteLine(t->Message);
}

然後觀察產生的IL代碼:

.method assembly static void  foo() cil managed
{
  // Code size       29 (0x1d)
  .maxstack  1
  .locals init ([0] class Test V_0)
  IL_0000:  ldstr      "Hello"
  IL_0005:  newobj     instance void Test::.ctor(string)
  IL_000a:  stloc.0
  IL_000b:  ldloc.0
  IL_000c:  call       instance void Test::Hello()
  IL_0011:  ldloc.0
  IL_0012:  call       instance string Test::get_Message()
  IL_0017:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_001c:  ret
} // end of method 'Global Functions'::foo

可以看到產生的IL代碼與前面的是完全一致的。由此可見,這種新的文法只是編譯器提供的一種機制,並不是真的在Stack上執行個體化對象。那麼為什麼要提供這種文法呢?或者說兩種的區別在哪裡呢?那就是在上一篇文章中所提到的顯式釋放資源。只有用Stack方法來定義變數,才能獲得自動調用Dispose()方法的好處。

或許,我們今後應該盡量少用gcnew,除非你想手動控制Dispose()方法調用的時機。唯一比較遺憾的是,由於是從vc 2005 tool refreshes才開始支援這種文法,所以vc express的IDE中的intellisense功能還沒有跟上,使用“點”操作符時,沒有任何提示,不過相信在beta2裡一定會全面支援的。另外MS的員工還透露說beta2中,STL.NET可能就會現身了,真是非常期待。

另:

昨天Ninputer問我Stack定義的對象,是用->訪問成員還是用“點”來訪問成員。我回答是用->來訪問,其實應該是“點”才對。前幾天實驗的時候不知道為什麼編譯器沒有報錯......可惜代碼已經不在了,也沒法知道當時犯了什麼錯 今天寫這個帖的時候才發現不對了...

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.