Разработчик приложений, решивший воспользоваться услугами Visual Studio.Net 7.0, получает в свое распоряжение достаточно много новых технологий и инструментов, которые позволяют ему быстро и эффективно создавать обычные Windows-приложения, которые теперь принято называть настольными — desktop applications, а также web-приложения и web-услуги (Web Services). Компания Microsoft добавила в арсенал программиста новый язык С# (произносится «Си шарп»), который, как обещают специалисты, способен в несколько раз ускорить цикл разработки сложных проектов.
Главной новостью, которая должна привлечь ваше внимание, является то, что Visual C++, Visual Basic и С# используют одну и ту же среду разработки IDE (Integrated Development Environment), что дает возможность создавать комплексные проекты с использованием разных языков (mixed-language solutions). Многоязыковая среда разработки .Net (.Net Framework) представляет собой сумму трех составляющих:
- общая для рассмотренного набора языков библиотека времени исполнения (Common Language Runtime);
- унифицированная библиотека классов разработчика (Unified Programming Classes);
- модель разработки web-приложений (Active Server Pages.Net).
Первая составляющая — библиотека времени исполнения (Common Language Runtime, сокращенно CLR), функционирует как на этапе выполнения, так и на этапе разработки. Во время выполнения кода она следит за динамикой многопотоковых приложений, обеспечивает взаимосвязь процессов, поддерживает их безопасность, автоматизирует процедуры выделения и освобождения памяти. На этапе разработки CLR автоматизирует типовые задачи, решаемые программистом, значительно упрощая использование новых технологий. Особо отмечаются преимущества, получаемые при создании компонентов стандарта COM (Component Object Model, сокращенно COM — Модель многокомпонентных объектов).
Вторая составляющая (Unified Programming Classes) предоставляет разработчику унифицированную, объектно-ориентированную, расширяемую библиотеку классов, которая совместно с другими ресурсами является частью программируемого интерфейса приложений API (Application Programming Interface). Она объединяет элементы MFC (Microsoft Foundation Classes), WFC (Windows Foundation Classes) и часть API, используемую Visual Basic.
Третья составляющая (ASP.Net) представляет собой надстройку на.д классами, которая дает возможность пользоваться объектно-ориентированной технологией при разработке типовых элементов HTML-интерфейса. Фактически выполняемые на стороне сервера, эти элементы проецируют функции пользовательского интерфейса в виде HTML-кода. Однако при разработке сервера имеется возможность использовать мощный аппарат, предоставляемый объектной моделью программирования. Результат — резкое упрощение процесса построения web-приложений. В дополнение к этому ASP.Net поддерживает достаточно новую концепцию или модель разработки программ. Вы, наверное, слышали о ней, как о технологии «тонкого» клиента. Основная суть этой модели — предоставление кода пользователю не в виде инсталлируемого продукта, а в виде временной услуги (service).
Код, который создан на основе среды разработки .Net Framework, носит название управляемого кода {managed code) в отличие от обычного, неуправляемого кода (unmanaged code). В режиме .Net компиляторы рассмотренных языков производят метаданные (metadata), которые сопровождают сам код. Это означает, что они генерируют дополнительную информацию, описывающую типы данных, объекты и ссылки. Библиотека времени исполнения (Common Language Runtime) использует метаданные для поиска и загрузки объектов, запуска функций, передачи параметров, размещения объектов в памяти.
Важной функцией, которую выполняет библиотека времени исполнения, является автоматическое освобождение памяти, занимаемой объектами, которые более не используются. Это нововведение призвано повысить надежность как отдельных компонентов, так и всего разрабатываемого приложения. Данные, время жизни которых управляется таким образом, называются управляемыми данными (managed data). Если ваш код является управляемым (managed code), то вы можете пользоваться управляемыми данными, но можете и не использовать их. Более того, вы можете и не знать, являются ли ваши данные управляемыми.
Общая библиотека времени исполнения (CLR) упрощает создание приложений и их составляющих, которые разработаны на разных языках и настроены (target) на использование CLR. Эти модули могут быть интегрированы в одном проекте и взаимодействовать между собой так, как будто они были созданы на одном языке. Например, вы можете декларировать класс, а затем создать производный от него класс уже на другом языке. Можно и просто пользоваться методами класса в рамках модуля, написанного на другом языке. Такая интеграция стала возможной потому, что компиляторы и инструменты разных языков пользуются общей системой типов, определенной в CLR, а также новыми правилами игры, принятыми при ее разработке.
Так называется множество расширений языка C++. Они были введены с целью помочь разрабатывать приложения, ориентированные на платформу Microsoft.Net. Традиционный (unmanaged) код C++ и управляемый код (managed) могут одновременно присутствовать в одном приложении, не мешая друг другу. Для того чтобы получить быстрое представление об этой технологии, рассмотрим пример. Вы начинаете со стартовой заготовки Visual C++ Projects, скроенной по шаблону Managed C++ Application, задав имя проекту (например, Man), и получаете два СРР-
файла: Мап.срр и Assemblylnfo.cpp. Первый файл представляет собой заготовку вашей программы консольного типа:
//=== Импортирует метаданные в программу, использующую
//=== Managed Extensions for C++
#using <mscorlib.dll>
// Стало доступным пространство имен System, которое
// содержит описания фундаментальных классов, атрибутов,
// интерфейсов и событий
using namespace System;
int main (void)
{
// Console — это класс, который обеспечивает стандартные
// операции ввода-вывода в окно консольного типа
Console::WriteLine("Hello World");
return 0;
}
Второй файл содержит атрибуты настройки сборочной информации (assembly metadata). Коды этого файла нет смысла рассматривать, так как они носят сугубо служебный характер. Вы можете запустить программу на выполнение (Ctrl+F5) и увидеть традиционное приветствие в окне консольного типа. Теперь покажем, как можно создать управляемый динамический массив. Вставьте директиву finclude и отредактируйте код главной функции:
void main()
{
// Описатель _gс декларирует garbage-collected object,
// то есть объект, за памятью которого будет следить CLR
int managed _gc[] = new int _gc[rand()%100 + 1);
//==== Обычный динамический массив
int *unmanaged = new int[rand()%100 + 1];
//==== Мы можем задавать вопросы объекту managed
Console::WriteLine (managed->Count);
Console::WriteLine (managed->Rank);
//==== Мы не можем задавать вопросы объекту unmanaged
}
Запустите проект и убедитесь в том, что в окне выведены два числа, 42 и 1. Первое число является случайно выбранным размером массива (managed), а второе — рангом массива, то есть его размерностью (одномерный массив). Для того чтобы чуть-чуть глубже проникнуть в тайны управляемого кода и данных, дополните тестовую программу кодами нового управляемого класса Man. Вставьте следующие коды до функции main.
Что-то от Java или Visual Basic? Нет, это — managed C++!
public _gc
class Man // Эта строка ничем не отличается от C++
{
private:
//=== String — новый мощный класс для работы с текстом
String *m_Name;
// Имя
int m_Age;
// Возраст
public:
//==== Конструкторы
Man ()
{
m_Name = S "Dummy";
m_Age = 0;
}
Man (String* n, int a)
{
m_Name = n;
m Age = a;
}
//==== Два метода доступа к закрытым данным
String* GetName()
{
return m_Name;
}
int GetAge ()
{
return m_Age;
}
};
Теперь опробуйте работу нового управляемого типа данных — объектов класса Man, в условиях управляемого кода.
void main ()
{
//=== Создаем двухмерный массив указателей
//=== на объекты класса Man
Man * men[,] = new Man *[2, 2];
//=== Как вам нравится новый (управляемый) синтаксис?
//=== Инициализируем один элемент массива
men [1,1] = new ManC'Alex Black ",54);
//===Мы можем задавать вопросы объекту men
Console: :WriteLine (men->Count) ;
Console: :WriteLine (men->Rank) ;
Console: :WriteLine (men[l, 1] ->GetName ( ) ) ;
Console: :WriteLine (men [1, 1] ->GetAge () ) ;
}
Программа выведет следующий текст:
4
2
Alex Black
54
Пока мы видим только новый синтаксис и возможность задавать вопросы динамическому массиву. Но теперь попробуйте вставить код с ошибками алгоритмического плана и запустите на выполнение.
for (int i=0; i<5; i++)
Console::WriteLine(men[i,i]->GetName());
Если вы на предложение отладить код ответите отказом, то в окне будет выведен такой текст:
Exception occurred: System.NullReferenceException:
Attempted to dereference a null object reference.
at Man.GetName() in с:\man\man.cpp:line 27
at main() in с:\man\man.cpp:line 61
Такое поведение программы в ситуации с типичной ошибкой разработчика, безусловно, следует признать более надежным. Оно даст возможность значительно сэкономить наше время в будущем. Отметьте, что если вы не хотите пользоваться услугами автоматического сборщика мусора (_gс), то не должны делать особое заявление по этому поводу.
Видимо, книгу можно было бы продолжить в том же духе и стиле, который был принят в предыдущем параграфе, но, к сожалению, время для этого еще не пришло. Во-первых, новые технологии требуют осмысления, во-вторых, бета-версия Studio.Net работает недостаточно надежно, в-третьих, документация по новым технологиям ограничена и доступна, пожалуй, только на сайте Microsoft. Поэтому мы постараемся осветить только ту часть возможностей, предоставляемых новой версией Studio.Net, которая относится к разработке настольных (desktop) приложений с использованием Visual C++ 7.0. Указанную область нельзя назвать узкой, так как она объединяет достаточно большое количество типов разрабатываемых приложений:
- приложения на основе MFC (Microsoft Foundation Classes);
- DLL СОМ-серверы на основе ATL;
- приложения с использованием библиотеки OpenGL;
- приложения, использующие динамические структуры данных и алгоритмы STL.
Вы узнаете, как управлять координатными пространствами Windows, как осуществлять взаимодействие нескольких представлений одного документа, как добиваться эффективности и реалистичности изображений OpenGL, как использовать
Shell API для управления файловым деревом, как разрабатывать СОМ-серверы и СОМ-контейнеры, как синхронизировать множество элементов управления в рамках диалога, как создавать свои собственные нестандартные окна, как использовать контейнеры и алгоритмы стандартной библиотеки C++ (STL), как строить графики функций в трехмерном пространстве и, наконец, как решать простейшие краевые задачи с демонстрацией результатов в виде аккуратных графиков. Кроме того, в последней главе вы найдете информацию об архитектуре Windows, с точки зрения разработчика программного обеспечения.
При изложении материала я не стараюсь подробно рассматривать все технические детали использования какого-либо класса, функции или типа данных, так как, на мой взгляд, нецелесообразно ставить себе задачу запоминать детали. Во-первых, их очень много даже в рамках одной технологии, во-вторых, MSDN (Microsoft Developer Network) для того и существует, чтобы при необходимости быстро прийти на помощь, в-третьих, я верю в принцип: чем чаще используете, тем вероятней, что запомните. Вместо этого ставится задача показать, какие преимущества вы получаете, используя новую сущность или новый технологический прием, а главное, как их использовать.
Иногда, я все-таки пускаюсь в пространные описания очень мелких и, казалось бы, непринципиальных деталей, но это делается обычно только после того, как сам потратил в логической ловушке много времени и нервов, ища из нее выход. Жизнь программиста полна ловушек, которые обычно он сам себе и расставляет, что-то недоговаривая, оставляя на потом или просто проявляя лень. Здесь вспоминается поговорка, которую любил повторять на лекциях по математике профессор И. С. Серебрянский в Санкт-Петербургском Политехническом институте: «Математики — это умные лентяи». Думаю, что многие программисты тоже болеют этим недугом, что позволяет им создавать эффективные, краткие, изящные алгоритмы и программы.
Язык C++ служит благодатной почвой для произрастания нестандартных, сложных, порой замысловатых, логических конструкций и неожиданных решений. Новые технологии разработки приложений, а также категории API-функций, довольно проворно разрабатываемые компанией Microsoft, дают пищу фантазии программиста и делают его жизнь еще более беспокойной, разнообразной и от этого более интересной.