为什么一个表单的析构函数被调用两次?
Why is destructor for a form called twice?
这段带有入口点的代码调用了窗体的析构函数两次。
void Main(array<String^>^ args)
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
MyApp::MyForm form;
Application::Run(%form);
}
我改成了
void Main(array<String^>^ args)
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
Application::Run(gcnew MyApp::MyForm);
}
第二个版本只调用一次析构函数。
为什么最初被调用了两次?
MyApp::MyForm form;
这是完全错误的。知道何时在变量声明上使用 ^ 帽子在 C++/CLI 中非常重要。当你不使用它时,就像你在这里所做的那样,然后你调用 "stack semantics"。它是 C++ RAII 模式的仿真,编译器会自动发出对 Main() 末尾的析构函数的调用。
但这不应该发生,MyForm 对象的析构函数会在您关闭 window 时自动调用。因此,在您的情况下,您会看到它 运行 两次。实际上不是致命的,与原生 C++ 非常不同,除非你在析构函数中用原生代码做一些不平凡的事情。请记住,ref 类型的析构函数与对象销毁没有任何关系,那是垃圾收集器的工作。它仅用于清理本机资源。
this MSDN article 中有关堆栈语义的更多信息。
这段带有入口点的代码调用了窗体的析构函数两次。
void Main(array<String^>^ args)
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
MyApp::MyForm form;
Application::Run(%form);
}
我改成了
void Main(array<String^>^ args)
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
Application::Run(gcnew MyApp::MyForm);
}
第二个版本只调用一次析构函数。
为什么最初被调用了两次?
MyApp::MyForm form;
这是完全错误的。知道何时在变量声明上使用 ^ 帽子在 C++/CLI 中非常重要。当你不使用它时,就像你在这里所做的那样,然后你调用 "stack semantics"。它是 C++ RAII 模式的仿真,编译器会自动发出对 Main() 末尾的析构函数的调用。
但这不应该发生,MyForm 对象的析构函数会在您关闭 window 时自动调用。因此,在您的情况下,您会看到它 运行 两次。实际上不是致命的,与原生 C++ 非常不同,除非你在析构函数中用原生代码做一些不平凡的事情。请记住,ref 类型的析构函数与对象销毁没有任何关系,那是垃圾收集器的工作。它仅用于清理本机资源。
this MSDN article 中有关堆栈语义的更多信息。