c++/cli ref class 和使用句柄的动态分配?
c++/cli ref class and dynamic allocation using handles?
在 .NET 版本的 C++ 中,我们可以通过以下方式声明一个 class:
ref class CoolClass
{
public:
String^ GetName()
{ return name;}
void SetName(String^ n)
{name = n;}
private:
String^ name;
}
当我们以这种方式创建 class 时,将使用 clr 的垃圾收集器在托管堆上创建和管理 class 的实例。
现在,假设我创建了 2 个动物实例 class。
Animal cat;
Animal ^dog = gcnew Animal();
这两个 classes 的操作完全相同。以一种或另一种方式创建 classes 的实例之间有什么真正重要的区别吗?它们都应该是托管代码,对吗?第一种方法似乎简单得多,并且使我不必使用“->”运算符。
第一个语法称为 stack semantics。这模拟了标准 C++ 中的堆栈分配。在离开范围时,包括引发异常时,该对象将被自动处置。这是一个很好的语法便利,但在引擎盖下,两个对象实际上都是在托管堆上实例化的。我个人只对一次性类型使用第一种语法,例如数据库连接。
至于区别,如果必须将实例传递给需要句柄类型的某个方法,则必须使用 % 一元运算符将使用堆栈语义声明的实例转换为其基础句柄类型。
在 .NET 版本的 C++ 中,我们可以通过以下方式声明一个 class:
ref class CoolClass
{
public:
String^ GetName()
{ return name;}
void SetName(String^ n)
{name = n;}
private:
String^ name;
}
当我们以这种方式创建 class 时,将使用 clr 的垃圾收集器在托管堆上创建和管理 class 的实例。
现在,假设我创建了 2 个动物实例 class。
Animal cat;
Animal ^dog = gcnew Animal();
这两个 classes 的操作完全相同。以一种或另一种方式创建 classes 的实例之间有什么真正重要的区别吗?它们都应该是托管代码,对吗?第一种方法似乎简单得多,并且使我不必使用“->”运算符。
第一个语法称为 stack semantics。这模拟了标准 C++ 中的堆栈分配。在离开范围时,包括引发异常时,该对象将被自动处置。这是一个很好的语法便利,但在引擎盖下,两个对象实际上都是在托管堆上实例化的。我个人只对一次性类型使用第一种语法,例如数据库连接。
至于区别,如果必须将实例传递给需要句柄类型的某个方法,则必须使用 % 一元运算符将使用堆栈语义声明的实例转换为其基础句柄类型。