Бьерн Страуструп. Язык программирования С++ Второе дополненное издание



Pdf көрінісі
бет132/256
Дата11.07.2022
өлшемі2,87 Mb.
#37591
1   ...   128   129   130   131   132   133   134   135   ...   256
6.7.2 Указание размещения 
По умолчанию операция new создает указанный ей объект в свободной памяти. Как быть, если надо 
разместить объект в определенном месте? Этого можно добиться переопределением операции 
размещения. Рассмотрим простой класс: 
class X { 
// 
... 
public: 
X(int); 
// 
... 
}; 
Объект можно разместить в любом месте, если ввести в функцию размещения дополнительные 
параметры: 
// операция размещения в указанном месте: 
void* operator new(size_t, void* p) { return p; } 
и задав эти параметры для операции new следующим образом: 
char buffer[sizeof(X)]; 
void f(int i) 

X* p = new(buffer) X(i); // 
разместить X в buffer 
// 
... 

Функция operator new(), используемая операцией new, выбирается согласно правилам сопоставления 
параметров ($$R.13.2). Все функции operator new() должны иметь первым параметром size_t. 
Задаваемый этим параметром размер неявно передается операцией new. 
Определенная нами функция operator new() с задаваемым размещением является самой простой из 
функций подобного рода. Можно привести другой пример функции размещения, выделяющей память из 
некоторой заданной области: 
class Arena { 
// 
... 
virtual void* alloc(size_t) = 0; 
virtual void free(void*) = 0; 
}; 
void operator new(size_t sz, Arena* a) 

return 
a.alloc(sz); 

Теперь можно отводить память для объектов произвольных типов из различных областей (Arena): 
extern Arena* Persistent; 
// 
постоянная память 
extern Arena* Shared; 
// 
разделяемая память 
void g(int i) 

X* p = new(Persistent) X(i); 
// X 
в постоянной памяти 


Бьерн Страуструп.
Язык программирования С++ 
 
179 
X* q = new(Shared) X(i); 
// X 
в разделяемой памяти 
// 
... 

Если мы помещаем объект в область памяти, которая непосредственно не управляется стандартными 
функциями распределения свободной памяти, то надо позаботиться о правильном уничтожении 
объекта. Основным средством здесь является явный вызов деструктора: 
void h(X* p) 

p->~X();
// вызов деструктора 
Persistent->free(p); 
// освобождение памяти 

Заметим, что явных вызовов деструкторов, как и глобальных функций размещения специального 
назначения, следует, по возможности, избегать. Бывают случаи, когда обойтись без них трудно, но 
новичок должен трижды подумать, прежде чем использовать явный вызов деструктора, и должен 
сначала посоветоваться с более опытным коллегой. 


Достарыңызбен бөлісу:
1   ...   128   129   130   131   132   133   134   135   ...   256




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет