На этом шаге мы рассмотрим структуры native и managed.
Наряду с обычными классами и структурами (их еще называют native-классы и native-структуры), существуют классы и структуры
для работы в среде Common Language Runtime (CLR, Общеязыковая среда выполнения) (их еще называют managed-классы и
managed-структуры). Эти конструкции будут располагаться в выделенной средой CLR памяти и поэтому приложения с применением
этого типа должны компилироваться с ключом /clr. Напомним, что в версии среды VC++ 2010 консольные приложения строятся по
шаблону сразу с ключом /clr.
Приложения типа Windows Form этому условию удовлетворяют (мы их рассмотрим позже). Няпомним также, что объекты, попадающие в память
под управлением CLR, требуют в программе специального выделения памяти, так как они должны попасть на самом деле в динамическую
память. Мы уже знаем, что указатели на такую управляемую память обозначаются символом "^". Выделяют такую память с помощью утилиты
gcnew.
Структуры и классы для работы в режиме CLR могут быть ссылочного типа (перед именем класса или структуры стоит квалификатор ref)
и типа значения (перед именем класса или структуры стоит квалификатор value). В объявлении такой конструкиции первым квалификатором
идет квалификатор доступа к данной конструкции. Для класса по умолчанию идет квалификат private, а для структуры - public, что
также имеет место и для эквивалентов этих конструкций в режиме native (это - для предыдущих версий среды). В чем смысл этих конструкций?
Например, возьмем классы:
ref class MyClass { public: int m_i; }; value class MyClassV { public: int m_i; };
Это обычные классы, только атрибут ref указывает, что его класс надо размещать в управляемой куче.
Например:
MyClass ^mc = gcnew MyClass();
Если же попробовать его разместить в native-куче, то компилятор выдаст ошибку. А для класса с атрибутом value компилятор
разрешает это делать, т. е. оператор:
MyClassV *vv = new MyClassV();
срабатывает. Пример:
void main() { MyClass ^mc = gcnew MyClass();//идет //MyClass *mc=new MyClass();//не идет mc->m_i=111; //присвоили значение члену класса int mci = mc->m_i; //достали значение из класса //MyClassV ^vv = gcnew MyClassV(); //идет MyClassV *vv = new MyClassV(); //идет vv->m_i = 222; int mv = vv->m_i; Console::WriteLine("mci = " + mci + " mv= " + mv); delete vv; Console::ReadLine(); //задержка }
Архив проекта можно взять здесь.
Результат работы приложения:
Рис.1. Результат работы приложения
Оказывается, что можно ссылаться из managed-типа на native-тип. Например, функция в managed-типе (классе или структуре)
может принимать native-параметр (например, struct). При этом если managed-тип и функция имеют атрибут доступа public,
то и native-тип должен иметь атрибут public.
Например:
// 79_2.cpp: главный файл проекта. #include "stdafx.h" using namespace System; //native-тип public struct N { int i; }; public ref struct R //managed-тип { // функция, у которой параметр nn имеет native-тип N int f(N nn) { nn.i++; return nn.i; } }; void main() { R ^r = gcnew R; N n; n.i = 333; int ni = r->f(n); Console::WriteLine("ni=" + ni); Console::ReadLine(); }
Архив проекта можно взять здесь.
Результат работы приложения:
Рис.2. Результат работы приложения
На следующем шаге мы рассмотрим массивы в C++.