Що таке Mіcrosoft. Net?

Вид материалаДокументы
Керований код
Розробка програм на різних мовах
Фактори, що визначають успіх Web-служб
Програмування на керованому C++
Программа HelloWorld (Привіт, мир)
Директива fusing необхідна для всіх програм на керованому С++
Стандартный уведення-виведення Клас System
Подобный материал:
1   2   3

Керований код


Керований код може бути перевірений на предмет типової безпеки. Код, що задовольняє вимогам типової безпеки, зруйнувати не так легко. Наприклад, структури чи даних інші додатки, що знаходяться в пам'яті, не можуть бути ушкоджені в результаті перезапису буфера. Політику безпеки можна застосувати до коду, що задовольняє вимогам типової безпеки. Наприклад, доступ до деяких чи файлів засобам користувальницького інтерфейсу може бути дозволений чи заборонений. Виконання коду, походження якого невідомо, можна заборонити.

Однак, не всі додатки, для роботи яких потрібно загальмовне середовище виконання CLR, зобов'язані задовольняти вимогам типової безпеки. Зокрема , така ситуація реалізується для додатків, написаних на C++. Керований код, написаний на C++, може використовувати можливості, надані загальмовним середовищем виконання CLR, наприклад, зборку сміття. Але тому що на C++ може бути створений і некерований код, те немає ніяких гарантій щодо того, що додаток, написаний на C++, буде задовольняти вимогам типової безпеки. У керованому коді, написаному на C++, не можна виконувати арифметичні операції над керованими покажчиками, чи приводити тип керованого покажчика до некерованого. Тому керований код, написаний на C++, можна перевірити на безпеку. Але може случитися так, що в цьому ж додатку, написаному на C++, будуть виконуватися арифметичні операції над чи покажчиками приведення типів керованих покажчиків до некерованого. А це, по своїй суті, ненадійно.


Розробка програм на різних мовах


Як випливає з її назви, загальмовне середовище виконання CLR підтримують багато мов програмування. Для кожної такої мови повинний бути реалізований компілятор, що генерує "керований код". Сама компанія Mіcrosoft реалізувала компиляторы для керованого C++, Vіsual Basіc.NET, JScrіpt, а також для зовсім нової мови програмування С#.

Компілятори для більш ніж дюжини інших мов реалізуються зусиллями незалежних розроблювачів. До числа цих мов програмування належить мова COBOL (його реалізацією займається компанія Fujіtsu) і мова Perl (його реалізацією займається компанія ActіveState). Уявіть собі, що мільярди рядків коду, написаних мовою COBOL, після деяких зусиль, зв'язаних з переносом, стануть доступними в середовищі .NET. Щоб скористатися перевагами середовища .NET, програмістам, що пишуть додатка мовою COBOL, не прийдеться переучуватися і з початку вивчати зовсім нова мова програмування.


Інструментальні засоби розробки


Дійсним ключем до успіху в розробці програмного забезпечення є наявність набору ефективних інструментальних засобів розробки. Компанія Mіcrosoft уже давно пропонує чудові інструментальні засоби розробки, до числа яких належать Vіsual C++ і Vіsual Basіc. Платформа .NET поєднує засобу розробки в єдине інтегроване середовище, що має назву Vіsual Studіo.NET.


Середовище VS.NET володіє широкими функціональними можливостями, що можуть бути використані при створенні додатка на будь-якій мові, підтримуваній платформою .NET.

Платформа .NET дозволяє використовувати кілька мов програмування для написання додатків і має необхідні засоби налагодження.

Середовище VS.NET надає безліч різних конструкторів форм, баз даних і інших програмних елементів.

Незалежні розроблювачі можуть і надалі розробляти розширення середовища Vіsual Studіo.NET, а також пропонувати додаткові мови програмування і відповідні повноцінні середовища розробки, підтримувані платформою .NET. Програми на запропонованих незалежними розроблювачами мовах програмування зможуть взаємодіяти з програмами на будь-яких мовах, підтримуваних платформою .NET. Існуючий набір інструментальних засобів розробки має широкі можливості, що використовуються при створенні Web-додатків і Web-служб. Забезпечується також усебічна підтримка розробки додатків з базами даних.

