Класс System::Array (Система::Массив)
В отличие от массивов в обычном C++, которые являются простым типом указателя, управляемые массивы являются полноценными управляемыми объектами, расположенными в динамически распределяемой области. System::Array (Система::Массив) – абстрактный класс, являющийся базовым для всех управляемых массивов. Для определения неуправляемых массивов можно использовать синтаксис обычного C++; для определения же управляемых массивов следует использовать либо ключевое слово _gс (сборщик мусора), либо указывать, что элементы массива относятся к управляемому типу. Далее приведены примеры определения массивов. Ключевое слово _gс (сборщик мусора) и управляемые типы подробнее рассмотрены ниже.
Обратите внимание на две закомментированные строки, в которых при определении массива задается его величина. Величину массива можно задавать при определении неуправляемого (располагаемого в стеке) массива, но не при определении управляемого массива (располагаемого в динамически распределяемой области). Причина в том, что, подобно всем остальным управляемым типам, управляемый массив располагается в динамически распределяемой области, а не в стеке.
//ArraySyntax.срр fusing <mscorlib.dll> using namespace System; // использовать пространство имен Система; ttpragma warning(disable: 4101) // уничтожить предупреждение о переменной, на которую нет ссылки: // предупреждение (отключить: 4101) void main(void) { // традиционный синтаксис неуправляемого массива int *pintUnManagedArrayOnHeap = new int [5]; int intUnManagedArray[5]; // нет ошибки для неуправляемого // массива // синтаксис управляемого массива, // используется ключевое слово _gс (сборщик мусора) int intManagedArrayOnHeap _gс[] = new int _gс[5]; //int intManagedArray _gc[5]; // ошибка для управляемого // массива // синтаксис управляемого массива, используется // управляемый тип элемента String *strManagedArrayOnHeap[] = new String* [5]; // Строка //String *strManagedArray[5]; // ошибка для управляемого // массива }
Управляемые массивы имеют некоторые дополнительные, по сравнению с неуправляемыми массивами, свойства и ограничения.
- Управляемый массив можно определить только в управляемой динамически распределяемой области памяти. Его нельзя поместить вне кучи (т.е. он не может быть расположен в стеке).
- Описание управляемого массива не должно содержать размер массива, так как это предполагало бы его размещение вне динамически распределяемой области памяти. Вместо этого размер массива указывается при использовании оператора new (создать), создающего объект-массив, содержащийся в управляемой динамически распределяемой области памяти.
- Все управляемые массивы являются потомками класса System::Array (Система::Массив), так что методы этого класса, как, например, Copy (Копировать), GetLength и GetType, также как и методы класса System::Object (Система::Объект), наподобие ToString и Equals (Равняется), могут использоваться в любом управляемом массиве.
- При попытке доступа к элементу управляемого массива производится проверка принадлежности к диапазону, т.е. контроль границ. Одна из самых распространенных ошибок – обращение к несуществующему объекту по адресу, указывающему за пределы массива. При попытке обратиться к элементу, номер которого не попадает в диапазон индексов элементов, возникает исключение IndexOutOfRangeException.
Следующий пример показывает, как можно использовать обработчик исключений при попытке доступа к несуществующему элементу управляемого массива. Обратите внимание, что массив содержит пять элементов, а в цикле производится попытка установить значение шестого. Программа в обычном C++ выполнила бы такое действие, изменив содержимое памяти за пределами массива. Никто не скажет точно, чем это могло бы закончиться. При проверке корректности адреса выполняются два действия: во-первых, предотвращается изменение содержимого памяти за пределами массива; во-вторых, программе сообщается, что возникла подобная ситуация, тем самым давая возможность исправить ошибку еще на стадии тестирования.