Семантика стека 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

См. также

Ссылки

Классы и структуры (расширения компонентов C++)