Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Медведев_С++_CLI_C#_Java_J#.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
5.17 Mб
Скачать

4.3Объявление переменных

Так же, как и в языке С, все переменные перед их использованием должны быть объявлены. В языках С++ и C++/CLI можно объявить переменную в любом месте программы перед её применением, где это необходимо. В языках Java и C# переменная может быть объявлена только в классе или в блоке.

Переменную можно объявить как в начале блока, так и перед её использованием. Объявление переменной действует до конца блока, внутри которого она была объявлена, как это показано в примере 4.3.1.

Пример 4.3.1. Объявление переменной в середине блока.

{// Начало блока

for (int i=0; i<=length; i++) // Начало действия объявления переменной i

s[i] = '\0';

} // Конец блока и конец действия объявления переменной i

4.4Операторы динамического распределения памяти new и delete

Вместо функций malloc(), calloc() и free() распределения памяти языка С в языке C++/CLI применяются более интеллектуальные операторы new, gcnew и delete, а в языках Java и C# только оператор new.

C++/CLI. Операторы new и gcnew используются для распределения памяти в куче, а оператор delete - для освобождения памяти, распределённой ранее оператором new.

Используя операторы new и gcnew, можно распределять память для одного объекта, массива объектов любого типа, в том числе типа, определённого программистом (структура, класс), вне программы в так называемой куче.

Неуправляемые данные с помощью оператора new помещаются в неуправляемую кучу, а управляемые данные с помощью оператора gcnew - в управляемую кучу.

В случае неуправляемых данных оператор new возвращает адрес начала отведённой памяти или 0 в случае неудачи. Этот адрес присваивается неуправляемому указателю. Значение, возвращаемое оператором new, не требует явного приведения к типу указателя, которому присваивается результативный адрес.

Память в неуправляемой куче, полученная по new, остаётся распределённой, пока она явно не будет освобождена оператором delete. Распределение памяти, то есть управление неуправляемой кучей, полностью лежит на совести программиста. Эта процедура ответственна - чтобы сделать программу эффективной, программист должен сам отслеживать время жизни каждого объекта и удалять объекты из кучи по мере прекращения их функционирования, применив оператор delete.

В случае управляемых данных размещение данных (объектов) в управляемой куче осуществляется специальной программой сборщиком мусора. Объекты помещаются в кучу при выполнении оператора gcnew, а удаляются сборщиком мусора. Ссылка к распределённым данным осуществляется с помощью управляемых указателей, называемых дескрипторами. Объявление дескриптора отличается от объявления (неуправляемого) указателя:

неуправляемый-тип *указатель; // указатель на данные в неупр. куче

управляемый-тип ^дескриптор; // дескриптор на данные в упр. куче

Использование указателя позволяет изменения его значения при доступе к указанным данным неуправляемой кучи, что может привести к выходам за дозволенные границы и, как результат, к аварийному завершению программы. Применение же дескриптора запрещает изменения его значения, что обеспечивает защиту данных в управляемой куче. То есть, как в языках Java и C#, опасный указатель применительно к управляемым данным заменён неизменяемой ссылкой.

Java и C#. Язык Java и C# используют оператор new при создании переменных ссылочного типа. Эти переменные-ссылки объявляются, как и обычные переменные, но они содержат ссылки на области управляемой кучи, выделяемые сборщиком мусора с помощью оператора new. Данные (объекты), размещённые в управляемой куче, становятся управляемыми данными, и они контролируются сборщиком мусора. Сборщик мусора периодически просматривает объекты, размещённые в управляемой куче, и удаляет из неё все ненужные объекты, то есть объекты, ссылки на которые обнулены. Таким образом, в языках Java и C# нет необходимости в операторе delete. Оператор delete в языках Java и C# отсутствует. Наличие сборщика мусора решило болезненную проблему, связанную с переполнением кучи - программисты часто забывали удалять размещённые в куче объекты.

Пример 4.4.1 иллюстрирует выделение и освобождение памяти для переменных и объектов для языка C++/CLI.

Пример 4.4.1. Использование операторов ncw, gcnew и delete в языке C++/CLI.

// C++/CLI

#include "stdafx.h"

class CFl // Описание неуправляемого класса

{

float fl; // Закрытая (по умолчанию) переменная fl

public: // Открыть функции

void Set(float vFI) {fl= vFI;}// Установить значение переменной fl

float Get(){return fl;} // Получить значение закрытой переменной fl

};

ref class CBool

{

bool b;

// Описание управляемого класса

// Закрытая (по умолчанию) переменная b

public: // Открыть функции

void Set (bool vB) {b= vB;} // Установить значение переменной b

bool Get ( ) {return b; } // Получить значение закрытой переменной b

};

int main(array<System::String ^> ^args)

{

//// Выделить память для целочисленного данного в стеке