Семантика стека C++ для ссылочных типов
До Visual C++ 2005, экземпляр ссылочного типа может быть создан с помощью оператора new, который создал объекта в куче мусора нет. Однако теперь можно создать экземпляр ссылочного типа, используя тот же синтаксис, который можно использовать для создания экземпляра собственного типа в стеке. Таким образом, нет необходимости использовать ref new, gcnew (расширения компонентов C++) для создания объекта ссылочного типа. И после выхода за границы области, компилятор вызывает деструктор объекта.
Примечания
При создании экземпляра ссылочного типа с помощью семантики стека, компилятор создает экземпляр внутренне в куче мусора нет (с помощью gcnew).
Когда сигнатура или возвращаемый тип функции будет экземпляр ссылочного типа — значение, функция будет помечена как в метаданных без специальной обработки (с modreq). Этот обработки специальных в настоящее время имеется только клиентами Visual C++; C. другие языки в настоящее время не поддерживают использование функции или данные, которые используют ссылочные типы, созданные с семантикой стека.
Одной из причин использования gcnew (динамическое выделение памяти) вместо семантики была стека, если тип не имеет деструктор. Кроме того, используя ссылочные типы, созданные с семантикой стека в сигнатурах функции не был возможна, если требуется функций использоваться языками C, отличных от 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