C++ cli 如何处理通过值传递给委托的本机类型?

C++ cli 如何处理通过值传递给委托的本机类型?,c++-cli,C++ Cli,通过值传递给委托调用的本机类会发生什么情况 这是一个让我困惑的代码。我对Native的ctor/dtor调用的期望在代码中有注释 输出: 本地计算机3207236 本机副本3207240 m1 本机dtor 3207240 m2 本机dtor 3207240 m3 本机dtor 3207240 本机dtor 3207236 真正的结果对我来说很奇怪: 每个委托处理程序调用本机的dtor,但本机的复制ctor只调用一次(在委托调用期间)。 这意味着通过值传递给委托的对象只创建一次(通过copy-c

通过值传递给委托调用的本机类会发生什么情况

这是一个让我困惑的代码。我对Native的ctor/dtor调用的期望在代码中有注释

输出:
本地计算机3207236
本机副本3207240
m1
本机dtor 3207240
m2
本机dtor 3207240
m3
本机dtor 3207240
本机dtor 3207236

真正的结果对我来说很奇怪:
每个委托处理程序调用本机的dtor,但本机的复制ctor只调用一次(在委托调用期间)。

这意味着通过值传递给委托的对象只创建一次(通过copy-ctor),但调用其dtor的次数有3(!)次! 我不明白为什么

有人能解释一下为什么我的期望落空了吗

class Native
{
public:
  Native()
  {
     Console::WriteLine("Native ctor {0}", __int64(this));
  }

  ~Native()
  {
     Console::WriteLine("Native dtor {0}", __int64(this));
  }

  Native(const Native& nat)
  {
     Console::WriteLine("Native copy ctor {0}", __int64(this));
  }
};

ref class Managed
{
public:
  delegate void Dele(Native);
  Dele^ m_delegate;

  Managed()
  {
     m_delegate = static_cast<Dele^>(Delegate::Combine(gcnew Dele(this, &Managed::m1), gcnew Dele(this, &Managed::m2), gcnew Dele(this, &Managed::m3)));
  }

  void m1(Native nat) // Expected: Native's copy ctor is called before Delegate calls the method 
                      // Reality: NO
  {
     Console::WriteLine("m1");
  } // Expected: Native's dtor is called; Reality: YES

  void m2(Native nat) // Expected: Native's copy ctor is called before Delegate calls the method
                    // Reality: NO
  {
     Console::WriteLine("m2");
  } // Expected: Native's dtor is called; Reality: YES

  void m3(Native nat) // Expected: Native's copy ctor is called before Delegate calls the method
                     // Reality: NO
  {
     Console::WriteLine("m3");
  } // Expected: Native's dtor is called; Reality: YES
};

int main(array<System::String ^> ^args)
{
   Native n; // Expected: Native's ctor is called; Reality: YES.
   Managed^ man = gcnew Managed();
   man->m_delegate(n); // Native's copy ctor is called; Reality: YES
   return 0;
} // Expected: Native's dtor is called; Reality: YES
本机类
{
公众:
本机()
{
控制台::WriteLine(“本机ctor{0}”,_uuint64(this));
}
~Native()
{
控制台::WriteLine(“本机dtor{0}”,_uuint64(this));
}
本机(常量本机和nat)
{
控制台::WriteLine(“本机副本选择器{0}”,uu int64(this));
}
};
ref类管理
{
公众:
代表无效删除(本地);
代表团成员;
管理的()
{
m_delegate=static_cast(delegate::Combine(gcnew Dele(this,&Managed::m1)、gcnew Dele(this,&Managed::m2)、gcnew Dele(this,&Managed::m3));
}
void m1(Native nat)//应为:在委托调用方法之前调用Native的copy-ctor
//现实:没有
{
控制台::写线(“m1”);
}//预期:调用本机的dtor;实际:是
void m2(Native nat)//应为:在委托调用该方法之前调用Native的copy-ctor
//现实:没有
{
控制台:WriteLine(“m2”);
}//预期:调用本机的dtor;实际:是
void m3(本机nat)//应为:在委托调用该方法之前调用本机的复制构造函数
//现实:没有
{
控制台:WriteLine(“m3”);
}//预期:调用本机的dtor;实际:是
};
int main(数组^args)
{
本机n;//应为:调用本机的ctor;实际情况:是。
托管^man=gcnew Managed();
man->m_delegate(n);//调用Native的copy-ctor;Reality:YES
返回0;
}//应为:调用本机的dtor;现实:是的

是的,您可以称之为bug。报告它没有意义,这很难解决。CLR在为委托生成存根时采用值类型行为,它没有处理变得无效的值类型值的机制。你需要通过引用来解决这个问题。谢谢!是的,我已经按照你的建议做了。您能告诉我在哪里可以阅读更多关于代理/存根生成的信息吗。我猜它类似于COM代理/存根。我记得有一种方法可以编写和注册自定义封送处理。除了CLR源代码之外,我不知道有任何地方记录了这一点。在SSCLI20发行版中提供,这是一本难读的书。与COM代理无关。顺便说一句,您可能对@Hans感兴趣;)