|
Аргументы оператора new Оператор new можно перегрузить так, чтобы помимо размера он вызывался и с другими дополнительными аргументами. Перегрузка лишает вас стандартной сигнатуры void* operator new(size_t), и, если вам этого не хочется, ее придется включить в программу вручную. #define kPoolSize 4096 struct Pool { unsigned char* next; // Следующий свободный байт unsigned char space[kPoolSize]; Pool() : next(&space[0]) {} }; class Foo { public: void* operator new(size_t bytes) { return ::operator new(bytes); } void* operator new(size_t bytes, Pool* pool) { void* space = pool->next; pool->next += bytes; return space; } }; void f() { Pool localPool; Foo* foo1 = new Foo; // Использует оператор new по умолчанию Foo* foo2 = new(&localPool) Foo; // Использует перегрузку } Здесь клиент, а не класс указывает, где следует разместить объект. Показан лишь фрагмент полной стратегии. Например, как оператор delete узнает, откуда была взята память - из глобального пула, используемого оператором new по умолчанию, или настандартного пула, который используется перегруженным оператором new? Впрочем, основная идея проста: предоставить клиенту класса некоторую степень контроля над размещением экземпляров в памяти. Это означает, что способ выделения памяти может выбираться для конкретных объектов и не обязан совпадать для всех экземпляров класса. Оператор new можно перегружать с любыми новыми сигнатурами при условии, что все они различаются, а первым аргументом каждой перегруженной версии является size_t - количество нужных байт. Перегрузки могут быть как глобальными, так и принадлежать конкретным классам. Когда компилятор встречает аргументы между new и именем класса, он подставляет размер в начало списка аргументов и ищет подходящую сигнатуру. |
Copyright 2005. Климов Александр. All Right Reserved.