C++堆栈语义对于引用类型
使用 new 运算符,在 Visual C++ 2005 之前,引用类型的实例只能创建,创建在垃圾回收堆上的对象。 但是,现在可以创建引用类型的实例使用您将使用创建本机类型实例在堆栈的语法相同。 因此,不需要使用 ref new、gcnew(C++ 组件扩展) 创建引用类型的对象。 此外,当对象超出范围时,编译器会调用该对象的析构函数。
备注
使用堆栈语义时,将创建引用类型的实例,编译器在内部创建在垃圾回收堆的实例 (使用 gcnew)。
当该签名或在元数据函数返回类型包括通过值传递的引用类型的实例,将函数标记为需要进行特殊处理 (与 modreq)。 此特殊处理由 Visual C++ 客户端仅当前提供;其他语言当前不支持使用的函数或使用的数据引用在堆栈语义创建的类型。
一个原因使用 gcnew (动态分配) 而不是堆栈语义是,如果该类型没有析构函数。 此外,除了 Visual C++ 外,因此,如果希望的功能由语言使用使用引用在堆栈语义创建的类型在函数签名是不可能的。
编译器不会为引用类型生成复制构造函数。 因此,因此,如果您定义了一个由值引用输入该签名的函数,必须定义引用类型的复制构造函数。 引用类型的复制构造函数具有以下形式的签名:R(R%){}。
编译器不会生成引用类型的默认值赋值运算符。 赋值运算符允许您创建对象使用堆栈语义和初始化它使用堆栈语义创建的现有对象。 引用类型的赋值运算符具有以下形式的签名:void operator=( R% ){}){}。
如果您的类型的析构函数释放关键资源,并且要使用堆栈语义对于引用类型,则无需显式调用析构函数 (或调用 delete)。 有关析构函数的更多信息引用类型,请参见 Visual C++ 中的析构函数和终结器。
编译器生成的赋值运算符将遵循通常标准 C++ 规则与下面添加:
类型是句柄引用类型的非静态数据成员将为卷影复制的 (象类型是指针) 的非静态数据成员。
类型是值类型的非静态数据成员将为卷影复制的。
类型是引用类型实例的所有非静态数据成员将调用。引用类型的复制构造函数。
编译器还提供 % 一元运算符转换使用堆栈语义创建的引用类型的实例转换为基础句柄类型。
以下引用类型不能与堆栈语义的方法:
示例
描述
下面的代码示例演示如何声明实例引用带有堆栈语义的类型,赋值运算符和复制构造函数如何工作,并且,如何初始化跟踪引用的引用使用堆栈语义创建的类型。
代码
// stack_semantics_for_reference_types.cpp
// compile with: /clr
ref class R {
public:
int i;
R(){}
// assignment operator
void operator=(R% r) {
i = r.i;
}
// copy constructor
R(R% r) : i(r.i) {}
};
void Test(R r) {} // requires copy constructor
int main() {
R r1;
r1.i = 98;
R r2(r1); // requires copy constructor
System::Console::WriteLine(r1.i);
System::Console::WriteLine(r2.i);
// use % unary operator to convert instance using stack semantics
// to its underlying handle
R ^ r3 = %r1;
System::Console::WriteLine(r3->i);
Test(r1);
R r4;
R r5;
r5.i = 13;
r4 = r5; // requires a user-defined assignment operator
System::Console::WriteLine(r4.i);
// initialize tracking reference
R % r6 = r4;
System::Console::WriteLine(r6.i);
}
Output
98
98
98
13
13