Шаг 52.
Microsoft Visual C++ 2010. Язык С/С++.
Указатели и структуры данных. Понятие указателя (окончание)

    На этом шаге мы рассмотрим типы указателей.

    На предыдущем шаге мы разобрали понятие указателя в общем смысле. Однако в VC++ это понятие несколько расширено, что вполне естественно для развивающихся систем. Здесь рассматриваются указатели трех типов:

    Чтобы понять суть сказанного, вспомним, что ранее упоминалась среда CLR - это менеджер, который управляет исполнением кода, памятью, потоками и работой с удаленными компьютерами, при этом строго обеспечивая безопасность и создавая надежность исполнения кода.

    CLR является добавкой-расширением C++, введенной фирмой Microsoft, начиная с версии VC++ 2005. Подключение к вашему проекту этого менеджера осуществляется на этапе компиляции. Если вы посмотрите свойства вашего проекта с помощью опции Project | Properties (Проект | Свойства) и в открывшемся диалоговом окне выберете папку Configuration Properties/General (Свойства конфигурации/Общие), то в правой части окна увидите настраиваемое свойство Common Language Runtime support (Поддержка общеязыковой среды выполнения), которое имеет значение "Поддержка CLR-среды" (рисунок 1).


Рис.1. Подключение к проекту CLR

    Среда версии 2010 в режиме CLR понимает программы, использующие "родные" указатели, обозначаемые символом * (это видно из примера приведенной ниже программы), хотя эта же среда предусматривает совсем иное обозначение указателя, что мы увидим несколько позже.

    Без режима CLR, когда вы в своей программе работаете с некоторыми объектами (здесь нам приходится забегать вперед, ибо объекты - это предмет более позднего изучения, когда мы станем знакомиться с классами), вы должны сами заботиться об их размещении в памяти, выделяемой средой. Память для вашего приложения выделяется в так называемой "куче": в ней вы размещаете свои объекты, там же сами должны освобождать память, когда перестаете работать с объектом, иначе куча может переполниться и процесс выполнения приложения прервется. Это так называемая неуправляемая куча. Указатели на участки памяти в такой куче обозначаются символом * (т. е. ранее мы раcсматривали указатели для неуправляемой памяти). Вот два последних типа указателя и являются традиционными указателями C/C++ на объекты в нерегулируемом объеме памяти, выделяемой для исполнения приложения.

    Другое дело, когда включается режим CLR. Такое приложение отличается от обычного тем, что его заготовка обеспечивает подключение к приложению специального системного пространства System, содержащего объекты, размещение в памяти которых надо автоматически регулировать. Так вот: режим CLR работает уже с управляемой кучей памяти, в которой размещение объектов и ее освобождение от них происходит под управлением среды. Такой сервис входит в язык Java, где не надо делить кучу на управляемую и неуправляемую.

    Регулируемый указатель - это тип указателя, который ссылается на объекты (адреса памяти, по которым можно обращаться к объектам), расположенные в общей регулируемой куче памяти, предоставленной приложению в момент его исполнения. Для таких указателей принято специальное обозначение: вместо символа * применяется символ ^.

    Создание CLR привело к необходимости разработки аппарата преобразования переменных, относящихся к одной куче, в адреса другой кучи (переход от управляемой кучи к неуправляемой и наоборот). Этот процесс назвали маршаллизацией. Существует специальная библиотека, обеспечивающая этот процесс.

    При рассмотрении работы с компонентами так называемых форм вы увидите, что регулируемые указатели создаются в обработчиках событий компонентов и что свойства проектов, работающих с объектами, содержат автоматическое подключение при компиляции поддержки режима CLR. В среде VC++ существует специальная утилита gcnew, которая формирует экземпляр какого-то объекта, выделяя ему (экземпляру) некоторую память, и возвращает ссылку на этот экземпляр.

    Ниже приводится пример программы, результат работы которой представлен на рисунке 2. Этот пример надо рассматривать просто как демонстрацию работы с объектом "Структура", суть которой мы рассмотрим в следующих шагах.

 // PtrStruc.cpp: главный файл проекта.

#include "stdafx.h"

using namespace System;

ref struct Message
{
    System::String ^sender, ^receiver, ^data;
};

int main()
{
	Message^ M = gcnew Message;
	M->sender="Сообщение для всех";
	M->data="20.01.2019";
	Console::WriteLine(M->sender);
	Console::WriteLine(M->data);
	Console::WriteLine(L"Здравствуй, мир!");
	Console::ReadLine(); //для задержки экрана
	    
        return 0;
}
Архив проекта можно взять здесь.

    Здесь объявлена некая структура Message ссылочного (ref) типа. Элементами ее являются указатели ^sender, ^receiver, ^data на объект типа String (строковые данные). В основной функции main() для структуры Message утилитой gcnew выделяется память и возвращается указатель M типа Message на эту структуру.


Рис.2. Результат работы приложения

    Шаблон CLR, когда мы хотим использовать регулируемые указатели, предполагает подключение к тексту программы специального пространства System, содержащего классы, которые задают ссылочные типы данных и функции работы с ними. В частности функция WriteLine() (вывод на печать) принадлежит этому же пространству. А нам как раз и надо работать с такими данными.

    На следующем шаге мы рассмотрим указатели и массивы.




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