Класс (C ++ 14) ниже имеет перегруженный оператор new
для выделения непрерывной памяти для объекта и некоторых байтов в качестве дополнительного хранилища. Объект хранит размер дополнительного хранилища в переменной-члене. Размер дополнительного хранилища должен быть передан в качестве параметра оператору new
. Например, чтобы выделить 10 байтов в качестве хранилища:
Storage* ptr = new(10)Storage;
Приведенная ниже реализация приводит к ошибке: « выражение нового размещения относится к функции без размещения »:
class Storage
{
private:
std::size_t storage_size;
public:
Storage(){};
~Storage() {};
static void* operator new(std::size_t object_size, std::size_t storage_size)
{
// Allocate memory for the object and the storage
char* ptr = new char[object_size + storage_size];
// Placement new
Storage* ptr2 = ::new(ptr)Storage;
// Set member variable
ptr2->storage_size = storage_size;
// Return
return ptr2;
}
static void operator delete(void* ptr, std::size_t storage_size)
{
// How?
}
};
Как мне реализовать перегруженный оператор delete
?
ОБНОВЛЕНИЕ
Следующий код основан на комментариях и примере @Igor Tandetnik (спасибо!) И работает, как и ожидалось. Я мог бы также установить переменную-член.
class Storage
{
private:
std::size_t storage_size;
public:
Storage(bool do_throw) {
std::cout << "Storage(): this = " << this << std::endl;
if (do_throw) {
std::cout << "Throwing exception!" << std::endl;
throw 42;
}
};
~Storage() { std::cout << "~Storage(): this = " << this << std::endl; };
void print_storage() { std::cout << "Storage size: " << storage_size << std::endl; }
static void* operator new(std::size_t object_size, std::size_t storage_size)
{
char* ptr = new char[object_size + storage_size]; // Allocate memory
std::cout << "Overloaded new: ptr = " << static_cast<void*>(ptr) << std::endl;
Storage* ptr2 = static_cast<Storage*>(static_cast<void*>(ptr));
ptr2->storage_size = storage_size;
return ptr;
}
static void operator delete(void* ptr, std::size_t storage_size)
{
std::cout << "Overloaded delete: ptr = " << ptr << std::endl;
delete[] ptr;
}
static void operator delete(void* ptr)
{
std::cout << "Delete: ptr = " << ptr << std::endl;
delete[] ptr; // Destructor called automatically
}
};
int main()
{
try {
auto ptr = new(10) Storage(false);
ptr->print_storage();
delete ptr;
ptr = new(10) Storage(true);
ptr->print_storage();
delete ptr;
}
catch (...) {
std::cout << "Got exception" << std::endl;
}
return 0;
}