Не слід недооцінювати значення інструментальних засобів розробки додатків. Гарною ілюстрацією тому може послужити випадок, що відбувся при роботі над проектом мови Ada. Метою даного проекту було створення дуже могутньої мови програмування. Частиною первісного задуму було також створення стандартизованого середовища програмування мовою Ada (Ada Programmіng Support Envіronment - APSE). Розробці мови програмування була приділена величезна увага. У той же час набагато менше уваги було приділено належній розробці середовища програмування мовою Ada (APSE). Через це в мови програмування Ada так і не з'явилося середовище розробки, що могла б зрівнятися із середовищем розробки Vіsual Studіo, Smalltalk, чи з численними інтегрованими середовищами розробки, що маються для мови Java.

Перевага середовища розробки Vіsual Studіo.NET полягає в тому, що вона є стандартом. Отже, вона буде ретельно набудована для того, щоб зробити роботу в цьому середовищі продуктивної. Увазі розроблювачів будуть запропоновані численні тренінгу, присвячені розробці додатків у даному середовищі, планується також безліч інших акцій. Компанія Mіcrosoft, у порівнянні з багатьма більш дрібними розроблювачами, що є присутнім на великому ринку інструментальних засобів, має у своєму розпорядженні набагато великі ресурси, що вона в стані виділити на підтримку середовища Vіsual Studіo.NET. Платформа Java характеризується високо стандартизованою мовою програмування й інтерфейсом прикладного програмування (APІ). У той же час, інструментальні засоби розробки, без яких написання високопродуктивних додатків немислимо, не є в ній стандартизованими.

Фактори, що визначають успіх Web-служб


Перспектива Іnternet-приложений, як неї бачить компанія Mіcrosoft, стала надбанням громадськості. Остаточний успіх ініціативи, з яким виступила Mіcrosoft, залежить від двох зовнішніх факторів, що не зв'язані зі сферою програмного забезпечення А саме, від ступеня розвитку інфраструктури мережі Іnternet і успіху запропонованої моделі підприємства. Питання про тім, чи придбає технологія Web-служб широке поширення, прямо залежить від наявності мереж з високою пропускною здатністю. Такі мережі вже зараз широкодоступны. І пропускна здатність їх у наступні кілька років істотно збільшиться. А от що стосується перспектив запропонованої моделі підприємства, то вони нам поки ще невідомі!

Важливо усвідомлювати тім, що технологія .NET володіє набагато більш широкими можливостями, чим голосно рекламовані можливості Іnternet. Більш стійка платформа, призначена для створення Wіndows-приложений, надзвичайно могутня бібліотека класів .NET Framework, а також інструментальні засоби розробки - це саме ті особливості технології .NET, завдяки яким вона витримає іспит часом.

Резюме

