浅议C++/CLI的gcnew关键字

时间:2010-04-28 16:00:36  来源:第二电脑网  作者:第二电脑网

  第二电脑网导读:而new创建的对象必须自己来管理和释放.   当然,从程序员的角度来说,管它是句柄还是什么其他的东西,总跑不掉是对某块内存地址的引用,实际上我们都可以理解成指针.下面我们就写一段代码来测试一下好了. using namespace System; ref class Foo{public:   Foo()...
  正文:C++/CLI中使用gcnew关键字表示在托管堆上分配内存,并且为了与以前的指针区分,用^来替换* ,就语义上来说他们的区别大致如下:

  1.   gcnew返回的是一个句柄(Handle),而new返回的是实际的内存地址.
  2.   gcnew创建的对象由虚拟机托管,而new创建的对象必须自己来管理和释放.   当然,从程序员的角度来说,管它是句柄还是什么其他的东西,总跑不掉是对某块内存地址的引用,实际上我们都可以理解成指针.下面我们就写一段代码来测试一下好了. 
using namespace System; ref class Foo{public:   Foo()   {    System::Console::WriteLine("Foo::Foo");   }   ~Foo()   {    System::Console::WriteLine("Foo::~Foo");   }public:   int m_iValue;}; int _tmain(){   int* pInt = new int;   int^ rInt = gcnew int;   Foo^ rFoo = gcnew Foo;    delete rFoo;    delete rInt;   delete pInt;}
   我把调试的时候JIT编译的汇编代码择录了部分如下显示(请注意红色部分):

   int* pInt = new int;0000004c  mov     ecx,4 00000051  call     dword ptr ds:[03B51554h] 00000057  mov     esi,eax 00000059  mov     dword ptr [esp+18h],esi    int^ rInt = gcnew int;0000005d  mov     ecx,788EF9D8h 00000062  call     FCFAF66C 00000067  mov     esi,eax 00000069  mov     dword ptr [esi+4],0 00000070  mov     edi,esi    Foo^ rFoo = gcnew Foo;00000072  mov     ecx,3B51768h 00000077  call     FCFAF66C 0000007c  mov     esi,eax 0000007e  mov     ecx,esi 00000080  call     dword ptr ds:[03B517ACh] 00000086  mov     dword ptr [esp+1Ch],esi     delete rFoo; 0000008a  mov     ebx,dword ptr [esp+1Ch] 0000008e  test     ebx,ebx 00000090  je      000000A4 00000092  mov     ecx,ebx 00000094  call     dword ptr ds:[03FD0028h] 0000009a  mov     dword ptr [esp+14h],0 000000a2  jmp     000000AC 000000a4  mov     dword ptr [esp+14h],0    delete rInt;000000ac  mov     edx,edi 000000ae  mov     ecx,788F747Ch 000000b3  call     FC8D20FD 000000b8  mov     ebp,eax 000000ba  test     ebp,ebp 000000bc  je      000000D0 000000be  mov     ecx,ebp 000000c0  call     dword ptr ds:[03FD0020h] 000000c6  mov     dword ptr [esp+10h],0 000000ce  jmp     000000D8 000000d0  mov     dword ptr [esp+10h],0    delete pInt;000000d8  mov     ecx,dword ptr [esp+18h] 000000dc  call     dword ptr ds:[03B51540h]  
    我们先看分配内存这部分的代码   1.调用new方式分配
int* pInt = new int;0000004c  mov     ecx,4 00000051  call     dword ptr ds:[03B51554h]

  可以看到,和以前在vc6中一样,分配内存的步骤如下:
  1.  首先把sizeof(int) = 4 放到ecx中
  2.  调用operator new 去分配4个字节
  3.  调用构造函数等等......(这里不是我们的重点)
  成功分配后,会把返回地址放在eax中。   2.调用gcnew方式分配
   int^ rInt = gcnew int;0000005d  mov     ecx,788EF9D8h 00000062  call     FCFAF66C。。。   Foo^ rFoo = gcnew Foo;00000072  mov     ecx,3B51768h 00000077  call     FCFAF66C

  可以看到gcnew也是通过把一个参数放到ecx中,然后再调用一个函数来完成分配的操作,显然0x788EF9D8应该是一个地址,而不可能是一个数值。我们可以看到这里gcnew创建两个不同类型的变量,调用的函数地址却都是0xFCFAF66C,而存放到ecx中的两个地址就不一样。究竟这几个地址代表什么呢?   和new一样gcnew也是把返回地址放在eax中。我们直接从内存窗口看eax指向的内存块好了。Aha,看到了没有? 《浅议C++/CLI的gcnew关键字》由第二电脑网原创提供,转载请注明:http://www.002pc.com/master/College/Language/VC/2010-04-28/13810.html


关键字:

关于《浅议C++/CLI的gcnew关键字》文章的评论

站内搜索: 高级搜索

热门搜索: Windows style 系统 tr IP QQ CPU 安装 function 注册 if td