Winform析构函数被调用两次

时间:2016-02-17 18:24:03

标签: .net winforms c++-cli destructor

我有一个由VS2013模板制作的标准c ++ cli win32 winform应用程序。

第一个调用返回到不可调试的位置"C:\Windows\SysWOW64\user32.dll"

第二个在Application::Run(%instance);中的Main()之后立即返回:

Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);

PorjectName::UserClass instance;
Application::Run(%instance);

我不认为这会伤害任何事情,但我很想知道为什么会这样。

这种行为是否与winforms c ++ cli对象的工作方式有关?我怎样才能弄清楚是什么导致它?

我遵循了这个指南:http://www.bogotobogo.com/cplusplus/application_visual_studio_2013.php

1 个答案:

答案 0 :(得分:2)

   PorjectName::UserClass instance;

这就是造成它的原因。 UserClass是一个引用类型,您通常声明一个变量,该变量使用^ hat存储对象的引用。但是你没有,你现在调用一个名为"stack semantics"的模式。它在本机C ++中模拟RAII模式,编译器会自动在结束括号中调用析构函数。

这不适用于派生自Form或Control的类。这些对象已经自动处理,它在窗口关闭后发生。所以你看到对析构函数的两个调用,第一个来自Winforms,第二个来自Main()函数中隐藏的析构函数调用。

这实际上不是托管代码中的错误,实际上在某些类中是常见的。例如,从Stream派生的类几乎是不可避免的。请记住,终结器扮演的角色与C ++ / CLI语法中的本机C ++析构函数!classname相同。尽管如此,如果你不依赖它,很容易拍出你的腿。

只需正确编写代码:

ProjectName::UserClass^ instance = gcnew ProjectName::UserClass;
Application::Run(instance);

或者

auto instance = gcnew ProjectName::UserClass;
Application::Run(instance);

或者

Application::Run(gcnew ProjectName::UserClass);