困惑:在c++中创建c#类的实例
本文关键字:实例 创建 c++ 困惑 | 更新日期: 2023-09-27 18:15:28
假设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++/CLI等效于前面的c#示例(浓缩到一行,这不是我感兴趣的点)。正确吗?(对不起,我对这个话题不熟悉)
在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
这个页面似乎告诉我,(至少,如果someeclass是一个c++类)cpp_auto
实际上是在堆栈上创建的,据我所知,这将是你在经典c++中得到的相同行为。这是你在c#中做不到的(你做不到,对吧?)我想知道的是:从c#程序集的实例也创建在堆栈上吗?你能否在c++中生成。net二进制文件,并在堆栈中创建类实例,而这在c#中是无法创建的?这可能会给你带来性能提升吗?
亲切的问候,托马斯
您引用的链接详细说明了这一点:
c++/CLI允许对引用类型使用堆栈语义。这意味着您可以使用为堆栈上的对象分配保留的语法引入引用类型。编译器将负责为您提供您期望从c++中获得的语义,并在幕后通过在托管堆上实际分配对象来满足CLR的要求。
基本上,它仍然对托管堆上的引用类型做一个句柄,但是当它超出IDisposable
的范围时,它会自动调用Dispose()
。
gcnew
有效地分配(放在托管堆上),并由垃圾收集器收集。这也有详细的解释:
当d超出作用域时,将调用其Dispose方法以允许释放其资源。同样,由于对象实际上是从托管堆中分配的,因此垃圾收集器将在自己的时间内负责释放它。
基本上,这些都是由编译器处理的,使代码看起来和工作起来像标准的c++堆栈分配类,但这实际上只是一个编译器的技巧。生成的IL代码仍然在执行托管堆分配。