测试类:
#pragma once
ref class Hello
{
public:
Hello();
~Hello();
!Hello();
};
/***************/
#include "Hello.h"
Hello::Hello()
{
System::Console::WriteLine("构造函数!");
}
Hello::~Hello()
{
System::Console::WriteLine("析构函数!");
}
Hello::!Hello()
{
System::Console::WriteLine("终结器:!");
}
主函数:
#include "Hello.h"
using namespace System;
int main()
{
{
Hello ^hello = gcnew Hello();
delete hello; // 显示释放
}
{
Hello h; // 这种栈对象,超过作用域会调用析构函数。也是显式释放。
}
String^ info = Console::ReadLine();
Console::WriteLine("信息:{0}", info);
GC::Collect(); // 垃圾回收
return 0;
}
上面的主函数,运行输出会这样:
构造函数!
析构函数!
构造函数!
析构函数!
如果,动态对象不显示释放:
int main()
{
{
Hello ^hello = gcnew Hello();
//delete hello; // 不显示释放
}
{
Hello h; // 这种栈对象,超过作用域会调用析构函数。也是显式释放。
}
String^ info = Console::ReadLine();
Console::WriteLine("信息:{0}", info);
GC::Collect(); // 垃圾回收
return 0;
}
输出应该这样:
构造函数!
构造函数!
析构函数!
终结器:!
经测试,Hello ^hello = gcnew Hello();
这种动态对象,如果用 delete
显示释放,会调用析构函数。终结器
是在GC回收前调用的;如果显示释放调用了析构函数,就不会再调用终结器
了。所以要注意这个。 gcnew 动态调用,不显示释放,GC 回收的话会调用终结器
。所以一般用下面这种方式,保证什么情况都能释放非托管内存:
Hello::~Hello()
{
// 这里释放非托管资源
System::Console::WriteLine("析构函数!");
!Hello(); // 在析构函数里再调用终结器
}
Hello::!Hello()
{
// 这里释放非托管资源
System::Console::WriteLine("终结器:!");
}
标签:调用,Console,函数,WriteLine,C++,析构,Hello,CLI
From: https://www.cnblogs.com/huvjie/p/18007150