use*_*240 0 c# memory idisposable c++-cli
我在'C++/CLI'中有一个程序集,它实现了某些类.我们假设该类是'SomeType'.
现在,在'C#'开发的应用程序中,执行以下操作 -
while(!Console.KeyAvailable)
{
using(SomeType type = new SomeType())
{
type.doSomething(); //do something
}
}
Run Code Online (Sandbox Code Playgroud)
在任何情况下都会有任何后果,例如内存泄漏等,比如是否存在未处理的异常或任何此类情况?
我读到using
关键字通常应该用于实现IDisposable的类,但对于C++/CLI类?
C++/CLI没有using关键字的等价物.它采用了一种不同的方法,一种是本机C++程序员所期望的方法.谁熟悉一种非常常见的C++习惯用法来实现确定性破坏,即RAII模式.调用它需要使用"堆栈语义".运行良好,但语法要求相当模糊.
我将首先展示笨拙的方式,有助于演示语法差异.让我们使用StreamReader,.NET中的一次性类:
String^ ReadTopLineFromFile(String^ path) {
StreamReader^ reader = gcnew StreamReader(path);
try {
return reader->ReadLine();
}
finally {
delete reader;
}
}
Run Code Online (Sandbox Code Playgroud)
try/finally是使代码异常安全的原因,如果ReadLine()抛出异常,则StreamReader对象仍然被释放,并且保证文件上的锁定被释放.这是C#编译器在您使用该using
语句时自动发出的代码.还要注意delete
运算符的使用,它实际上调用了StreamReader :: Dispose()方法.编译器不会让你写reader->Dispose()
,使用运算符是必需的.
现在是C++/CLI编译器支持的使用版本.您可以通过模拟本机C++编译器处理在堆栈上分配的C++对象的方式来调用堆栈语义.像这样:
String^ ReadTopLineFromFile(String^ path) {
StreamReader reader(path);
return reader.ReadLine();
} // <== disposed here
Run Code Online (Sandbox Code Playgroud)
请注意变量名称上缺少的^ hat,通常在存储引用类型引用时需要.故意省略它是调用模式的原因.无需显式gcnew
调用,编译器会自动发出它.另请注意->
,您现在不再使用取消引用该对象.
C++/CLI编译器自动生成try/finally块以及delete操作符调用.这是在示波器块的右括号中发出的.就像本机C++编译器一样.虽然看起来托管对象是在堆栈上分配的,但这只是一种语法错觉,它仍然在GC堆上.
语法当然是非常不同的,唯一真正的挂起功能.知道何时使用^ hat以及何时依赖堆栈语义是需要学习的东西,需要一段时间.
归档时间: |
|
查看次数: |
551 次 |
最近记录: |