“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类?

“using"关键字用于赋值新的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,什么时候依赖堆栈语义是需要学习的东西,需要一些时间。