困惑:c++中c#类的实例创建

Posted

技术标签:

【中文标题】困惑:c++中c#类的实例创建【英文标题】:Confused: instance creation of c# class in c++ 【发布时间】:2012-01-05 01:55:04 【问题描述】:

假设someClass 是一个用C# 定义的类,带有一些int doSomething(void) 方法,为简单起见,提供一个不带参数的构造函数。然后,在 C# 中,必须在 gc 堆上创建实例:

someClass c;                   // legit, but only a null pointer in C#
// c->doSomething()            // would not even compile. 
c = new someClass();           // now it points to an instance of someclass.
int i = c->doSomething();      

现在,如果someClass被编译成一些.Net库,你也可以在C++/CLI中使用它:

someClass^ cpp_gcpointer = gcnew someClass();
int i = cpp_gcpointer->doSomething();

就这么简单!漂亮!这当然是假设对 .Net 库的引用已添加到项目中,并且已做出相应的 using 声明。

据我了解,这是与前面的 C# 示例完全相同的 C++/CLI 示例(浓缩为一行,这不是我感兴趣的重点)。正确的? (对不起,我是这个话题的新手)

然而,在 C++ 中,也

someClass cpp_cauto;              // in C++ declaration implies instantiation
int i = cpp_cauto.doSomething(); 

是有效的语法。出于好奇,我今天尝试了这个。一位同事看着我的肩膀,愿意打赌它甚至不会编译。他会输掉赌注。 (这仍然是 C# 程序集中的类)。实际上,它也产生与前面示例中的代码相同的结果i

也很漂亮,但是 - 嗯 - 它到底是什么,这里创造了什么?我的第一个疯狂猜测是,在我背后,.Net 在 gc 堆上动态创建了一个实例,cpp_auto 是该对象的某种包装器,其语法行为类似于 someClass 类的实例。但后来我找到了这个页面

http://msdn.microsoft.com/en-us/library/ms379617%28v=vs.80%29.aspx#vs05cplus_topic2

这个页面似乎告诉我,(至少,如果 someClass 是 C++ 类)cpp_auto 实际上是在堆栈上创建的,据我所知,这与经典 C++ 中的行为相同。还有一些你不能在 C# 中做的事情(你不能,可以吗?)。我想知道的是:来自 C# 程序集的实例是否也在堆栈上创建?您可以在 C++ 中使用无法在 C# 中创建的堆栈上的类实例生成 .Net 二进制文件吗?这甚至可能会给您带来性能提升:-) 吗?

亲切的问候,

托马斯

【问题讨论】:

【参考方案1】:

link you referenced 对此进行了详细解释:

C++/CLI 允许您使用引用类型的堆栈语义。这意味着您可以使用为在堆栈上分配对象而保留的语法引入引用类型。编译器将负责为您提供 C++ 所期望的语义,并通过在托管堆上实际分配对象来满足 CLR 的要求。

基本上,它仍在对托管堆上的引用类型进行句柄,但当它超出您的范围时,会自动在 IDisposable 实现上调用 Dispose()

然而,对象实例仍然通过gcnew(放置在托管堆上)有效地分配并由垃圾收集器收集。这也有详细解释:

当 d 超出范围时,将调用其 Dispose 方法以释放其资源。同样,由于对象实际上是从托管堆中分配的,因此垃圾收集器会在自己的时间处理释放它。

基本上,这一切都由编译器处理,以使代码看起来和工作起来像标准 C++ 堆栈分配的类,但它实际上只是一个编译器技巧。生成的 IL 代码仍在进行托管堆分配。

【讨论】:

哎哟。所以我在不认识的情况下找到了答案。感谢您向我指出这一点:-) @Thomas 没问题。这是一个很大的页面——你必须知道在那里寻找什么才能找到关于编译器诡计的讨论;) 再次感谢,但是,你看,这不是因为它是一个大页面。关键是,只有在您向我指出它确实回答了我的问题之后,我才真正理解引文。但也许这只是初学者的无知。然后,当然,无知是幸福:-)

以上是关于困惑:c++中c#类的实例创建的主要内容,如果未能解决你的问题,请参考以下文章

这在 C++ 中可能吗?

C#中类的创建和实例化

c++ 创建类的实例作为引用类型

为啥我不能创建在与类定义相同的命名空间中定义的 C++ 类的实例?

C# Activator.CreateInstance 动态创建类的实例

C# Activator.CreateInstance 动态创建类的实例