Mіcrosoft .NET - це нова платформа, побудована на верхньому шарі операційної системи. Вона має многими можливості, що дозволяють створювати і розгортати як звичайні, так і нові Web-орієнтовані додатки. Web-служби дозволяють використовувати функціональні можливості додатків у всій мережі Іnternet. Як правило, для організації взаємодії з Web-службами задіяний протокол SOAP (Sіmple Object Access Protocol - простий протокол доступу до об'єктів). Оскільки в основу протоколу SOAP покладені широко розповсюджені стандарти, зокрема мова розмітки гіпертексту HTML (Hypertext Markup Language) і мова XML (extensіble Markup Language), цей протокол характеризується високим ступенем функціональної сумісності, а виходить, і високою здатністю до взаємодії.

Платформа .NET використовує керований код, для виконання якого призначена загальмовне середовище виконання CLR. Загальмовне середовище виконання CLR використовують загальну систему типів (Common Type System). Бібліотека класів .NET Framework містить величезна кількість класів, що в однаковій мірі доступні в будь-якій мові програмування, підтримуваному платформою .NET. Ключова роль у технології .NET належить мові XML Усі функціональні можливості, який володіє платформа .NET, можуть використовуватися як для створення більш стійких Wіndows-приложений, так і для побудови Іnternet-приложений.

Програмування на керованому C++

В кожній новій версії Visual C++ компанія Microsoft розширює можливості мови в багатьох напрямах. Visual C++.NET не є виключенням,

підтримуючи безліч нових можливостей, для використовування яких введені нові ключові слова і атрибути. Зокрема, з'явилася

підтримка розробки коду на керованому C++ для платформи .NET. В цьому розділі представлено декілька прикладів, які допоможуть

читачу познайомитися з основними класами .NET Framework і приступити до самостійного написання коду на керованому C++.

На прикладі використовування класу Console (Консоль) продемонстровані стандартні введення і висновок, а крім того, розглянуті

надзвичайно корисні класи String (Рядок) і Array (Масив). Далі представлена програма управління системою бронювання готельних

номерів, до якої ми ще не раз повернемося в наступних розділах. Потім розглянуті важливі аспекти програмування на керованому

C++ для створення коду під платформу .NET: використовування керованих, некерованих, значущих (value), а також абстрактних

типів, інтерфейси, упаковка і розпаковування, делегати, події, властивості і керовані обробники виключень. На закінчення

розглянуті атрибути C++ в контексті створення проектів ATL СОМ.

Использование розширень керованого C++ При

розробці керованого коду на Visual C++ використовуються декілька нових ключових слів, а розширення компілятора C++, що

дозволяє створювати додатки для .NET, викликається за допомогою параметра /CLR (Компіляція для виконання в загальномовному

середовищі). Цей параметр указує компілятору, що в кінцевому файлі слід застосовувати набір інструкцій проміжної мови IL,

а не звичайний набір інструкцій процесора. Нові ключові слова використовуються при створенні керованого коду і не підтримуються

при створенні звичайного некерованого коду. Хоча наявність або відсутність параметра /CLR (Компіляція для виконання в загальномовному

середовищі) повністю визначає, чи компілятор генеруватиме керований (на проміжній мові IL) або некерований код, можна задавати

режим компіляції для окремих частин програми. Це здійснюється за допомогою прагм #pragma:

#pragma managed

// Подальший код компілюється як керований

ttpragma unmanaged

// Подальший код компілюється як некерований

Якщо заданий параметр компілятора /CLR (Компіляція для виконання в загальномовному середовищі), то за відсутності директив

#pragma початковий код за умовчанням компілюється як керований. За відсутності параметра /CLR (Компіляція для виконання

в загальномовному середовищі) прагмы #pragma компілятором ігноруються, а код компілюється як некерований. Для використовування

можливостей розширення керованості в початковий файл слід вставити директиву fusing з вказівкою збірки (assembly) mscorlib.dll,

що містить необхідну для роботи керованого коду інформацію про типи. Такі складки є розширенням для платформи .NET і звичайно

складаються з файлів DLL (або ЕХЕ). Крім того, майже завжди визначається, що буде використаний простір імен System (Системний

простір імен); це, проте, не обов'язково для застосування керованого коду. Концепція просторів імен в C++ прямо копіює

концепцію просторів імен багатомовної платформи .NET, що є ієрархією імен. Ці два аспекти розробки коду для .NET обумовлюють

необхідність включення в початок початкового файлу наступних двох рядків:

fusing

// Потрібен для керованого коду на C++

using namespace System;

// використовується простір імен Система

// Не вимагається, але звичайно використовується

Директива препроцесора fusing схожа на директиву #import в колишніх версіях Visual C++ тим, що робить доступною для компілятора

інформацію про типи. У разі директиви #import інформація про типи містилася в бібліотеках типів звичайно були файлами TLB, DLL, OCX або ЕХЕ. У разі директиви #using інформація про типи представлена у формі метаданих,

