простое многонаследование
struct A {};
struct B {};
struct C : A, B {};
или виртуальное наследование
struct B {};
struct C : virtual B {};
Обратите внимание, что типы не являются полиморфными.
Пользовательское распределение памяти:
template <typedef T, typename... Args>
T* custom_new(Args&& args...)
{
void* ptr = custom_malloc(sizeof(T));
return new(ptr) T(std::forward<Args>(args)...);
}
template <typedef T>
void custom_delete(T* obj)
{
if (!obj)
return obj;
void* ptr = get_allocated_ptr(obj); // here
assert(std::is_polymorphic_v<T> || ptr == obj);
obj->~T();
custom_free(ptr); // heap corruption if assert ^^ failed
}
B* b = custom_new<C>(); // b != address of allocated memory
custom_delete(b); // UB
Как я могу реализовать get_allocated_ptr
для не полиморфных типов? Для полиморфных типов dynamic_cast<void*>
выполняется задание.
В качестве альтернативы я могу проверить, что obj
является указателем на базовый класс, поскольку удаление не полиморфного объекта указателем на базовый класс - UB. Я не знаю, как это сделать или если это возможно вообще.
operator delete
правильно освобождает память в таких случаях (например, VС++), хотя стандарт говорит, что это UB. Как оно работает? специфичная для компилятора функция?