“using”关键字用于分配新的C ++ / CLI类

我有一个’C ++ / CLI’程序集,它实现了某些类。 我们假设该类是’SomeType’。

现在,在’C#’开发的应用程序中,执行以下操作 –

while(!Console.KeyAvailable) { using(SomeType type = new SomeType()) { type.doSomething(); //do something } } 

它会有任何后果,如内存泄漏等在任何情况下,如果有未处理的exception或任何此类情况?

我读到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; } } 

try / finally是使代码exception安全的原因,如果ReadLine()抛出exception,则仍然处理StreamReader对象并保证释放文件上的锁定。 这是使用using语句时C#编译器自动发出的代码。 还要注意使用delete运算符,它实际上调用了StreamReader :: Dispose()方法。 编译器不会让你写reader->Dispose() ,使用运算符是必需的。

现在是C ++ / CLI编译器支持的使用版本。 您可以通过模拟本机C ++编译器处理在堆栈上分配的C ++对象的方式来调用堆栈语义。 像这样:

 String^ ReadTopLineFromFile(String^ path) { StreamReader reader(path); return reader.ReadLine(); } // <== disposed here 

请注意变量名称上缺少的^ hat,通常在存储引用类型引用时需要。 故意省略它是调用模式的原因。 无需显式gcnew调用,编译器会自动发出它。 另请注意,您现在不再使用->取消引用对象.

C ++ / CLI编译器自动生成try / finally块以及delete操作符调用。 哪个是在示波器块的右括号中发出的。 就像本机C ++编译器一样。 虽然看起来托管对象是在堆栈上分配的,但这只是一种语法错觉,它仍然在GC堆上。

语法当然是非常不同的,唯一真正的挂起function。 知道何时使用^ hat以及何时依赖堆栈语义是需要学习的东西,需要一段时间。