“using"关键字用于赋值新的c++ /CLI类
本文关键字:c++ CLI 赋值 用于 using quot 关键字 | 更新日期: 2023-09-27 17:53:15
我在' c++/CLI'中有一个实现某些类的程序集。让我们假设这个类是'SomeType'。
现在,在用c#开发的应用程序中,执行以下操作-
while(!Console.KeyAvailable)
{
using(SomeType type = new SomeType())
{
type.doSomething(); //do something
}
}
会有任何后果,如内存泄漏等,在任何情况下,说,如果有一个未处理的异常或任何类似的?
我读到using
关键字通常应该用于实现IDisposable的类,但对于c++/CLI类?
c++/CLI没有使用关键字的等效。它采用了一种不同的方法,一种本地c++程序员所期望的方法。熟悉一种非常常见的c++实现确定性销毁的习惯用法,即RAII模式。调用它需要使用"堆栈语义"。工作得很好,但是语法要求相当模糊。
我将首先展示笨拙的方式,有助于演示语法差异。让我们使用。net中的一次性类StreamReader:
String^ ReadTopLineFromFile(String^ path) {
StreamReader^ reader = gcnew StreamReader(path);
try {
return reader->ReadLine();
}
finally {
delete reader;
}
}
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
注意变量名上缺少^帽,这通常在存储引用类型引用时是必需的。故意省略它是调用模式的原因。不需要显式的gcnew
调用,编译器会自动发出它。还要注意,您不再使用->
来解引用对象,现在使用.
c++/CLI编译器自动生成try/finally块和delete操作符调用。它在作用域块的结束大括号处发出。就像本地c++编译器一样。虽然它看起来好像托管对象是在堆栈上分配的,但这只是一种语法错觉,它仍然在GC堆上。
语法当然是非常不同的,这是该特性唯一真正的缺点。知道什么时候使用^ hat,什么时候依赖堆栈语义是需要学习的东西,需要一些时间。