Можем ли мы явно вызвать виртуальный `оператор удаления`?

По причинам, которые я не хотел бы здесь углубляться, мне необходимо полностью распределить средства и освободить их в большой существующей кодовой базе, которая использует пользовательские operator new а также operator delete, С этой целью я переписываю (используя входной интерфейс Clang) каждый случай new X(...) с new (allocate<X>()) X(...)где реализация по умолчанию allocate<X> призывает к классу operator new, если он существует, или ::operator new иначе. Я знаю, что это не 100% звук, но он «достаточно хорош» для кодовой базы, на которую я нацеливаюсь.

Теперь я пытаюсь ввести подобное поведение перехвата для delete, но это сложнее, чем ожидалось, из-за странной природы виртуального operator delete, От https://en.cppreference.com/w/cpp/memory/new/operator_delete:

Призыв к классу T::operator delete Полиморфный класс — единственный случай, когда статическая функция-член вызывается посредством динамической диспетчеризации.

Рассмотрим следующий пример:

struct A {
virtual ~A() { cout << "~A" << endl; }
static void operator delete(void* ptr) {
cout << "A::operator delete" << endl;
::operator delete(ptr);
}
};
struct B : public A {
virtual ~B() { cout << "~B" << endl; }
static void operator delete(void* ptr) {
cout << "B::operator delete" << endl;
::operator delete(ptr);
}
};

В идеале я хотел бы заменить каждое вхождение delete x в кодовой базе с deleteWrapper(x), что эквивалентно delete x по умолчанию, но я могу добавить дополнительные инструменты и специализировать его для определенных типов x если нужно.

Я думал, что могу сделать что-то вроде следующего, чтобы достичь этого:

template <typename T>
void deleteWrapper(T* x) {
x->~T();
// The deallocation behavior here should "tweakable" for certain types
// of T, for example I might need different implementations for
// std::pair<int, int> and std::pair<std::string, int>
x->operator delete(x);
}

Но (кроме вызова неопределенного поведения) это не эквивалентно delete x: С вышеуказанной иерархией типов, deleteWrapper(static_cast<A*>(new B)) звонки A::operator delete вместо B::operator delete, Есть ли способ вызвать правильную перегрузку, учитывая полиморфный указатель, без использования delete?

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

4

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector