Оператор new – это универсальный оператор, получающий память у операционной системы и возвращающий указатель на начало выделенного блока. Для освобождения выделенных участков памяти и возврата их операционной системе используется оператор delete. Причем освобождение памяти не подразумевает удаление указателя, связанного с этим блоком памяти; это и не изменение адреса значения, на которое указывает указатель. Однако этот указатель не имеет силы. Память, на которую он указывает, может быть применена для других целей.
Оператор new очень часто используется в конструкторах классов, а delete соответственно в деструкторах.
Указатели могут указывать на объекты так же, как и на простые типы данных и массивы. Например:
#include <iostream>
using namespace std;
class Distance
{
private:
int feet;
float inches;
public:
void GetDist()
{
cout <<”Введите футы”;
cin >> feet;
cout <<”Введите дюймы”;
cin >> inches;
}
void ShowDist()
{ cout << feet << “\’-“ << inches<<’\”’; }
};
int main()
{
Distance Dist; //создаем объект типа Distance
Dist.GetDist(); //получаем данные
Dist.ShowDist(); //отображаем данные на мониторе
//создаем указатель на объект типа Distance
Distance* pDist;
pDist = new Distance(); //создаем объект Distance
pDist->GetDist(); //получаем данные
pDist->ShowDist();//отображаем данные на мониторе
…
if (pDist) delete pDist; //освобождаем память
return 0;
}
Иногда может встретиться другой более общий способ применения операции new для выделения памяти для объектов. Так как new возвращает указатель на блок памяти, содержащий объект, то мы имеем возможность обратиться к первоначальному объекту путем разыменования указателя. Например, можно переписать функцию main следующим образом:
int main()
{
//создаем объект типа Distance
Distance& Dist = *(new Distance);
Dist.GetDist(); //доступ к членам класса
//осуществляем через оператор “.”
Dist.ShowDist(); //отображаем данные на мониторе
…
return 0;
}
Выражение new Distance возвращает указатель на блок памяти, достаточный для размещения объекта Distance, и мы можем обратиться к первоначальному объекту, используя *(new Distance).
На этот объект указывает указатель. Используя ссылку, мы определили Dist как объект класса Distance и определили его равным *(new Distance). Теперь мы можем ссылаться на члены объекта Dist, используя операцию точки . , а не операцию ->.
Этот подход используется реже, чем указатели на объекты, полученные с использованием операции new, но он работает точно так же.
Способом, аналогичным вышеописанному, выделяется память и под массивы объектов. Например:
…
//создаем массив из 7 элементов типа Distance
Distance DistMas[7];
…
//обращаемся к методу 3-го элемента массива
DistMas[2].ShowDist();
…
//создаем массив из 5 указателей на Distance
Distance *pDistMas[5];
for (int i=0; i<5; i++)
{
//создаем объект типа Distance
pDistMas[i] = new Distance;
//обращаемся к методу i-го элемента массива
pDistMas[i]->GetDist();
}
…
Отметим, что в этом случае удалить созданный нами с помощью оператора new массив указателей, просто вызвав
delete []pDistMas;
нельзя. Так как эта запись удалит массив указателей, но не объекты, на которые они указывают. Поэтому мы должны вызвать каждый элемент массива и применить к нему оператор delete:
for (i=0; i<5; i++)
delete pDistMas[i];
Класс может предусматривать применение своих собственных вариантов операторов new и delete. При этом
• - функция тип_класса::operator new будет вызываться всякий раз, когда создается динамический объект;
• - функция тип_класса::operator new[] будет вызываться всякий раз, когда создается динамический массив объектов;
• - функция тип_класса::operator delete будет вызываться вся-кий раз, когда уничтожается динамический объект;
• - функция тип_класса::operator delete [] будет вызываться вся-кий раз, когда уничтожается динамический массив объектов.
Например:
class X
{
…
public:
void *operator new(long sz){return myalloc(sz); };
void *operator delete(X *p) { myfree(p); };
X(){/*Инициализация*/};
…
}
Для объектов класса X вместо операторов new и delete будут использоваться X::operator new и X::operator delete. Глобальный оператор new, как и прежде, может использоваться для выделения памяти для объектов других типов. |