Шаг 79.
Microsoft Visual C++ 2010. Язык С/С++.
Классы, структуры и массивы в среде CLR. Классы и структуры

    На этом шаге мы рассмотрим структуры 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++.




Предыдущий шаг Содержание Следующий шаг