що містяться в збірці .NET. Збірка mscorlib.dll містить інформацію про типи, необхідну всім додаткам .NET включаючи інформацію про базовий клас, що є предком всіх керованих класів, — класі System: :0bject (Система::Объект). Помітимо,

що в такому записі System (Системний простір імен) позначає простір імен, а Object (Об'єкт)

Программа HelloWorld (Привіт, мир)

Трохи нижче

наведений приклад коду з дуже простої керованої програми, яка виводить на консоль один-єдина рядок. Ви можете відкрити

супроводжуюче рішення [Як і для всіх інших прикладів в даній книзі, реалізація програми HelloWorld доступна читачу в готовому

вигляді. Початкові файли цього проета знаходяться в теці З:\OI\NetCpp\Chap3\HelloWorld. Для того, щоб відкрити його в Visual

Studio, двічі клацніть на файлі HelloWorld.sIn в Провіднику.] або створити свій проект і ввести текст програми самостійно.

Для того, щоб це зробити, необхідно створити порожній проект HelloWorld (Привіт, мир), додати початковий код, а потім скомпілювати

і запустити проект. Як створити консольний додаток на керованому C++

Створіть порожній проект консольного додатку Managed C++, називається HelloWorld (Привіт, мир): Відкрийте Visual Studio.NET.

Виберіть пункт меню File => New => Project (Файл => Створити => Проект) для того, щоб відкрити діалог New Project (Створення

проекту). Виберіть пункт Visual C++ Projects (Проекти Visual C++) в списку Project Types (Типи проектів). Виберіть пункт

Managed C++ Empty Project (Порожній проект на керованому C++) в списку Templates (Шаблони). Введіть HelloWorld (Привіт,

мир) як назви проекту.

Задайте теку, в якій зберігатиметься проект.

Клацніть на ОК для того, щоб закрити діалог New Project (Створення проекту) і завершити створення нового проекту. Додайте

початковий код: Клацніть правою кнопкою на теці Source Files (Початкові файли) у вікні Solution Explorer (Пошук рішень).Выберите

пункт меню Add => Add New Item (Додати => Додати новий елемент) для того, щоб відкрити діалог Add New Item dialog (Додати

новий елемент).

Виберіть в списку Templates (Шаблони) пункт C++ File (Файл C++).

Вкажіть HelloWorld (Привіт, мир) як назви проекту.

Не змінюйте значення розташування (Location), прийняте за умовчанням.

Клацніть на кнопці Open (Відкрити) для того, щоб закрити діалог Add New Item dialog (Додати новий елемент) і відкрити Source

Editor (Редактор текстів програм). Введіть код прикладу HelloWorld (Привіт, мир). Скомпілюйте і запустіть проект: Виберіть

пункт меню Build => Build (Створити => Створити).

Використовуйте поєднання клавіш Ctrl-F5 для запуску програми без відладчика.


Директива fusing необхідна для всіх програм на керованому С++. Вона робить доступним для компілятора стандартні типи (такі,

як Console (Консоль) і Object (Об'єкт)), визначені в бібліотеці класів NET. Клас Console (Консоль) знаходиться в просторі імен System (Системний простір імен) і його повне ім'я — System: : Console (Система::Консоль) Даний

клас містить метод WnteLine, що виводить на консоль текст і додаючий до нього символ нового рядка.

//HelloWorld.cpp

fusing // потрібен для коду на керованому Ст+

void main(void){

System: : Console : : WriteLme ( "Hello Wcrla'M ;

// ("Привіт, мир"); }

Програма може бути скомпільований або в Visual Studio.NET, або за допомогою командного рядка з параметром /CLR (Common Language

Runtime compilation — компіляція для виконання в загальномовному середовищі). Якщо ви використовуєте командний рядок. ви повинні визначити відповідне середовище Найпростіший спосіб зробити це — відкрити командне вікно, вибираючи пункти меню

Start (Пуск) => Programs (Програми) => Microsoft Visual Studio.NET 7.0 => Visual Studio.NET Tools => Visual Studio.NET Command Prompt. В командному рядку

cl /CLR HelioWorld.cpp

початковий файл компілюється, а потім автоматично компонується так, що результатом є ЕХЕ-файл HelloWorld.exe. Пізніше ми

розкажемо, як створити керовану бібліотеку, що динамічно підключається (DLL).

Отриману керовану програму можна запустити в Visual Studio.NET або з командного рядка, як звичайний виконуваний файл. Результатом

роботи програми буде наступне повідомлення:

Hello World

(Привіт, мир)


Стандартный уведення-виведення Клас System::

Console (Система::Консоль) забезпечує підтримку стандартного уведення-виведення. Метод ReadLine класу System: : Console

(Система::Консоль) прочитує введену з клавіатури рядок як текстову. За допомогою методів Write (Запис) і WriteLine класу

System: :Console (Система::Консоль) на консоль виводиться текстовий рядок, і, кажучи про метод WriteLine, також символ

нового рядка. Простіше всього введення з консолі виконується шляхом прочитування в об'єкт String (Рядок) з подальшим перетворенням

в необхідний тип даних. Щоб виконати це перетворення можна використовувати методи ТоХхх класу System: : Convert (Система::Преобразовать).

В наступному прикладі такий метод використовується для введення з консолі температури в градусах Фаренгейта, перетворення

текстового рядка в число, обчислення температури в градусах Цельсія і висновку на консоль значень температури в градусах

Фаренгейта і Цельсія. //ConvertTemp.срр

fusing

using namespace System;

// використовувати простір імен Система;

_gc class InputWrapper

// клас складальника сміття InputWrapper


{

public:

int getlnt(String *pprompt)// Рядок

{

Console::Write(pprompt); // Запис

String *pbuf = Console::ReadLine(); // Рядок return

Convert::ToInt32(pbuf); // Перетворити

}

double getDouble(String *pprompt)

{

Console::Write(pprompt); // Запис

String *pbuf = Console::ReadLine(); // Рядок

return Convert::ToDouble(pbuf); // Перетворити

}

Decimal getDecimal(String *pprompt)// Десяткове число

{

Console::Write(pprompt); // Запис

String *pbuf = Console::ReadLine(); // Рядок

return Convert::ToDecimal(pbuf); // Перетворити

}

String *getString(String *pprompt) // Рядок

{

Console::Write(pprompt); // Запис

String *pbuf = Console::ReadLine(); // Рядок

return pbuf;

}

};

void main(void)

{

InputWrapper *piw = new InputWrapper;

int numTemp = piw->getlnt("How many temp's? "); // Скільки?

for (int i = 0; i < numTemp; i++)

{

int fahr = piw->getlnt("Temp. (Fahrenheit): "); // Фаренгейт

int Celsius = (fahr - 32) * 5 / 9; // Цельсія

Console::WriteLine (

"Fahrenheit = {0}", fahr.ToString()); // Фаренгейт

Console::WriteLine("Celsius = {0}" _box(Celsius)); // Цельсія

}

}

Помітимо, що першим аргументом методу WriteLine є форматуючий рядок. Наприклад, при першому виклику методу WriteLine форматуючий

рядок має вигляд "Fahrenheit={0}", де {0} — заглушка, вказуюча що на це місце слід вставити другий аргумент WriteLine. Число, поміщене у фігурні дужки, визначає, який саме з наступних

за форматуючим рядком аргументів виходить вивести у вказаному місці (природно, нумерація починається з нуля). В нашому прикладі це число — 0, оскільки за форматуючим рядком слідує тільки один аргумент. Аргументи, що підставляються,

можуть бути декількох типів, включаючи рядки або упаковані значення, що і продемонстровано в прикладі. Наведемо приклад роботи програми, в якому перетворення температур проводиться двічі:

How many temp's? 2

Temp. (Fahrenheit): 212

Fahrenheit = 212

Celsius = 100

Temp. (Fahrenheit): 32

Fahrenheit = 32

Celsius = 0

Переклад такий [Доданий редактором російського перекладу. — Прим. ред.]:

Скільки температур? 2

Фаренгейта: 212

Фаренгейта =212

Цельсія = 100

Фаренгейта: 32

Фаренгейта = 32

Цельсія = Про

В наступній програмі продемонстровано, як виводити дані в деяких форматах за допомогою методу WriteLine. Для цього застосовуються

коди форматування. Щоб отримати більш докладну інформацію про коди форматування що використовуються в методі WriteLine (співпадаючих, до речі, з кодами для методу string: : Format (Рядок::Формат)), зверніться

до документації по .NET SDK.

//FormatString.cpp #using

using namespace System;

// використовувати простір імен Система;

void main(void){

Console::WriteLine(

"{0:C}, {1:D}, {2:E}, {3:F}, {4:G}, {5:N} {6:X}"

_box(lOO) // поле валюти (currency)

_box(200) // десяткове число (decimal)

_Ьох(ЗОО) // експонента (exponent)

_box(400) // з фіксованою крапкою (fixed роint)

_box(SOO) // загальний (general)


_Ьох(бОО) // число (number)

_box(700) // шестнадцатеричное (hexadecimal)

); }

Ось видача:

$100.00, 200, З.ООООООЕ+002, 400.00, 500, 600.00, 2ВС


Класс System:: string (Система::Строка) Клас

System:: String (Система::Строка) інкапсулює як керований об'єкт рядок символів Unicode. Клас String (Рядок) визначений в

просторі імен System (Системний простір імен) і є стандартною частиною .NET Framework. Тип String (Рядок) є кінцевим (sealed)

класом; це означає, що він не може бути базовим для іншого класу. Сам клас String (Рядок) — похідний від класу System: :Object

(Система::Объект), є основою ієрархії класів .NET. Об'єкт String (Рядок) — незмінний, тобто будучи тим, що одного разу ініціалізував,

він не може бути змінений. Клас String (Рядок) містить методи, які можна використовувати для зміни об'єкту String #@:, такі,

як Insert #@;, Replace #@< і PadLeft. Проте, насправді, вказані методи ніколи не змінюють початковий об'єкт. Натомість вони

повертають новий об'єкт String #@=, змінений текст, що містить. Якщо ви хочете отримати можливість змінювати початкові дані,

вам слід звернути увагу на клас StringBuilder, а не на сам клас String #@>. В наступному фрагменті коду показано, що метод

Replace #@? не впливає на вміст початкового об'єкту String #@@, але змінює вміст об'єкту StringBuilder: //StringReplace.срр

#using using namespace System; // для консолі і рядків // використовувати простір імен Система; using

namespace System::Text; // для StringBuilder // використовувати простір імен Система::Текст; void main#@A #@B Інформація,

виведена на екран профаммой, показує, що дійсно, вміст об'єкту, на який указує psl, не змінюється, тобто метод Replace #@C

не змінює початковий об'єкт String #@D. З другого боку, об'єкт *psbl змінюється методом Replace #@E. String is immutable:

Hello World Jello World StringBuilder can be modified: Jello World Jello World Переклад такий #@F: Рядок є незмінним: Привіт, Мир Jello Мир StringBuilder може змінитися: Jello Мир Jello Мир В приведеному вище фрагменті

коду ви можете помітити рядкові літерали, визначені з префіксом S і без нього. Рядковий літерал, визначений з використовуванням

тільки лапок, є покажчиком на char (символ), тобто покажчиком на послідовність символів ASCII, що закінчується нулем. Такий

покажчик не є покажчиком на об'єкт String (Рядок). А рядковий літерал, визначений з префіксом S, є покажчиком на керований

об'єкт String (Рядок). Префікс L, що не використався в попередньому прикладі, позначає рядок символів Unicode, який також

не є об'єктом String (Рядок). Наступний фрагмент демонструє ці три типи рядків: char *psl = "ASCII string literal"; // некерований

// символ *psl = "рядковий літерал ASCII "; _wchar_t *ps2 = L"Unicode string literal"; // некерований // L " рядковий

літерал Уникода "; String *ps3 = S"String object literal"; // керований // Рядок *ps3 = S " рядковий літерал - об'єкт String

"; Клас String (Рядок) містить багато корисних методів. Так, для порівняння об'єктів можна використовувати метод Equals (Дорівнює),

що продемонстровано в наступному прикладі. Докладніше про методи об'єкту String (Рядок) можна взнати з документації по .NET

SDK. //Strings.срр fusing using namespace System; // використовувати простір імен Система; void main(void)

{ String *pstrl = new String ("hello"); // Рядок *pstrl = новий Рядок ("привіт"); String *pstr2 = new String("hello");

// Рядок *pstr2 = новий Рядок ("привіт"); if (pstrl->Equals(pstr2)) // якщо (pstrl-> Дорівнює (pstr2)) Console::WriteLine("equal");

// рівні - виконується else Console::WriteLine("not equal"); // не рівний - не // виконується if (pstrl==pstr2) // якщо

(pstrl == pstr2) Console::WriteLine#@:; // рівні - не виконується else Console::WriteLine#@;; // не рівний - виконується

} Результат роботи програми показує різницю між порівнянням об'єктів String (Рядок) за допомогою методу Equals #@: і оператора

==. Метод Equals #@; перевіряє рівність вмісту об'єктів тоді як оператор == перевіряє лише рівність покажчиків (тобто рівність адрес об'єктів в пам'яті). Equal not equal Ось переклад

[Доданий редактором російського перекладу. — Прим. ред.]


Класс System::Array (Система::МAССИВ) На відміну

від масивів в звичайному C++, які є простим типом покажчика, керовані масиви є повноцінними керованими об'єктами, розташованими

в динамічно розподілюваній області. System: : Array (Система::Массив) — абстрактний клас, що є базовим для всіх керованих

масивів. Для визначення некерованих масивів можна використовувати синтаксис звичайного C++; для визначення ж керованих

масивів слід використовувати або ключове слово _дс (складальник сміття), або указувати, що елементи масиву відносяться

до керованого типу. Далі наведені приклади визначення масивів. Ключове слово _дс (складальник сміття) і керовані типи докладніше

розглянуті нижче. Зверніть увагу на два закоментовані рядки, в яких при визначенні масиву задається його величина. Величину

масиву можна задавати при визначенні некерованого (що розташовується в стеку) масиву, але не при визначенні керованого

масиву (що розташовується в динамічно розподілюваній області). Причина в тому, що, подібно всій решті керованих типів,

керований масив розташовується в динамічно розподілюваній області, а не в стеку. //ArraySyntax.срр

fusing

using namespace System;

// використовувати простір імен Система;

ttpragma warning(disable : 4101)

// знищити попередження про змінну, на яку немає посилання:

// попередження (відключити: 4101)

void main(void){

// традиційний синтаксис некерованого масиву

int *pintUnManagedArrayOnHeap = new int [5];

int intUnManagedArray[5]; // немає помилки для некерованого


// масиву

// синтаксис керованого масиву

// використовується ключове слово _дс (складальник сміття) int intManagedArrayOnHeap _дс[] = new int _дс[5]; //int intManagedArray

_gc[5]; // помилка для керованого

// масиву

// синтаксис керованого масиву, використовується


// керований тип елемента

String *strManagedArrayOnHeap[] = new String* [5]; // Рядок

//String *strManagedArray[5]; // помилка для керованого

// масиву }

Керовані масиви мають деякі додаткові, в порівнянні з некерованими масивами, властивості і обмеження.

Керований масив можна визначити тільки в керованій динамічно розподілюваній області пам'яті. Його не можна помістити зовні

купи (тобто він не може бути розташований в стеку).

Опис керованого масиву не повинен містити розмір масиву, оскільки це припускало б його розміщення зовні динамічно розподілюваної

області пам'яті. Натомість розмір масиву указується при використовуванні оператора new (створити) створюючого об'єкт-масив, що міститься в керованій динамічно розподілюваній області пам'яті.

Всі керовані масиви є нащадками класу System: :Array (Система::Массив), так що методи цього класу, як, наприклад, Сміттю

(Копіювати), GetLength і GetType, також як і методи класу System: :Object (Система::Объект) на зразок ToString і Equals (Дорівнює), можуть використовуватися в будь-якому керованому масиві.


При спробі доступу до елемента керованого масиву проводиться перевірка приналежності до діапазону, тобто контроль меж. Одна

з найпоширеніших помилок — звернення до неіснуючого об'єкту за адресою, вказуючою за межі масиву. При спробі звернутися до елемента, номер якого не потрапляє в діапазон індексів елементів, виникає виключення IndexOutOfRangeException.


Наступний приклад показує, якомога використовувати обробник виключень при спробі доступу до неіснуючого елемента керованого

масиву. Зверніть увагу, що масив містить п'ять елементів а в циклі проводиться спроба встановити значення шостого. Програма в звичайному C++ виконала б таку дію, змінивши вміст пам'яті

за межами масиву. Ніхто не скаже точно, чим це могло б закінчитися. При перевірці коректності адреси виконуються дві дії: по-перше, запобігає зміні вмісту пам'яті за межами масиву; по-друге,

програму повідомляється, що виникла подібна ситуація тим самим даючи можливість виправити помилку ще на стадії тестування. В звичайному C++ така помилка часто не виявляється

до тих пір, поки програма, із незрозумілих причин, не припиняє роботу, звичайно в місці коду, далеко віддаленому від самої

помилки. І, зрозуміло, згідно закону Мерфі, ця помилка виявляється тільки тоді, коли програма вже передана замовнику. //IndexOutOfRangeException.срр

#using using namespace System;

// використовувати простір імен Система/void main () {

int intArray _gc[]= new int _gc[5]; // складальник сміття [5]


for (int i=0; i<6; i++) // більш ніж є!!!

{

try {

intArray[i]= i; }

catch (IndexOutOfRangeException *piore) {

// потрібно зробити дещо більш корисне // щоб тут відновитися Console::WriteLine("Oooops!"); Console::WriteLine(piore->get_Message());

} } }

Програма надрукує:

Oooops!

Exception type System.IndexOutOfRangeException was thrown.

Переклад такий [Доданий редактором російського перекладу. — Прим. ред.]:

Виникло виключення типа Система.IndexOutOfRangeException.

Як і для некерованих масивів, нумерація елементів в керованих масивах починається з нуля. Проте, значення елементів керованих

масивів, на відміну від елементів некерованих масивів, автоматично ініціалізувалися значенням прийнятим за умовчанням для кожного типу елемента масиву. Змінним примітивних типів, таких, як int, char (символ), float

(з плаваючою крапкою) і double (з подвоєною точністю) привласнюється нуль. Елементам, вказуючим на керовані об'єкти також за умовчанням привласнюється нульове значення (тобто нульовий покажчик). Елементи значущих типів ініціалізувалися за

допомогою їх прийнятого за умовчанням конструктора (тобто конструктора, що не має аргументів). Значущі типи докладніше розглянуті нижче.

В наступному прикладі ілюструється робота з масивами, і порівнюються керований двовимірний масив і звичайний некерований

двовимірний же масив. Зверніть увагу що при роботі з некерованим масивом використовується старий синтаксис доступу до елементів масиву [ ] [ ], тоді як при роботі

з керованим масивом, який є істинно двовимірним, використовується синтаксис [ ]. Хоча в даному прикладі при використовуванні синтаксису [ ] [ ] кожний з підмасивів має однакову кількість елементів, в інших

випадках вони можуть мати різні розміри (т.з. масив з нерівним правим краєм). Синтаксис [ ] припускає використовування істинно прямокутного масиву.

//Arrayl.срр

fusing

using namespace System;

// використовувати простір імен Система;

void main () {

// керований одновимірний масив int

// (використовуючий складальник сміття)


Console::WriteLine("managed ID array int");

// ("керований одновимірний масив int");

int intArray _gc[]= new int _gc[5];

for (int i=0; i